常见的调用约定有:
-
__stdcall(pascal)
-
cdecl
-
fastcall
-
thiscall
-
naked call
__stdcall
stdcall(pascal)–Standard Call的缩写,C++的标准调用方式
在Microsoft C++系列的C/C++编译器中,常常用PASCAL宏来声明这个调用约定,类似的宏还有WINAPI和CALLBACK。
一般WIN32的函数都是__stdcall
声明的语法为:
int __stdcall function(int a,int b)
__stdcall的调用约定意味着:
参数从右向左压入堆栈
函数自身清理堆栈
函数名自动加前导的下划线,后面紧跟一个@符号,其后紧跟着参数的尺寸
cdecl
cdecl–C Declaration的缩写,C语言缺省的调用约定
声明的语法为:
int function (int a ,int b) //不加修饰就是C调用约定
int __cdecl function(int a,int b)//明确指出C调用约定
cdecl调用约定意味着:
参数从右向左压入堆栈
调用者负责清理堆栈
C调用约定允许函数的参数的个数是不固定的,这也是C语言的一大特色
仅在函数名前加上一个下划线前缀,格式为_functionname。
fastcall
声明的语法为:
int fastcall function(int a,int b)
fastcall调用约定意味着:
函数的第一个和第二个DWORD参数(或者尺寸更小的)通过ecx和edx传递,其他参数通过从右向左的顺序压栈
函数自身清理堆栈
函数名修改规则同stdcall:函数名自动加前导的下划线,后面紧跟一个@符号,其后紧跟着参数的尺寸
thiscall
thiscall–C++类成员函数缺省的调用约定。
thiscall是唯一一个不能明确指明的函数修饰,因为thiscall不是关键字。由于成员函数调用还有一个this指针,因此必须特殊处理,thiscall意味着:
参数从右向左入栈
如果参数个数不确定,this指针在所有参数压栈后被压入堆栈。如果参数个数确定,this指针通过ecx传递给被调用者。
如果参数个数不确定,调用者清理堆栈,否则函数自己清理堆栈
对于参数个数固定情况下,类似于stdcall,不定时则类似cdecl
naked call
一个很少见的调用约定,一般用于实模式驱动程序设计