stand on the shoulders of giants

【代码真相】之 函数调用方式 __cdecl & __stdcall

【代码真相】之 函数调用方式 __cdecl & __stdcall

1. __cdecl     C和C++缺省调用方式
实参的压栈顺序是从右到左,最后由主调函数进行堆栈恢复。由于主调用函数管理堆栈,所以可以实现变参函数。
示例:
void Input(int &m,int &n){}
int a =1, b=2;
Input(a,b);

Disassembly是这样的:
 Input(a,b);
004114EC  lea         eax,[b]        //将b的地址传给eax
004114EF  push        eax           //这两行完成参数b入栈 其实是地址入栈
004114F0  lea         ecx,[a]        //将c的地址传给ecx
004114F3  push        ecx           //这两行完成参数a入栈 其实是地址入栈
004114F4  call        Input (4111E5h)  //调用Input函数
004114F9  add         esp,8         //恢复栈

思考:如果写成void Input(int m, int n){}是什么样的呢?
Input(a,b);
004114EC  mov         eax,dword ptr [b]  //将2入栈
004114EF  push        eax 
004114F0  mov         ecx,dword ptr [a]
004114F3  push        ecx 
004114F4  call        Input (4111EAh)
004114F9  add         esp,8
知道传值和传引用传地址的区别了吧。

2. __stdcall   CALLBACK
实参的压栈顺序是从右到左,调用返回时,堆栈由被调函数调整。
Input(a,b);
004114EC  lea         eax,[b]
004114EF  push        eax 
004114F0  lea         ecx,[a]
004114F3  push        ecx 
004114F4  call        Input (4111FEh)
可以看出来,在调用函数Input之后,没有相应的堆栈恢复工作

posted @ 2008-12-04 18:03  DylanWind  阅读(305)  评论(0编辑  收藏  举报