函数调用时栈的变化

 
1.1 标准调用(__stdcall函数)
1.1.1 代码
#include <stdio.h>
 
int __stdcall Callee(int param1,int param2)
{
int iVar = param1 ;
return 10;
}
 
int main()
{
Callee(1,2);
return 0;
}
1.1.2 函数int main()
int main()
{
00411460 push        ebp 
00411461 mov         ebp,esp
00411463 sub         esp,0C0h
00411469 push        ebx 
0041146A push        esi 
0041146B push        edi 
0041146C lea         edi,[ebp-0C0h]
00411472 mov         ecx,30h
00411477 mov         eax,0CCCCCCCCh
0041147C rep stos    dword ptr es:[edi]
     Callee(1,2);
0041147E push        2   
00411480 push        1   
00411482 call        CrackFun (4111EAh)
【Jeffrey: 在函数调用前先将参数从左到右入栈,然哈欧调用参数。】
     return 0;
00411487 xor         eax,eax
}
00411489 pop         edi 
0041148A pop         esi 
0041148B pop         ebx 
0041148C add         esp,0C0h
00411492 cmp         ebp,esp
00411494 call        @ILT+300(__RTC_CheckEsp) (411131h)
00411499 mov         esp,ebp
0041149B pop         ebp 
0041149C ret              
--- No source file -------------------------------------------------------------
 
......
004111E5 jmp         Callee (411410h)
004111EA jmp         Callee (411410h)
【Jeffrey:此时已经将函数的返回值地址压入栈中。】
004111EF int         3   
004111F0 int         3
......
 
1.1.3 函数int __stdcall Callee(int param1,int param2)
 
int __stdcall Callee(int param1,int param2)
{
00411410 push        ebp 
00411411 mov         ebp,esp
00411413 sub         esp,0CCh
00411419 push        ebx 
0041141A push        esi  
0041141B push        edi 
【Jeffrey:在子函数入口处,依次将以上4个寄存器的值入栈。】
0041141C lea         edi,[ebp-0CCh]
00411422 mov         ecx,33h
00411427 mov         eax,0CCCCCCCCh
0041142C rep stos    dword ptr es:[edi]
     int iVar = param1;
0041142E mov         eax,dword ptr [param1]
00411431 mov         dword ptr [iVar],eax
     return 10;
00411434 mov         eax,0Ah
【Jeffrey:函数返回值放在寄存器EAX中。】
}
00411439 pop         edi 
0041143A pop         esi 
0041143B pop         ebx 
0041143C mov         esp,ebp
0041143E pop         ebp 
【Jeffrey:在函数返回前,将入口处入栈的寄存器逆次出栈。】
0041143F ret         8   
【Jeffrey:标准调用中,函数返回前负责恢复堆栈信息,“8”为传入参数的大小。】
--- No source file -------------------------------------------------------------
 
1.2 C调用(__cdecl函数)
1.2.1 代码
#include <stdio.h>
 
int __cdecl Callee(int param1,int param2)
{
    int iVar = param1;
    return 10;
}
 
int main()
{
    Callee(1,2);
    return 0;
}
1.2.2 函数int main()
int main()
{
004113D0 push        ebp 
004113D1 mov         ebp,esp
004113D3 sub         esp,0C0h
004113D9 push        ebx 
004113DA push        esi 
004113DB push        edi 
004113DC lea         edi,[ebp-0C0h]
004113E2 mov         ecx,30h
004113E7 mov         eax,0CCCCCCCCh
004113EC rep stos    dword ptr es:[edi]
    Callee(1,2);
004113EE push        2   
004113F0 push        1   
004113F2 call        Callee (411136h)
004113F7 add         esp,8
【Jeffrey:函数返回后主调函数负责恢复堆栈信息。】
    return 0;
004113FA xor         eax,eax
}
004113FC pop         edi 
004113FD pop         esi 
004113FE pop         ebx 
004113FF add         esp,0C0h
00411405 cmp         ebp,esp
00411407 call        @ILT+300(__RTC_CheckEsp) (411131h)
0041140C mov         esp,ebp
0041140E pop         ebp 
0041140F ret             
--- No source file -------------------------------------------------------------
 
1.2.3 函数int __cedcl Callee(int param1,int param2)
int __cdecl Callee(int param1,int param2)
{
00411390 push        ebp 
00411391 mov         ebp,esp
00411393 sub         esp,0CCh
00411399 push        ebx 
0041139A push        esi 
0041139B push        edi 
0041139C lea         edi,[ebp-0CCh]
004113A2 mov         ecx,33h
004113A7 mov         eax,0CCCCCCCCh
004113AC rep stos    dword ptr es:[edi]
    int iVar = param1;
004113AE mov         eax,dword ptr [param1]
004113B1 mov         dword ptr [iVar],eax
    return 10;
004113B4 mov         eax,0Ah
}
004113B9 pop         edi 
004113BA pop         esi 
004113BB pop         ebx 
004113BC mov         esp,ebp
004113BE pop         ebp 
004113BF ret              
【Jeffrey:C调用中,子函数不负责堆栈信息。】
--- No source file -------------------------------------------------------------
 
1.3 函数调用过程中栈数据的变化
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值