x86平台下的调用约定
_cdecl __fastcall与 __stdcall,三者都是调用约定(Calling convention),它决定以下内容:
1)函数参数的压栈顺序
2)由调用者还是被调用者把参数弹出栈
3)以及产生函数修饰名的方法。
1、
__stdcall调用约定:
__stdcall是
Windows API默认调用约定,微软的WINAPI、CALLBACK等宏都是这个调用约定
函数的参数自
右向左通过栈传递,
被调用的函数在返回前
清理传送参数的内存栈,
2、
__cdecl:
__cdecl是
C/C++的默认调用约定,如果不显示声明调用约定的情况下,就是该调用约定。
函数的参数自
右向左通过栈传递,每一个
调用它的函数都包含
清理堆栈的代码,所以产生的可执行文件大小会比调用_stdcall函数的大。
注意:对于可变参数的成员函数,始终使用__cdecl的转换方式。
3、
__fastcall调用约定:它是通过
自右向左
寄存器传参(实际上,它用ECX和EDX传送前两个双字(DWORD)或更小的参数,
剩下的参数仍旧
自右向左压栈传送,
被调用的函数在返回前
清理传送参数的内存栈)。
x64平台下的调用约定
x64平台取消了上文的_cdecl __fastcall __stdcall这些调用约定。而传参是寄存器和栈相结合实现。
优先寄存器传参. 前4个参数分别是 rcx rdx r8 r9进行传参.多余的通过栈传参.从右向左入栈.
函数传参顺序
32位函数入栈传参
从右到左依次入栈
64位函数寄存器传参
前四个参数从左到右依次入寄存器:rdx, rcx, r8, r9, 后面的依次从 右向左 入栈(和32位汇编一样)