在堆栈上读取地址 returns 0 而不是 MIPS 中的 00400018

Reading address on the stack returns 0 instead of 00400018 in MIPS

我正在尝试在 MIPS 中创建递归乘法函数。逻辑是:

我们想将 x 乘以 y。

基本情况:x = 0,return y

一般情况:x != 0, return 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 个点和一个“|” ,这导致读数为 return 0 到 $ra(因为它显示为“一个点”),但我无法真正理解它。

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

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

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

你应该做的:

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