我正在x86汇编中编写一个应可从C代码调用的函数,并且我想知道返回到调用者之前必须恢复哪些寄存器。

目前,我仅还原espebp,而返回值位于eax中。

我还有其他需要关注的寄存器吗,或者我可以在其中留下一些令我满意的寄存器?

最佳答案

使用Microsoft's 32 bit ABIcdeclstdcall或其他调用约定),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,只需还原RBXRBPRDIRSIR12R13R14R15。 XMM6..15被保留。 (并且必须保留32个字节的影子空间,以供被调用方使用,无论是否有不适合寄存器的arg。)xmm6..15被保留。
有关更多详细信息,请参见https://en.wikipedia.org/wiki/X86_calling_conventions#Microsoft_x64_calling_convention

其他OS使用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/

10-12 00:33
查看更多