【原文】http://blog.csdn.net/xupan_jsj/article/details/7459630
  1. int goo(int a, int b)
  2. {
  3. return a + b;
  4. }
  5. void foo()
  6. {
  7. int a[] = {1, 2, 3};
  8. int result = goo(a[1], a[2]);
  9. printf("result: %d", result);
  10. }

VS2010下编译

foo函数部分汇编:

[cpp] view plaincopyprint?
  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
[cpp] view plaincopyprint?
  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函数完整汇编:

[cpp] view plaincopyprint?
  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
[cpp] view plaincopyprint?
  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等的可变参数个数功能,因为子函数不知道具体有多少要参数进入了,只有调用处才知道)

转载于:https://www.cnblogs.com/zzmx/p/4166443.html

【转】函数调用时堆栈变化相关推荐

  1. C++函数调用时堆栈的变化情况

    代码编译运行环境:VS2017+Debug+Win32 1.栈帧简介 函数的运行是在栈上展开的,每一个函数在被调用时所占用的内存空间就是栈,栈保存了一个函数调用需要维护的信息.函数栈通常被称为栈帧(S ...

  2. 从函数调用过程中的堆栈变化理解缓冲区溢出

    一.说明 本来是想直接写一个缓冲区溢出的例子,但是一是当前编译器和操作系统有溢出的保护措施没有完全弄清怎么取消,二是strcpy等遇到00会截断需要进行编码这比较难搞,所以最终没有实现. 但已经双看了 ...

  3. 献给汇编初学者-函数调用堆栈变化分析

    献给汇编初学者-函数调用堆栈变化分析 标 题: 献给汇编初学者-函数调用堆栈变化分析 作 者: 堕落天才 时 间: 2007-01-19,19:20 链 接: http://bbs.pediy.com ...

  4. 对PInvoke函数函数调用导致堆栈不对称。原因可能是托管的 PInvoke 签名与非托管的目标签名不匹配。...

    C#引入外部非托管类库时,有时候会出现"对PInvoke函数调用导致堆栈不对称.原因可能是托管的 PInvoke 签名与非托管的目标签名不匹配"的报错. 通常在DllImport标 ...

  5. ARM函数调用时参数传递规则

    之前在学习如何在C语言中嵌入汇编时有了解到C语言之前的参数调用是使用寄存器 R0传递第一个参数, R1传递到第二个.. 一直到R3传递第四个参数. 但是 实际上有时可能传递的参数非常多,超过8个,或是 ...

  6. 在c语言程序中,数组名做函数调用的实参时,传递给形参的是,若用数组名作为函数调用时的实参,则实际上传递给的形参的是(C)...

    若用数组名作为函数调用时的实参,则实际上传递给形参的是数组首地址. 数组首地址数组第一个元素的地址.数组名字本身就是一个指针,它是一个指针常量,指向的地址不变. 比如定义了一个数组变量,编译器就会在内 ...

  7. C/C++函数调用时参数传递过程、调用约定与可变参函数的实现

    目录 1.参数传递过程 2.参数压栈顺序从右至左的影响 3.调用约定 3.1.__cdecl C/C++ 缺省调用约定 3.2. __stdcall调用约定 3.3. __fastcall (快速调用 ...

  8. C#调用C/C++动态库dll异常:对 PInvoke 函数调用导致堆栈不对称问题

    结论:如果你是用C#调用C的动态库,如果出现"对 PInvoke 函数调用导致堆栈不对称问题",建议优先调整CallingConvention的值,建议改为CallingConve ...

  9. 【总结整理】javascript的函数调用时是否加括号

    javascript的函数调用时是否加括号 if(event.preventDefault){ event.preventDefault(); if判断条件里面不要加括号,不加括号是应该以属性形式,i ...

最新文章

  1. 钻进眼球的致盲寄生虫威胁近亿人,却只是生存竞争的失败者
  2. Cvmat IplImage
  3. redis存opc_KEPServerEX6完整免费版
  4. (译)你应该知道的jQuery技巧
  5. 利用维纳滤波编码实现给定的运动模糊图像恢复
  6. maven 总结整理(二)——download source code
  7. 用Spire.doc来合并邮件
  8. 大数据集群跨多版本升级、业务0中断,只因背后有TA
  9. 右侧按钮登录注册html,翻转式用户登录注册界面设计
  10. java安装时无法写入文件_Java - 无法写入第二个文件
  11. [总结] 本人代表性博客总结
  12. oracle安装失败 主机名_PeopleTool 8.58.04 安装
  13. 用grub4dos制作U盘启动盘winpe+红叶dos+maxdos+veket+linuxmint
  14. Unity粒子系统-粒子光环
  15. Android 9.0 10.0 手动安装Persistent app失败的解决方案
  16. ExpandableListView中不同条目的位置不同的显示位置
  17. 如何使用Hyper-V Manager和Powershell合并Hyper-V检查点
  18. 讯飞 AIUI 集成
  19. [Java]Spring Ioc讲解,不怕你不懂
  20. npm run dev命令报错解决方式

热门文章

  1. java 二维数组位置_请完成下列Java程序:查找一个矩阵中的鞍点,对于一个二维数组中的鞍点,该点位置上的元素在该行上...
  2. 【若依(ruoyi)】打开新的选项卡
  3. 【maven】dependency的systemPath属性:引入本地系统中的jar
  4. 最长回文串--动态规划
  5. python翻页_python实现电子书翻页小程序
  6. 技嘉主板万能网卡驱动_技嘉Z490系列主板来袭:16相供电/钽电容,堆料更进一步...
  7. php+字符串去掉反斜杠,PHP如何去掉反斜杠?
  8. linux定时器回调处理过程,Linux内核系统定时器TIMER实现过程分析
  9. java 命令行eclipse_在命令行中运行eclipse中创建的java项目
  10. 四阶显式Adams法求方程组C语言,第五讲第4章线性多步法(续