ARM中Scratch寄存器的用途是什么?

3
ARM架构中为什么会有一个scratch寄存器?处理器是如何使用它的,也就是说这个寄存器的目的是什么?
2个回答

8

来自Arm 架构过程调用标准:

临时寄存器 / Scratch 寄存器:用于在计算过程中存储一个中间值的寄存器(通常这些值在程序源代码中没有名称并具有有限的生命周期)。

如果您调用函数,函数调用后 Scratch 寄存器中的值可能已被更改。因此,函数调用者必须确保如果这些值仍然需要,它们需要保存。这些寄存器也称为调用者安全寄存器,与被调用者安全寄存器相对。被调用的函数会将后者保存。因此,如果需要临时存储值,则首先使用 Scratch 寄存器,因为无需事先保存它们。


6
在ARM体系结构中为什么有一个scratch register?这个寄存器有什么用途? 使用scratch registers高效,因为在使用前不需要保存。许多函数序言和尾声活动至少需要一个scratch register。 处理器只是一个常规寄存器。 在ARM中没有'scratch register'。您可能将其称为'caller' saved register;但这是EABI/AAPCS或您遵循的任何其他标准。它不在'architecture'内。它是用于代码互操作的约定。这可以包括操作系统调用、库调用和工具互操作(跨语言调用)。根据您正在使用的软件基础设施/工具,可能会生效不同的但非常相似的标准。 对于传统的ARM,有四个“caller” saved registers。它们是r0-r3。它们也是函数的参数和返回值。设计为互操作的例程可以将r0-r3用于任何目的,即使它们不是参数列表的一部分。例如,像 void foo(void) 这样的例程甚至不需要r0,但是该例程可以在不保存它的情况下使用r0。调用foo() 的例程如果要保留r0,则必须保存r0。在这种情况下,r0-r3是短暂的寄存器或scratch registers。相比之下,如果要使用r4-r11,则必须将其保存(在堆栈上)。 r12或ip通常不对汇编程序员有特殊意义,也可以视为scratch register。 r12是scratch register,但原因不同于r0-r3。 r12未用作参数寄存器,因此可以由序言代码(例程开始)使用。 如果您希望在“回溯”中使用您的例程,则可能会有其他限制。您可以使用伪操作.cantunwind将您的例程标记为“不可回溯”的堆栈回溯。这不是ARM汇编器,而是ELF文件中的“元数据”。在这种情况下,您可以将r14(lr)用作已保存的寄存器;不是scratch. 在纯汇编项目中,所有寄存器都可以成为scratch registers。例如,启动处理器的初始代码通常不需要保存任何内容,并且所有寄存器都是scratch registers。一个例外可能是堆栈指针。 注意:一些系统会专门使用r9,但这很少见。一个例子可能是u-boot。r9从来不是scratch register。 参考资料

此外,对于这个问题的读者来说,ARM R12 APCS可能也是有趣的。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接