assembly - x86 函数必须保留哪些寄存器?

标签 assembly x86 calling-convention

我正在 x86 程序集中编写一个函数,该函数应该可以从 C 代码调用,我想知道在返回调用者之前必须恢复哪些寄存器。

目前我只恢复espebp,而返回值在eax中。

还有其他我应该关心的寄存器吗?或者我可以在其中留下我喜欢的内容吗?

最佳答案

使用Microsoft's 32 bit ABI (cdeclstdcall 或其他调用约定)、EAXEDXECX是暂存寄存器(调用破坏)。其他通用整数寄存器是调用保留的。

EFLAGS 中的条件代码被调用破坏。调用/返回时需要 DF=0,因此您可以先使用 rep movsb 而无需使用 cld。 x87 堆栈在调用时或从不返回 FP 值的函数返回时必须为空。 (FP 返回值位于 st0 中,除此之外 x87 堆栈为空。)XMM6 和 7 是调用保留的,其余的是调用破坏的暂存寄存器。

在 Windows 之外,大多数 32 位调用约定(包括 Linux 上的 i386 System V)都同意选择 EAX、EDX 和 ECX 作为调用破坏,但是所有 xmm 寄存器都被调用- 被破坏了。

<小时/>

对于Windows下的x64,只需恢复RBXRBPRDI RSIR12R13R14R15。 XMM6..15 是调用保留的。 (并且您必须保留 32 字节的影子空间供被调用者使用,无论是否有任何不适合寄存器的参数。) xmm6..15 是调用保留的。
请参阅https://en.wikipedia.org/wiki/X86_calling_conventions#Microsoft_x64_calling_convention了解更多详情。

其他操作系统使用 x86-64 System V ABI (see figure 3.4) ,其中调用保留的整数寄存器为 RBPRBXRSPR12R13R14R15。所有 XMM/YMM/ZMM 寄存器都被调用破坏。

EFLAGS 和 x87 堆栈与 32 位约定相同:DF=0,条件标志被破坏,x87 堆栈为空。 (x86-64 约定在 XMM0 中返回 FP 值,因此 x87 堆栈寄存器在调用/返回时始终需要为空。)

<小时/>

有关官方调用约定文档的链接,请参阅 https://stackoverflow.com/tags/x86/info

关于assembly - x86 函数必须保留哪些寄存器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9603003/

相关文章:

c - 函数指针和调用约定

c++ - cdecl 调用约定如何破坏 ESP?

assembly - 如何在程序集 x86-64 中保存字符串临时变量

c - 从函数外部访问标签

assembly - 为什么 Intel 的编译器更喜欢 NEG+ADD 而不是 SUB?

windows - MS 加载程序将 PE 文件的哪些部分映射到内存中?

assembly - 自动检测违反程序集调用约定的情况

c - 在单独的编译单元中调用函数是否有更多开销?

c - c代码汇编输出中的if语句

performance - MOVSD的性能取决于参数