资源预览内容
第1页 / 共11页
第2页 / 共11页
第3页 / 共11页
第4页 / 共11页
第5页 / 共11页
第6页 / 共11页
第7页 / 共11页
第8页 / 共11页
第9页 / 共11页
第10页 / 共11页
亲,该文档总共11页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
C程序运行时内存结构分析时间:2015-11-24 22:25点击:37次实验知识 静态变量存储在静态存储区,局部变量存储在动态存储区(栈),代码存放在代码区 寄存器,EBP指向栈底,ESP指向栈顶,EIP指向正在执行指令的下一条指令,三个寄存器中保存的都是地址,32位系统,地址为4个字节即dword 所有写在函数定义里面的语句都编译成指令(驱动CPU)实验代码#include intfun(inta,intb);intm = 10;intmain()inti = 4;intj = 5;m = fun(i, j);intfun(inta,intb)intc = 0;c = a + b;returnc;这段代码包含两个函数,因此可以测试函数调用,此外还包含了静态变量、局部变量、返回值等实验测试测试工具:VC6.0源代码及对应的汇编如下寄存器及内存状态如下EBP栈顶初始值为0018FF84h,ESP初始为0018FF48hESP和EBP在栈中的作用在每个函数最开始的地方有两条语句push ebpmov ebp,esp在函数返回前也有两条语句mov esp,ebppop ebp每运行一个函数就新开一段栈空间,所谓的开栈空间就是移动ebp栈底,在移动ebp之前,通过push ebp保存上一级函数的栈底,然后用ebp指向现在函数栈的栈顶,即为当前函数开辟了栈;接着给局部变量进行地址分配以及保存现场等,esp不断向低地址移动,当函数调用结束时,esp指回当前函数的栈顶(mov esp,ebp),然后上一级函数的栈顶地址出栈保存在ebp中(pop ebp)。因此,每一个函数的栈顶上面都保存着上一级函数的栈顶地址,用于当前函数结束时能够返回上一级函数的栈,通过ebp和esp以及压栈出栈操作对栈进行维护。逐条分析main函数对应的汇编代码如下7:intmain()8: 00401020 push ebp/ ebp初始为0018FF84h压栈,压栈后esp = 0018FF48h - 4 = 0018FF44h00401021 mov ebp,esp/ ebp保存栈顶0,ebp=esp=0018FF44h00401023 sub esp,48h/ esp -= 48h开辟了一段栈空间,留待后面保存局部变量,此时esp=0018FF44h-48h=0018FEFCh00401026 push ebx00401027 push esi00401028 push edi/ ebx、esi和edi压栈,esp = 0018FEFCh - 4*3 = 0018FEF0h00401029 lea edi,ebp-48h/ lea指令将ebp-48h作为偏移地址保存在edi中,edi=0018FEFCh,即栈中ebx的上面0040102C mov ecx,12h00401031 mov eax,0CCCCCCCCh00401036 rep stos dword ptr edi/ 将eax重复保存在以edi开始的栈空间里,重复次数为ecx次,向高地址方向,共覆盖12h*4=48h个地址,即栈中保存ebx的地址以上到ebp指向的地址这一段全部填充为cch9:inti = 4;00401038 mov dword ptr ebp-4,4/ 保存变量i10:intj = 5;0040103F mov dword ptr ebp-8,5/ 保存变量j11: m = fun(i, j);00401046 mov eax,dword ptr ebp-8/ 将j保存在eax中00401049 push eax/ eax压栈, esp=0018FEF0h-4=0018FEECh0040104A mov ecx,dword ptr ebp-4/ 将i保存在ecx中0040104D push ecx/ ecx压栈,esp=0018FEECh-4=0018FEE8h0040104E call ILT+0(_fun) (00401005)/ 以上实际上是为形参分配内存,顺序从右到左,此步进行函数跳转00401053 add esp,8/ 形参的地址回收,esp=0018FEE8h+8=0018FEF0h00401056 mov _m (00424a30),eax/ 返回值存放在静态变量m中12:return0;0040105B xor eax,eax/ 返回值置为013: 0040105D pop edi0040105E pop esi0040105F pop ebx00401060 add esp,48h00401063 cmp ebp,esp00401065 call _chkesp (004010d0)0040106A mov esp,ebp0040106C pop ebp0040106D retfun函数的汇编代码理解15:intfun(inta,intb)16: 00401090 push ebp00401091 mov ebp,esp00401093 sub esp,44h00401096 push ebx00401097 push esi00401098 push edi00401099 lea edi,ebp-44h0040109C mov ecx,11h004010A1 mov eax,0CCCCCCCCh004010A6 rep stos dword ptr edi/ 以上理解同main函数,ebp压栈时保存的地址是0018FF44h,即main函数栈开始开始的地方,然后ebp指向当前函数栈开始的地方17:intc = 0;004010A8 mov dword ptr ebp-4,0/ 为c分配地址,并赋值18: c = a + b;004010AF mov eax,dword ptr ebp+8/ 获得第一个参数004010B2 add eax,dword ptr ebp+0Ch/ 与第二个参数求和004010B5 mov dword ptr ebp-4,eax/ 结果保存在c中19:returnc;004010B8 mov eax,dword ptr ebp-4/ 返回值存放在eax20: 004010BB pop edi/ 现场恢复004010BC pop esi004010BD pop ebx004010BE mov esp,ebp/ 当前函数栈空间回收,以后可重新分配,esp=0018FEE8h004010C0 pop ebp/ ebp恢复为0018FF44h004010C1 ret/ 返回,等待执行函数调用的下一条指令调用fun函数时的内存情况局部变量i和j保存在48h空间的开始位置(高地址),即栈底附近,如下图在调用fun函数之前,将形参从右至左依次压栈,如下图call fun函数时执行跳转来源:未知/所属分类:技术资料/更新时间:2015-11-24 22:25
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号