_stdcall,_cdecl,_fastcall
参数入栈顺序:
两者都是从右到左。
参数出栈区域:
_stdcall是在函数内部清理释放栈。更好的封装性。
_cdecl是在调用函数的地方释放,所有每个调用的地方都有一块弹出栈空间的代码,编译出来的程序较大。
名称修饰:
除了与_stdcall, _cdecl有关,还与是否用C或C++导出有关
1. C方式编辑,即(extern ‘C’)
a. _stdcall : _函数名@参数字节数
eg: void func(int a, int b): _func@8
b. _cdecl: 与原名称相同
eg:void func(int a, int b): func
2. C++方式编译,即(extern 'C++')
a. _stdcall:
1) 以?开头
2) 原名称后接@@YG
3) 再接返回值代号和参数代号
X--void ,
D--char,
E--unsigned char,
F--short,
H--int,
I--unsigned int,
J--long,
K--unsigned long,
M--float,
N--double,
_N--bool,
4) 再接@Z表示结束
eg:void func(int a, int b): ?func@@YGXHH@Z
b. _cdecl
与_stdcall规则相同,只是参数表的开始标识由上面的“@@YG”变为“@@YA”
使用场景:
__stdcall通常用于Windows API中
#elif (_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED) #define CALLBACK __stdcall #define WINAPI __stdcall
VS中默认的调用方式是_cdecl, 在属性页,C/C++,调用约定下设置。
特殊场景;
对于可变参数,由于函数内部不知道有几个参数,也就无法做清理的工作,只能由调用者来做,所以可变参数是按照cdecl的约定方式。
使用较少的调用约定:
_fastcall:
特点就是快,因为是前两个参数是通过寄存器传递的
格式:@函数名@参数字节数
前两个参数或更小的两个参数的传递顺序是按照从左到右的顺序,其他参数是按照从右到左的顺序。
_vectorcall:
目的是优化浮点向量运算,intel处理器种有很多浮点向量寄存器,传统的浮点参数需要从栈上获取
_vectorcall 直接从寄存器上传递参数
_vectorcall是集成_fastcall的