原文:http://blog.csdn.net/yeruby/article/details/39780943

esp是栈指针,是cpu机制决定的,push、pop指令会自动调整esp的值;

ebp只是存取某时刻的esp,这个时刻就是进入一个函数内后,cpu会将esp的值赋给ebp,此时就可以通过ebp对栈进行操作,比如获取函数参数,局部变量等,实际上使用esp也可以;

既然使用esp也可以,那么为什么要设定ebp呢?

答案是为了方便程序员。

因为esp在函数运行时会不断的变化,所以保存一个一进入某个函数的esp到ebp中 会方便程序员访问参数和局部变量,而且还方便调试器分析函数调用过程中的堆栈情况。前面说了,这个ebp不是必须要有的,你非要使用esp来访问函数参数 和局部变量也是可行的,只不过这样会麻烦一些。

通过一段程序理解esp和ebp:

main() {

//执行test前

print(int p1,int p2);

//执行test后

}

分析下上面程序的调用原理,假设执行print前esp=Q:

push p2; //函数参数p2入栈,esp=Q-4H

push p1; //函数参数p1入栈,esp=Q-8H

call print; //函数返回地址入栈,esp=Q-0CH

//现在进入print内,做些准备工作:

push ebp; //保护先前ebp指针,ebp入栈,esp=Q-10H

mov esp,ebp; //设置ebp等于当前的esp

// 此时,ebp+0CH=Q-4H,即p2的位置

// 同样,ebp+08H=Q-8H,即p1的位置

// 下面是print内的一些操作:

sub esp,20H; //设置长度为10H大小的局部变量空间,esp=Q-20H

// ... ...

// 一系列操作

// ... ...

add esp,20H; //释放局部变量空间,esp=Q-10H

pop ebp; //出栈,恢复原先的ebp的值,esp=Q-0CH

ret 8; //ret返回,弹出先前入栈的返回地址,esp=Q-08H,后面加操作数8H为平衡堆栈

// 之后,弹出函数参数,esp=Q,恢复执行print函数前的堆栈;

图示,注意栈在内存中的生长方向是逆向:

执行push p2;前,esp=Q;

执行push p2;过程中,esp-=4H,p2入栈;

执行push p2;后,esp=Q-4H;

最新文章

  1. 【转载】latch: cache buffers chains
  2. VMware如何实现和主机共享网络上网
  3. Linux echo, sort, sed 等一些命令总结
  4. 操作系统开发系列—13.g.操作系统的系统调用 ●
  5. VFS分析(二)基本数据结构(持续更新)
  6. 三大UML建模工具Visio、Rational Rose、PowerDesign的区别
  7. Tomcat 安装--小白教程
  8. Nuget 摘录
  9. How to compile and install NCAR Command Language on IBM PowerPC 64 --- NCL编译安装步骤
  10. mac mysql安装
  11. C#使用参数数组
  12. iOS中解析json多种方法
  13. 模板C++ 03图论算法 2最短路之全源最短路(Floyd)
  14. Bottle源码阅读笔记(二):路由
  15. [leetcode-560-Subarray Sum Equals K]
  16. 十二、JDBC
  17. Jetson TX1 install py-faster-rcnn
  18. SSE图像算法优化系列九:灵活运用SIMD指令16倍提升Sobel边缘检测的速度(4000*3000的24位图像时间由480ms降低到30ms)。
  19. useradd语法2
  20. Python下载安装

热门文章

  1. linux影响上传文件大小的因素
  2. Vim编辑器的学习
  3. console的使用
  4. POJ1511 Invitation Cards SPFA算法裸题变形
  5. [TJOI2013]松鼠聚会 BZOJ 3170
  6. 10.Find All Anagrams in a String(在一个字符串中发现所有的目标串排列)
  7. Spring Security获取已登录的用户信息的两种方法
  8. js 弹性菜单
  9. CSS background-size contain 与cover的区别
  10. 随笔1:Markdown语法学习