assembly - 谁负责在 MIPS 中保存被调用者保存的寄存器?

标签 assembly mips calling-convention

当在 MIPS 中调用子例程时,由于被调用者保存的寄存器 ($s0-$s7) 在函数/子例程调用中保留,如果要修改它们,它们将保存在子例程的堆栈帧中。谁负责拯救他们?我是负责通过编写指令将这些被调用保存的寄存器保存到堆栈中的汇编程序员吗?或者,在为我调用子例程时,汇编程序是否会以某种方式自动管理被调用者保存的寄存器的保存,以便在调用之间保留它们?我只是在学习 MIPS 调用约定,所以这对我来说是全新的。

最佳答案

您的函数实际上不必保存/恢复它们,您只需要确保在您的函数返回时它们仍然具有原始值。 最简单的方法是根本不接触这些寄存器。

调用者与被调用者保存的寄存器是一个令人困惑的术语,并且错误地暗示每次有函数调用时所有寄存器都必须保存在某处。

更好的术语:调用保留与调用破坏。 在这两种情况下,您都从相同的角度查看寄存器,并且并不暗示任何人实际上都在浪费指令进行任何保存。如果在 jal 之后不需要寄存器中的值,就让寄存器被破坏。 .

你可以使用像 $t0..$t9 这样的调用破坏寄存器无论你想要什么,你都可以带着他们返回你的代码之后剩下的任何垃圾。

如果您在循环内进行函数调用,您可能需要保存几个调用保留的寄存器 ( $s0..$s7 ) 并将一个用于循环计数器。然后在函数结束时恢复它。您不想在循环中自己存储/重新加载它;如果您调用的函数不涉及寄存器,那将是一个很大的浪费。

关于assembly - 谁负责在 MIPS 中保存被调用者保存的寄存器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50409351/

相关文章:

c - 如何在没有 Glibc 的情况下在 C 中使用内联汇编获取参数值?

c - ELF 二进制文件的运行时修补

c - x64 帧指针应该指向哪里,为什么指向? ( Windows x64 ABI)

linux - 为什么在返回 MEMORY 类型时返回 %rax 中的对象地址?

windows - __stdcall 没有任何修饰

assembly - 如何阅读英特尔操作码符号

c - 缓冲区溢出: execute char array loaded into memory

linux - mips 交叉编译器中的 crt1.o 错误

将 C 编译成 MIPS

linux - 从 x86 交叉编译 MIPS 路由器