我正在尝试在 MIPS 中创建一个递归乘法函数。逻辑是:
我们想将 x 乘以 y。
基本情况:x = 0,返回 y
一般情况:x != 0,返回y + (x-1)*y
所以我写了代码,除了一点点之外,一切都按预期工作。在代码的开头,我这样做:
# save the first address from $ra on the stack so that we can come back and exit
sw $ra 0($sp)
addi $sp $sp -4
jal recursive_multiplication
# get the last address on the stack for the last jr $ra to exit
lw $ra 0($sp)
addi $sp $sp 4
这应该将 $ra 的第一个地址存储在堆栈中,第一个地址是 00400018,代码初始化中“隐藏”jal main 之后的行。把它放在堆栈上并完成我的业务后,我可以回来阅读它,并以 jr $ra 结束我的代码并终止进程。问题是:当我读取堆栈上的地址时,我得到 0,而不是 00400018。此外,我注意到每次我在堆栈上放置一个地址时,堆栈都会添加如下所示的内容:
| . @ .
整个堆栈是这样的:
[7ffff6b0] 00000001 7ffff777 00000000 7fffffe1 . . . . w . . . . . . . . . . .
为此:
[7ffff698] 0040007c 0040007c | . @ . | . @ .
[7ffff6a0] 0040007c 0040007c 0040003c 00000000 | . @ . | . @ . < . @ . . . . .
[7ffff6b0] 00400018 7ffff777 00000000 7fffffe1 . . @ . w . . . . . . . . . . .
当然,我只包括用户堆栈中有趣的部分。其余部分不会被我的代码访问或修改。
我有一种感觉,错误是因为在最后两个@之间,有 7 个点,而不是常规的 2 和一个“|” ,这会导致读数返回 0 到 $ra(因为它读取的是“一个点”),但我无法真正理解它。
知道为什么会这样吗?感谢阅读!
答案 0 :(得分:1)
push 操作应该预先递减栈指针。也就是说,而不是:
sw $ra 0($sp)
addi $sp $sp -4
你应该这样做:
addi $sp $sp -4
sw $ra 0($sp)