我在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
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
标签,从堆栈恢复返回地址并将返回值传递给我的main
函数。
问题是参数$ 5的值未定义。它可以是任何给定的值。我相信我的程序的问题是我的main
函数的返回地址丢失了,程序无法返回它。我相信wen程序到达jal func
指令,main
返回地址被jal func
指令返回地址替换。
我该如何解决这个问题? (不是要求代码而只是一些指示)
答案 0 :(得分:1)
[...]我相信我的程序的问题是我的
main
函数的返回地址丢失了,程序无法返回它。我相信wen程序到达jal func
指令,main
返回地址被jal func
指令返回地址替换。
差不多。您在函数开头递减堆栈指针($29
/ $sp
)以创建空间以保存返回地址($31
/ $ra
),但之后在最后重新加载返回地址时,你错过了堆栈指针的相应增量 - 你正在查看该值,但实际上并没有从堆栈中弹出它。
答案 1 :(得分:1)
评论您的代码会有很大帮助。你使用临时寄存器可能会使事情更复杂。您只需要使用一个临时寄存器。这是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: