打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
函数调用堆栈变化情况

函数调用堆栈变化情况

分类: C++语言 319人阅读 评论(0) 收藏 举报

  1. int goo(int a, int b)  
  2. {  
  3.     return a + b;  
  4. }  
  5.   
  6. void foo()  
  7. {  
  8.     int a[] = {1, 2, 3};  
  9.     int result = goo(a[1], a[2]);  
  10.     printf("result: %d", result);  
  11. }  

VS2010下编译


foo函数部分汇编:

  1. 00EB3890  push        ebp    
  2. 00EB3891  mov         ebp,esp    
  3. 00EB3893  sub         esp,0E4h    
  4. 00EB3899  push        ebx    
  5. 00EB389A  push        esi    
  6. 00EB389B  push        edi    
  7. 00EB389C  lea         edi,[ebp-0E4h]    
  8. 00EB38A2  mov         ecx,39h    
  9. 00EB38A7  mov         eax,0CCCCCCCCh    
  10. 00EB38AC  rep stos    dword ptr es:[edi]    
  11. 00EB38AE  mov         eax,dword ptr [___security_cookie (0EB7000h)]    
  12. 00EB38B3  xor         eax,ebp    
  13. 00EB38B5  mov         dword ptr [ebp-4],eax    
  14.     int a[] = {1, 2, 3};  
  15. 00EB38B8  mov         dword ptr [ebp-14h],1    
  16. 00EB38BF  mov         dword ptr [ebp-10h],2    
  17. 00EB38C6  mov         dword ptr [ebp-0Ch],3    
  18.     int result = goo(a[1], a[2]);  
  19. 00EB38CD  mov         eax,dword ptr [ebp-0Ch]    
  20. 00EB38D0  push        eax    
  21. 00EB38D1  mov         ecx,dword ptr [ebp-10h]    
  22. 00EB38D4  push        ecx    
  23. 00EB38D5  call        goo (0EB11E5h)    
  24. 00EB38DA  add         esp,8    

goo函数完整汇编:

  1. 00EB1580  push        ebp    
  2. 00EB1581  mov         ebp,esp    
  3. 00EB1583  sub         esp,0C0h    
  4. 00EB1589  push        ebx    
  5. 00EB158A  push        esi    
  6. 00EB158B  push        edi    
  7. 00EB158C  lea         edi,[ebp-0C0h]    
  8. 00EB1592  mov         ecx,30h    
  9. 00EB1597  mov         eax,0CCCCCCCCh    
  10. 00EB159C  rep stos    dword ptr es:[edi]    
  11.     return a + b;  
  12. 00EB159E  mov         eax,dword ptr [a]    
  13. 00EB15A1  add         eax,dword ptr [b]    
  14. }  
  15. 00EB15A4  pop         edi    
  16. 00EB15A5  pop         esi    
  17. 00EB15A6  pop         ebx    
  18. 00EB15A7  mov         esp,ebp    
  19. 00EB15A9  pop         ebp    
  20. 00EB15AA  ret    


foo函数push ebp, mov ebp, esp后

保存原ebp,设定新的ebp为当前esp位置



sub esp, 0E4h

给局部变量分配足够大的栈空间


保存原先的一些寄存器值,每次push,esp继续向下移



为局部变量a数组赋值


调用goo前Push两个参数,esp继续下移


call goo函数时,cpu自动push下一条指令地址,esp继续下移

在goo函数中,同样保存foo函数中的ebp值,设定新的ebp,esp等


在执行玩goo函数最后几句指令时,edi, esi, ebx恢复,esp同时也编程goo中ebp的位置,ebp恢复至foo函数原来的位置(pop ebp)

下一条指令也装入IP(ret指令),esp继续向上一步



foo函数中的add esp, 8将esp值继续往上(清除函数参数)

清除函数参数的工作也可通过ret X在goo函数返回时设定(这样的话不必在每次调用点上加上add esp, X指令缩短了编译出来的文件大小,但在子函数中清除将不能做到printf等的可变参数个数功能,因为子函数不知道具体有多少要参数进入了,只有调用处才知道)

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
献给汇编初学者-函数调用堆栈变化分析
一个简单的C++程序反汇编解析
qq反汇编日志
【代码真相】函数调用 堆栈 转载 - liangxiufei - 博客园
DLL中调用约定和名称修饰(一)
函数调用方式介绍
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服