为什么根据 ARM 过程调用标准将 r12 指定为暂存寄存器?它位于两组保留寄存器之间:r4-r11 和 sp-lr-pc。为什么不将 r0-r4 临时化并保留其他所有内容?
请注意,ARM 有STM
and LDM
以数字递增/递减顺序存储和加载值的指令。寄存器 R0-R3 用作参数和返回值,并在需要时“调用者保存”。寄存器 R4-R8 是被调用者保存的寄存器(可能还有更多)。另外,R13-R15 是特殊寄存器。 R12 的使用允许使用 LDM/STM 相当有效地访问寄存器组,因为您可能希望以不同的方式对待组(上下文保存、函数调用、信号等,都有不同的要求)。
函数尾声和序言代码可能需要运行计算和/或保存值。为此需要一个临时寄存器。因此,给定 LDM/STM 和其他 ARM 寻址模式,临时寄存器不应破坏连续序列。您可能需要根据上下文和代码生成策略来保存/恢复调用者和被调用者保存的寄存器。在 R4 休息一下并不是一个好的选择。影响最小的自然中断发生在被调用者和上层内部寄存器(PC、SP、LR)之间。请注意,R9-R11 可以是特殊寄存器,具体取决于前面的系统(静态基址、堆栈范围和帧指针)APCS。由于这些是可选的,因此在某些系统中它们可能按照 R4-R8 保存。
为什么根据 ARM 过程调用标准将 r12 指定为暂存寄存器?
WHY这是一个非常棘手的问题。鉴于不使用连续寄存器来实现类似的功能会使事情变得复杂。它也更容易记住,并且确实为某些 ARM 指令提供了更大的灵活性。此外,代码生成的实现可能更简单,因为您只需要保存一个上限即可知道被调用者保存的寄存器。目标是使函数尾声/序言尽可能快。这根据功能和系统要求而有所不同。希望需要暂存寄存器的原因是显而易见的。如果没有多个堆栈保留,基于参数的可变大小数组将很难实现。一些代码例如信号可能依赖FP
在序言期间自动设置;即,您处于已设置堆栈和帧指针的函数中,或者您不在没有中间状态的情况下。 IP (r12) 对于胶合板和其他链接技巧(PLT、GOT 等)也很有用。 R12 的选择允许某些系统使用 R9-R11 作为被调用者保存的通用寄存器,而不会破坏类似寄存器的任何序列。
从 APCS 来看,
ip寄存器仅在函数调用期间有专用作用;在其他时候,它可以用作暂存寄存器。
(旁白:按照惯例,编译器代码生成器使用 ip 作为本地代码生成器临时寄存器)。
不幸的是,APCS 已被 AAPCS 淘汰,因此 ARM 不再提供它(很难找到 Web 参考资料)。然而,它让我们深入了解 ARM ABI 的演变。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)