【问题标题】:Reading address on the stack returns 0 instead of 00400018 in MIPS在 MIPS 中读取堆栈上的地址返回 0 而不是 00400018
【发布时间】:2021-05-28 09:00:00
【问题描述】:

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

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

【问题讨论】:

  • 您应该能够使用调试器和单步执行查看问题。观察每条指令,并观察每条指令后寄存器和/或内存发生什么/何时发生变化。您将能够看到负载将转到与存储不同的地址。

标签: stack mips


【解决方案1】:

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

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

你应该这样做:

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

【讨论】:

  • 谢谢!!我已经坚持了一个多小时了,我觉得这是一个很小的错误,但找不到。非常感谢您的帮助,将其标记为解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-04-21
  • 2010-12-14
  • 2015-06-11
  • 1970-01-01
  • 1970-01-01
  • 2021-09-09
  • 2022-01-20
相关资源
最近更新 更多