MIPS汇编开发中如何判断哪些寄存器需要执行栈保存操作
MIPS寄存器保留规则与sort函数$a0/$a1保存原因解答
为什么sort函数需要保存$a0、$a1
你遇到的问题本质是混淆了调用者保存寄存器和被调用者保存寄存器的适用场景,以及叶子函数和非叶子函数的差异:
- MIPS中
$a0~$a3属于「调用者保存」类寄存器,约定规则是:被调用的函数不需要保留这类寄存器的原值,可以直接修改。 - sort函数是非叶子函数,内部需要调用
swap函数。而sort的整个执行周期都需要用到传入的两个参数:$a0存储的数组v的基地址、$a1存储的数组长度n。如果调用swap前不保存这两个寄存器的值,swap执行过程中完全可能修改$a0、$a1的内容,等回到sort的循环逻辑时,就无法拿到正确的v和n的值,所以必须提前保存。
你之前接触的leaf_example是叶子函数,不会调用任何其他函数,没有被其他函数修改$a寄存器的风险,所以不需要额外保存$a0~$a3的值。
寄存器是否需要保存的通用判断方法
MIPS的寄存器保留规则可以分成两类场景判断:
1. 被调用者保存寄存器(必须由当前执行的函数负责保存)
这类寄存器包括$s0~$s7、$ra(返回地址寄存器)、$sp(栈指针寄存器):
- 只要你的函数内部要修改任意一个这类寄存器,就必须在函数入口处将原值压入栈中保存,函数返回前从栈中恢复原值。
- 规则逻辑:调用你的上层函数默认这些寄存器的值不会被你修改,后续还要使用,所以你作为被调用者有义务保留它们的原值。
2. 调用者保存寄存器(必须由发起函数调用的一方负责保存)
这类寄存器包括$t0~$t9、$a0~$a3、$v0~$v1:
- 如果你要调用其他函数,且调用完其他函数之后,还需要使用你当前存在这类寄存器里的值,就必须在调用其他函数之前,把这些值存入栈中,调用结束后再恢复。
- 规则逻辑:你调用的其他函数默认可以随意修改这类寄存器,不会为你保留原值。
内容的提问来源于stack exchange,提问作者user9178840
相关产品推荐
相关产品推荐

