我正在阅读有关 Linux 上 MIPS 的 PIC 实现 here .它说:
The global pointer which is stored in the $gp register (aka $28) is a callee saved register.
Wikipedia article about MIPS说的一样。
但是,根据他们的说法,当在函数序言中使用 .cpload
指令时,它会破坏 $gp 的先前值而不先保存它。当使用 .cprestore
时,它会将 current $gp 保存到堆栈帧,而不是函数入口处的 $gp 值。 .cprestore
对 jal
/jalr
的影响也是如此:它会在被调用者返回后恢复 $gp - 假设被调用者可能已经崩溃
最后,函数尾声中没有任何关于 $gp 的内容。
总而言之,对我来说这听起来不像是被调用者保存的寄存器。听起来像是来电保存的寄存器。我在这里误解了什么?
最佳答案
MIPS 上的 Linux 程序可以编译为 pic 或不编译。如果编译为 pic,那么他们必须使用“abicalls”,其行为与 no-abicals 约定的行为略有不同。
从“SYSTEM V APPLICATION BINARY INTERFACE - MIPS Processor Supplement 3rd Edition”的“Position-Independent Function Prologue”部分我们可以引用:
After calculating the gp, a function allocates the local stack space and saves the gp on the stack, so it can be restored after subsequent function calls. In other words, the gp is a caller saved register.
The code in the following figure illustrates a position-independent function prologue. _gp_disp represents the offset between the beginning of the function and the global offset table.
name: la gp, _gp_disp addu gp, gp, t9 addiu sp, sp, –64 sw gp, 32(sp)
所以总而言之,如果您使用的是 -mabicalls
,那么 gp
是在所有需要全局符号的函数的开头计算的(有一些异常(exception)),另外任何调用 abi 代码的代码(abi 或非 abi)都将确保调用的函数地址存储在 t9
中。
关于linux - $gp、.cpload 和 MIPS 上的位置独立性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21567030/