1

特别是,您如何知道调用者保存的寄存器与被调用者保存的寄存器中的一段代码中的变量执行的保存/恢复操作的数量?

4

2 回答 2

6

调用者保存的寄存器,也称为易失性寄存器,是调用函数必须保存(通常保存到运行时堆栈)的任何 CPU 内核寄存器,如果调用函数需要寄存器中的值;即如果值是“活的”。被调用者保存的寄存器,也称为非易失性寄存器,是任何 CPU 内核寄存器,其中包含函数必须承诺不会破坏的值。如果被调用者(被调用函数)需要使用这些寄存器,它必须先将这些寄存器中的值保存(一般在运行时栈上),然后在返回给调用者之前恢复它们。

正如 Carl Norum 所提到的,哪些 CPU 核心 regs 是 caller-save 和哪些是 callee-save 由调用约定定义(历史上记录不佳,并且历史上特定于编译器),或由 ABI(应用程序二进制接口)定义。

尽管它的信息绝对是 x86 特定的,但 Agner Fog 的以下文档在描述调用约定和调用者保存/被调用者保存寄存器方面做得非常好:

http://www.agner.org/optimize/calling_conventions.pdf

下面介绍 PowerPC EABI,包括它的调用约定。但在本文档中,搜索“volatile”和“nonvolatile”(分别为 caller-save 和 callee-save):

http://www.freescale.com/files/32bit/doc/app_note/PPCEABI.pdf

于 2013-01-29T19:29:57.827 回答
3

在物理上,调用者保存的寄存器和被调用者保存的寄存器之间没有区别。仅通过过程调用标准(调用约定)或 ABI 进行区分。如果您需要分析一段代码,您可以编译(但不汇编)或反汇编二进制文件,并使用 ABI 或调用约定手册作为参考,逐个函数和逐条指令地检查它。

于 2013-01-29T19:00:06.797 回答