函数调用惯例
-
函数的调用者必须知道函数的调用惯例才能正确地调用函数
-
常见的调用惯例有
__cdecl
__stdcall
__fastcall
__thiscall
-
调用惯例之间的区别在于函数参数的入栈顺序、函数执行完毕后由谁来清理堆栈、以及函数编译后的符号名
调用惯例 参数入栈顺序 堆栈清理方 备注 __cdecl
从右到左的顺序入栈 调用者 由于是调用者清理栈,所以可以实现可变参数函数,是 C/C++
默认的调用惯例__stdcall
从右到左的顺序入栈 被调用者 由于是被调用者清理栈,所以不可以实现可变参数函数,是 WINDOWS API
的调用惯例__fastcall
函数的第一个和第二个 DWORD
参数(或者尺寸更小的)通过ecx
和edx
传递, 其他参数通过从右向左的顺序入栈被调用者 由于是被调用者清理栈,所以不可以实现可变参数函数 __thiscall
从右到左的顺序入栈 如果参数个数确定, this
指针通过ecx
传递给被调用者, 如果参数个数不确定,this
指针在所有参数压栈后被压入堆栈对参数个数不定的, 调用者清理堆栈, 否则函数自己清理堆栈 注意:
ecx
、edx
是寄存器 -
如果函数的调用者使用了跟函数本身的调用惯例不一致的调用惯例来调用函数的话,栈就会被破坏