常见的几种函数调用约定
C语言代码示例
1 | int test(int x, int y, int z); |
cdecl
常用场合:C/C++语言中的缺省函数调用约定
由调用者维护栈
支持不确定的参数个数
代码示例:
1
2
3
4
5
6push c
push b
push a
call test
add esp, 12
mov ret, eax- 在第5行,栈是由调用者清理的
stdcall
常用场合:Windows给Win32平台定义的函数调用约定
由被调用函数负责调用后栈的恢复,因为这些被调用函数是WinAPI,清理栈的责任由实现API函数代码的DLL程序承担
参数个数必须确定
比cdecl的调用方式效率稍微高一些
代码示例:
1
2
3
4
5push c
push b
push a
call test
mov ret, eax- 与上面不同,调用者不需要清理栈
fastcall
常用场合:适用于性能要求较高的场合
采用寄存器传参,运算速度更快
如果参数过多,会有一部分参数通过栈传递
被调用的函数在返回前清理传送参数的内存栈
Win32平台参数入栈方式:
- 前2个参数从左到右采用ECX,EDX传递,其余参数从右到左使用栈传递
Win64平台参数入栈方式:
- 前4个参数采用RCX、RDX、R8、R9传递,其余参数采用栈传递
- 如果有this指针,则this指针通过RCX作为第一个参数传递
Linux-64bit平台参数入栈方式:
- 前6个参数采用RDI、RSI、RDX、RCX、R8、R9传递,其余参数采用栈传递
Win32平台代码示例:
1
2
3
4
5push c
mov edx, b
mov ecx, a
call test
mov ret, eax
参考
- 上课的课件
- 恶意代码分析实战
- 【C/C++】__stdcall、__cdcel和__fastcall定义与区别
- [函数调用方式–__thiscall调用方式和__cdecl,__stdcall有什么区别](