哪些寄存器在函数中可以安全使用(x86)

时间:2013-02-05 06:37:07

标签: assembly x86 abi

根据Wikipedia,英特尔ABI允许使用EAXECXEDX,而无需在功能中保留它们。
我不确定“Intel ABI”是什么意思。这是否意味着所有针对Intel CPU的编译器都强制执行/遵循它?我正在编写一个将从C代码调用的汇编函数。我可以为所有编译器假设这个吗? (我目前只定位x86

2 个答案:

答案 0 :(得分:6)

英特尔ABI只是英特尔建立的呼叫惯例。

通常,在函数调用期间如何传递参数以及保存或删除哪些寄存器由函数的调用约定定义:

http://en.wikipedia.org/wiki/Calling_convention

特别是对于__cdecl,__ stdcall和__fastcall,您应该期望EAX,ECX和EDX被删除,并且您的函数应该保留其他寄存器并返回EAX(或EDX:EAX以返回64位)。

如果您不知道应该使用的调用约定是什么,则不应该使用汇编语言,因为搞乱调用约定会导致应用程序中出现可利用的错误。

在C中,默认调用约定通常是__cdecl,对于Windows导出的API,它通常是__stdcall。

答案 1 :(得分:1)

这是英特尔应用程序二进制接口,这是一套规则,规定诸如可以使用哪些寄存器而不保存,如何在堆栈上推送参数,调用者或被调用者是否清理堆栈帧等等。

如果您知道正在遵循规则,那没关系。我倾向于保存所有内容以防万一(除了我当然用于返回信息的那些东西)。

但它并不一定对所有编译器都强制执行,除非编译器明确指出,否则你认为这样做是不明智的。