函数栈帧

来源:互联网 发布:颂党恩 知党史 促成长 编辑:程序博客网 时间:2024/06/07 07:19

用下面的程序举例说明函数调用时函数栈帧的情况。

#include<stdio.h>int Add(int x,int y){int z=0;z=x+y;return z;}int main(){int x=4;int y=3;Add(x,y);return 0;}


main函数开始被mainCRTStartup函数调用。

在代码执行之前系统自动做下列事
00D813F0  push        ebp  
将寄存器ebp压如栈中
00D813F1  mov         ebp,esp 
ebp中的地址放入esp
00D813F3  sub         esp,0D8h 
esp减去D8h
00D813F9  push        ebx  
00D813FA  push        esi  
00D813FB  push        edi  
将ebx,esi,edi三个寄存器入栈
00D813FC  lea         edi,[ebp-0D8h] 
00D81402  mov         ecx,36h 
00D81407  mov         eax,0CCCCCCCCh 
00D8140C  rep stos    dword ptr es:[edi] 
将esp到ebp这段空间初始化为CCCCCCCCh
int x=4;
00D8140E  mov         dword ptr [x],4 
int y=3;
00D81415  mov         dword ptr [y],3 
Add(x,y);
008D141C  mov         eax,dword ptr [y] 
008D141F  push        eax  
008D1420  mov         ecx,dword ptr [x] 
008D1423  push        ecx  
008D1424  call        @ILT+215(_Add) (8D10DCh) 
这几条指令是将实参传给形参并且保存函数返回时的地址

int Add(int x,int y)
{
008D13A0  push        ebp  
008D13A1  mov         ebp,esp 
008D13A3  sub         esp,0CCh 
008D13A9  push        ebx  
008D13AA  push        esi  
008D13AB  push        edi  
008D13AC  lea         edi,[ebp-0CCh] 
008D13B2  mov         ecx,33h 
008D13B7  mov         eax,0CCCCCCCCh 
008D13BC  rep stos    dword ptr es:[edi]
这些指令与main函数刚开始是的指令功能相似,将ebp到esp大小为CCh的空间的内容初始化为CCCCCCCCh.

int z=0;
008D13BE  mov         dword ptr [z],0 

z=x+y;
008D13C5  mov         eax,dword ptr [x] 
008D13C8  add         eax,dword ptr [y] 
008D13CB  mov         dword ptr [z],eax 
执行z=x+y并将z的值保存

return z;
008D13CE  mov         eax,dword ptr [z] 
}
008D13D1  pop         edi  
008D13D2  pop         esi  
008D13D3  pop         ebx  
008D13D4  mov         esp,ebp 
008D13D6  pop         ebp  
008D13D7  ret              
将z的值保存到eax中并且edi,esi,ebx出栈ebp,esp指向原位置ebp出栈
008D1429  add         esp,8 


return 0;
008D142C  xor         eax,eax 
}
008D142E  pop         edi  
008D142F  pop         esi  
008D1430  pop         ebx  
008D1431  add         esp,0D8h 
008D1437  cmp         ebp,esp 
008D1439  call        @ILT+315(__RTC_CheckEsp) (8D1140h) 
008D143E  mov         esp,ebp 
008D1440  pop         ebp  
这些指令的功能与上面的功能类似将所有寄存器出栈销毁这块空间

1 0