函数调用约定就是描述参数如何传递,堆栈由调用方还是被调用方平衡,返回值如何返回等规则。
函数调用约定的几种类型有:__stdcall, __cdecl, __fastcall, __thiscall, __nakedcall, __pascal
下面介绍几种常见的函数调用约定(以VS2010编译器为例):
(1) __cdecl调用约定
1. 参数从右向左传递,放在栈中
2. 栈平衡由调用函数来执行
3. 不定参数的函数可以使用
下面看一个汇编的例子
int a = 1, b = 2;
mov dword ptr [a],1
mov dword ptr [b],2
int sum = Sum(a, b);
mov eax,dword ptr [b] // 参数从右向左压入栈,压入参数b
push eax
mov ecx,dword ptr [a] // 参数从右向左压入栈,压入参数a
push ecx
call Sum (13611A9h) // 调用函数
add esp,8 // 调用方平衡堆栈(弹出参数)
mov dword ptr [sum],eax // 返回值保存在eax中
int __cdecl Sum(int a, int b)
{
push ebp // 保存上一层函数栈底指针
mov ebp,esp