x86 函数必须保留哪些寄存器? [英] What registers must be preserved by an x86 function?

查看:16
本文介绍了x86 函数必须保留哪些寄存器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm writing a function in x86 assembly that should be callable from c code, and I'm wondering which registers i have to restore before i return to the caller.

目前我只恢复espebp,返回值在eax.

Currently I'm only restoring esp and ebp, while the return value is in eax.

是否还有其他我应该关注的寄存器,或者我可以在其中保留任何我喜欢的内容?

Are there any other registers I should be concerned about, or could I leave whatever pleases me in them?

推荐答案

使用 Microsoft 的32 位 ABI(cdeclstdcall 或其他调用约定)、EAXEDXECX 是临时寄存器(调用破坏).其他通用整数寄存器是调用保留的.

Using Microsoft's 32 bit ABI (cdecl or stdcall or other calling conventions), EAX, EDX and ECX are scratch registers (call clobbered). The other general-purpose integer registers are call-preserved.

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

The condition codes in EFLAGS are call-clobbered. DF=0 is required on call/return so you can use rep movsb without a cld first. The x87 stack must be empty on call, or on return from a function that doesn't return an FP value. (FP return values go in st0, with the x87 stack empty other than that.) XMM6 and 7 are call-preserved, the rest are call-clobbered scratch registers.

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

Outside of Windows, most 32-bit calling conventions (including i386 System V on Linux) agree with this choice of EAX, EDX and ECX as call-clobbered, but all the xmm registers are call-clobbered.

Windows下的x64,只需要恢复RBXRBPRDIRSIR12R13R14R15.XMM6..15 是呼叫保留的.(并且您必须保留 32 字节的影子空间供被调用者使用,无论是否有任何不适合寄存器的参数.)xmm6..15 是调用保留的.
有关详细信息,请参阅 https://en.wikipedia.org/wiki/X86_calling_conventions#Microsoft_x64_calling_convention.

For x64 under Windows, you only need to restore RBX, RBP, RDI, RSI, R12, R13, R14, and R15. XMM6..15 are call-preserved. (And you have to reserve 32 bytes of shadow space for use by the callee, whether or not there are any args that don't fit in registers.) xmm6..15 are call-preserved.
See https://en.wikipedia.org/wiki/X86_calling_conventions#Microsoft_x64_calling_convention for more details.

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

Other OSes use the x86-64 System V ABI (see figure 3.4), where the call-preserved integer registers are RBP, RBX, RSP, R12, R13, R14, and R15. All the XMM/YMM/ZMM registers are call-clobbered.

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

EFLAGS and the x87 stack are the same as in 32-bit conventions: DF=0, condition flags are clobbered, and x87 stack is empty. (x86-64 conventions return FP values in XMM0, so the x87 stack registers always need to be empty on call/return.)

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

For links to official calling convention docs, see https://stackoverflow.com/tags/x86/info

这篇关于x86 函数必须保留哪些寄存器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆