Assembly 程序集返回地址不工作
我在C中有这个函数:Assembly 程序集返回地址不工作,assembly,mips,Assembly,Mips,我在C中有这个函数: int func(int n0, int n){ if (n > 1){ int nFinal = func(n0, --n); return (nFinal*nFinal) + n0; } return n0; } 并希望在汇编中对其进行编程。 我有以下代码: .data .text .globl func func: addi $29,$29, -4
int func(int n0, int n){
if (n > 1){
int nFinal = func(n0, --n);
return (nFinal*nFinal) + n0;
}
return n0;
}
并希望在汇编中对其进行编程。
我有以下代码:
.data
.text
.globl func
func:
addi $29,$29, -4
sw $ra,0($29)
move $8,$4
move $9,$5
ble $9,1,fim
sub $9,$9,1
move $5,$9
jal func
move $4,$11
jal quadrado
add $11,$2,$8
j fim
quadrado:
mul $2,$4,$4
jr $31
fim:
lw $31,0($29)
move $2,$11
jr $31
如果$4和$5中传递的参数分别是2和1,我可以看到程序达到了ble
指令,它可以按预期工作。它跳转到fim
标签,从堆栈中恢复返回地址,并将返回值传递给mymain
函数
问题是参数$5上的值未定义。它可以是任何给定的值。我相信我的程序的问题在于,我的main
函数的返回地址丢失,程序无法返回。我相信wen程序到达了jal func
指令,main
返回地址被jal func
指令返回地址所替代
func:
#push rtn. addr. onto stk
sw $ra, 0($sp)
subi $sp, $sp, 4
#result = arg0
move $t0, $a0
#if arg1 <= 1 return arg0
ble $a1, 1, rtn
#call func(arg0, arg1-1)
subi $a1, $a1, 1
jal func
#result = func(arg0, arg1-1)^2 + arg0
mul $t0, $v0, $v0
add $t0, $t0, $a0
rtn:
我怎样才能解决这个问题?(不是问代码,只是问一些方向)
[…]我认为我的程序的问题在于,我的main
函数的返回地址丢失,程序无法返回到它。我相信wen程序到达了jal func
指令,main
返回地址被jal func
指令返回地址所替代
func:
#push rtn. addr. onto stk
sw $ra, 0($sp)
subi $sp, $sp, 4
#result = arg0
move $t0, $a0
#if arg1 <= 1 return arg0
ble $a1, 1, rtn
#call func(arg0, arg1-1)
subi $a1, $a1, 1
jal func
#result = func(arg0, arg1-1)^2 + arg0
mul $t0, $v0, $v0
add $t0, $t0, $a0
rtn:
差不多。您在函数开始时递减堆栈指针(
$29
/$sp
),以创建空间来保存返回地址($31
/$ra
),但在最后重新加载返回地址后,您缺少堆栈指针的相应增量--您正在查看值,但实际上并不是从堆栈中弹出它。对代码进行注释将非常有帮助。使用临时寄存器可能会使事情更加复杂。您只需要使用一个临时寄存器。下面是有关func
例程的一些帮助。我想你可以完成剩下的。当弹出返回地址时,请记住移动堆栈指针
func:
#push rtn. addr. onto stk
sw $ra, 0($sp)
subi $sp, $sp, 4
#result = arg0
move $t0, $a0
#if arg1 <= 1 return arg0
ble $a1, 1, rtn
#call func(arg0, arg1-1)
subi $a1, $a1, 1
jal func
#result = func(arg0, arg1-1)^2 + arg0
mul $t0, $v0, $v0
add $t0, $t0, $a0
rtn:
func:
#按rtn。地址。上stk
西南$ra,0($sp)
subi$sp$sp,4
#结果=arg0
移动$t0,$a0
#如果arg1@MathewS,谢谢。在myfunc
上的j fim
之前添加了addi$29、$29、4
,并按预期工作。不知道这是否是正确的方法,但它的工作方式应该是:)@Favolas:即使添加了该指令,您的程序也不会在MARS中输出正确的结果。@blackcompe您是对的。忘了告诉我把'ble$9,1,fim'改为'ble$9,0,fim'。Offtopic使用此代码,如何在MARS中传递参数?@Favolas:我明白了。你的意思是向函数传递参数吗?如果是这样,只需设置$a0和$a1。谢谢。我有我的代码注释,但因为它是在另一种语言删除后才张贴在这里。相对于将参数传递给mars上的函数,我们并没有讨论“强制”设置$a0和$a1,而是使用“设置”菜单上的“提供给MIPS程序的程序参数”。我还没弄明白它是怎么工作的…@Favolas:我从来没用过程序参数。