C转MIPS代码时,何时将a0-a3、s0-s7等寄存器存入$sp?
MIPS汇编中寄存器入栈的判断规则
一、针对保存寄存器(s0-s7)
只要你的函数会使用这类寄存器,且调用者依赖这些寄存器的值在函数返回后保持不变,就必须先将它们的当前值压入栈,函数执行完毕返回前再恢复。
- 比如你在函数里用$s0存储计算的中间变量,而调用该函数的代码可能早已用$s0保存了关键数据,不提前存栈就会覆盖调用者的数据,引发错误。
二、针对参数寄存器(a0-a3)
- 若函数在调用其他子函数前,还需要使用这些寄存器中的原始值,就必须先压栈。
举个实例:函数先利用a0的值完成部分计算,之后还要调用另一个函数(此时a0会被用作新函数的参数),就需要先把a0的原始值存到栈中,待子函数执行完毕后再取出继续使用。 - 注:如果函数需要处理超过4个参数,超出的参数由调用者存入栈,但如果你的函数需要修改这些栈上的参数副本,且后续还要用到原始值,同样需要提前存栈备份。
三、返回地址寄存器($ra)
只要函数内部存在嵌套函数调用(即执行jal指令),就必须将$ra压栈,否则子函数执行jr $ra时会覆盖当前函数的返回地址,导致无法正确返回调用者。
额外场景
- 递归函数:比如阶乘实现中,除了保存$ra,还要保存当前的n值(若用a0存储n,递归调用时a0会被改为n-1);如果使用s寄存器存储中间结果,也需要提前保存s寄存器的原有值。
- 临时空间不足:当临时寄存器(t0-t9)不够存放临时数据时,也可以将部分值压入栈作为临时存储,不过优先使用t寄存器。
内容的提问来源于stack exchange,提问作者Nuggetman
相关产品推荐
相关产品推荐

