MIPS:读取堆栈上的地址返回 0 而不是 00400018

时间:2021-05-28 09:00:00

标签: stack mips

我正在尝试在 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(因为它读取的是“一个点”),但我无法真正理解它。

知道为什么会这样吗?感谢阅读!

1 个答案:

答案 0 :(得分:1)

push 操作应该预先递减栈指针。也就是说,而不是:

sw $ra 0($sp)
addi $sp $sp -4

你应该这样做:

addi $sp $sp -4
sw $ra 0($sp)