【问题标题】:$gp, .cpload and position independence on MIPSMIPS 上的 $gp、.cpload 和位置独立性
【发布时间】:2014-02-05 01:34:22
【问题描述】:

我正在阅读有关 Linux here 上 MIPS 上的 PIC 实现的信息。它说:

存储在 $gp 寄存器(又名 $28)中的全局指针是一个被调用者保存的寄存器。

Wikipedia article about MIPS 也是这么说的。

然而,根据他们的说法,当在函数序言中使用.cpload 指令时,它会破坏 $gp 的先前值而不先保存它。当使用.cprestore 时,它将当前 $gp 保存到堆栈帧,而不是函数入口处的$gp 值。 .cprestorejal/jalr 的影响也是如此:一旦被调用者返回,它就会恢复 $gp - 假设被调用者可能已经破坏了它。

最后,函数尾声中没有关于 $gp 的内容。

总而言之,对我来说,这听起来不像是被调用者保存的寄存器。听起来像一个呼叫者保存的寄存器。我在这里误会了什么?

【问题讨论】:

    标签: linux assembly mips


    【解决方案1】:

    MIPS 上的 Linux 程序可以编译为 pic 也可以不编译。如果编译为 pic,则必须使用“abicalls”,其行为与 no-abicalls 约定的行为略有不同。

    从“SYSTEM V APPLICATION BINARY INTERFACE - MIPS Processor Supplement 3rd Edition”的“Position-Independent Function Prologue”部分我们可以引用:

    函数计算完gp后,分配本地栈空间,并将gp保存在栈上,以便后续函数调用后可以恢复。换句话说,gp 是调用者保存的寄存器。

    下图中的代码说明了一个与位置无关的函数序言。 _gp_disp 表示函数开头与全局偏移表之间的偏移量。

    name:
       la gp, _gp_disp
       addu gp, gp, t9
       addiu sp, sp, –64
       sw gp, 32(sp)
    

    总而言之,如果您使用-mabicalls,那么gp 将在所有需要全局符号的函数(有一些例外)以及调用abi 代码的任何代码(abi 与否)的开头计算会确保被调用的函数地址存储在t9中。

    【讨论】:

    • 所以,基本上,Linux/MIPS ABI 无视供应商建议的约定 :) 酷。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-20
    相关资源
    最近更新 更多