ARM过程调用标准中的r12

时间:2017-07-27 19:26:02

标签: arm cpu-registers

为什么根据ARM过程调用标准将r12指定为临时寄存器?它位于两组保留的寄存器之间:r4-r11和sp-lr-pc。为什么不让r0-r4暂时保留所有其他内容?

2 个答案:

答案 0 :(得分:1)

请注意,ARM具有STMLDM指令,这些指令以数字递增/递减顺序存储和加载值。寄存器R0-R3用作参数和返回值,如果需要,可以“调用保存”。寄存器R4-R8是被调用者保存的寄存器(可能更多)。同样,R13-R15是特殊寄存器。使用R12可以使用LDM / STM非常有效地访问寄存器组,因为您可能希望以不同的方式处理组(上下文保存,函数调用,信号等都有不同的要求)。

功能结尾和序言代码可能需要运行计算和/或保存值。为此需要一个临时寄存器。因此,给定LDM / STM和其他ARM寻址模式,暂存寄存器不应该破坏连续序列。根据上下文和代码生成策略,您可能需要保存/恢复调用者和被调用者保存的寄存器。在R4休息不是一个好选择。在被调用者和上部内部寄存器(PC,SP,LR)之间具有最小影响的自然中断。请注意,R9-R11可以是特殊寄存器,具体取决于先前APCS中的系统(静态基址,堆栈范围和帧指针)。由于这些是可选的,在某些系统中,它们可能按照R4-R8进行保存。

  

为什么根据ARM过程调用标准将r12指定为临时寄存器?

为什么是一个非常棘手的问题。鉴于它会使不使用连续寄存器的类似功能复杂化。它也更容易记住,并且通过一些ARM指令提供更大的灵活性。此外,代码生成的实现可能更简单,因为您只需要保存上限即可知道被调用者保存的寄存器。目标是尽可能快地制作功能结尾/序幕。这取决于功能和系统要求。希望为什么需要临时寄存器是显而易见的。如果没有多个堆栈预留,基于参数的可变大小的阵列将难以实现。某些代码(如信号)可能依赖于FP在序言期间进行原子设置;也就是说,你在使用堆栈和帧指针设置的函数中,或者你没有介于两者之间。 IP(r12)对于胶合板和其他连接技巧(PLT,GOT等)也很有用。 R12的选择允许一些系统使用R9-R11作为被调用者保存的通用寄存器,而不会破坏任何类似寄存器的序列。

来自APCS,

  

ip寄存器仅在函数调用期间具有专用角色;在其他时候,它可以用作临时记录。

     

(旁白:传统上,ip被编译器代码生成器用作/本地代码生成器临时寄存器)。

不幸的是,APCS已被AAPCS淘汰,因此ARM不再提供它(很难找到Web引用)。但是,它让人看到了ARM ABI的演变。

答案 1 :(得分:-2)

AAPCS指南http://infocenter.arm.com/help/topic/com.arm.doc.ihi0042f/IHI0042F_aapcs.pdf的第14,15和18页定义了R12的使用 程序调用暂存寄存器(IP)。链接器使用它来访问分支和链接(BL)指令无法访问的32位地址空间。