为何使用栈指针生成返回地址?MIPS汇编栈操作疑问
关于MIPS中用栈指针减4保存$ra的疑问解答
嗨,首先得夸夸你!能自己写出跑通的MIPS最小值函数,还搞懂了栈指针的寻址逻辑,这进度真的很棒,QtSPIM跑成功的那一刻成就感拉满对吧😉
针对你的疑问,咱们从MIPS的栈机制和调用惯例说起:
- MIPS栈是向下生长的:MIPS架构里,栈的起始地址是高内存地址,每次要往栈里存数据(压栈),都得先把栈指针
$sp往低地址方向移动——也就是减4字节(因为MIPS是32位架构,每个寄存器/数据块占4字节),这样才会腾出一块全新的、未被使用的栈空间。 - 为什么不能直接用当前
$sp的位置存$ra?:当前的$sp指向的是栈顶的最后一个已使用位置,如果直接往这个地址写数据,会覆盖掉之前压入栈的内容,这会破坏栈的完整性,导致后续弹出数据时出错。所以必须先调整$sp到新的空位置,再把$ra存进去。 - 保存
$ra的必要性:当你的主函数调用自己写的最小值子函数时,$ra寄存器会被更新为子函数执行完后要返回的地址。如果主函数在调用子函数后还有后续代码要执行,就必须把调用前的$ra值先存在栈里,否则子函数返回后就找不到主函数原来的执行位置了。而按照MIPS的调用惯例,保存这类寄存器的标准操作就是先调整栈指针,再写入数据。
举个简单的代码片段例子,你可能会看到类似这样的主函数逻辑:
main: addi $sp, $sp, -4 # 先把栈指针减4,腾出4字节空间 sw $ra, 0($sp) # 把$ra的值存在这个新的栈位置 # 调用你的最小值函数 jal min_function # ...后续执行代码 lw $ra, 0($sp) # 从栈里恢复原来的$ra值 addi $sp, $sp, 4 # 栈指针加4,释放占用的栈空间 jr $ra
这样操作就能保证栈的正确使用,不会丢失主函数的返回地址啦。
内容的提问来源于stack exchange,提问作者Richie
相关产品推荐
相关产品推荐

