参考:

在软件开发中,application binary interface,ABI 是指两程序模块间的接口;通常其中一个程序模块会是库或操作系统所提供的服务,而另一边的模块则是用户所运行的程序。

一个ABI定义了机器代码如何访问数据结构与运算程序,此处所定义的界面相当低端并且相依于硬件。而类似概念的API则在源代码定义这些,则较为高端,并不直接相依于硬件,通常会是人类可阅读的代码。X86调用约定就是一种ABI。

ABI涵盖了各种细节,如:

X86 约定:

  1. cdecl c语言默认的调用约定

    特点:

    参数从右往左依次入栈,调用者实现栈平衡

    编译后的函数名前缀以一个下划线字符

    受函数调用影响的寄存器:EAX, ECX, EDX, ES, GS

    不受函数调用影响的寄存器: EBX, EBP, ESP, EDI, ESI, CS, DS

    返回值存放在 EAX 中

2.stdcall 函数调用约定

特点:

stdcall是由微软创建的调用约定,是Windows API的标准调用约定

由被调用者负责栈平衡,参数从右往左入栈

返回值存放在 EAX 中

编译后的函数名后缀以符号"@"

3.fastcall 函数调用约定

特点:

msvc或gcc的__fastcall约定把第一个(从左至右)不超过32比特的参数通过寄存器ECX/CX/CL传递,第二个不超过32比特的参数通过寄存器EDX/DX/DL,其他参数按照自右到左顺序压栈传递。

被调用者实现栈平衡

返回值存放在 EAX 中

4.thiscall 调用约定

在调用c++非静态成员函数时使用此约定。基于所使用的编译器和函数是否使用可变参数,有两个主流版本的thiscall。 对于GCC编译器,thiscall几乎与cdecl等同:调用者清理堆栈,参数从右到左传递。差别在于this指针,thiscall会在最后把this指针推入栈中,即相当于在函数原型中是隐式的左数第一个参数。

在msvc中,this指针通过ecx寄存器传递,其余同cdecl约定。

对参数个数不定的, 调用者清理堆栈, 否则函数自己清理堆栈

X64 调用约定:

__fastcall 在x64环境下编译代码时,只有一种调用约定