发现文字描述还是太没有快感。上几幅图,来说明这个调试过程更好。此文对于深刻理解ebp,esp是具有长远意义的

可以看到,初始情况下,ebp此时值为0012FEDC,也就是栈帧的地址,而栈顶地址esp值为0012FDFC。可以看到两个值有一定的关系。而帧指针的地址较高。

然后我们让它执行前两句,push ebp,mov ebp,esp

可以看到前两句已经执行了,那么ebp跟esp的值也发生了变化。esp=0012FDF8,ebp=0012FDF8。为神马?一句句解读,push ebp,向栈里面压入了一个东西,那么栈顶此时应该发生变化了,也就是地址-4字节。为什吗是减法呢?因为是向低地址增长的,这点一定得注意。所以此时esp变化成了0012FDFC-4=OO12FDF8.至于ebp也等于0012FDF8就不解释了

接着上图不解释:

此时呢,观察现在的值。栈顶esp=0012FDF4,而ebp=0012FDF8;没啥好说的,此时的栈顶已经又跑上去了,说明又有元素压栈了。那么执行这句mov
esp,ebp之后,不用说,esp跟ebp都会变成0012FDF8.我们重点看下一幅,执行完pop,让ebp出栈,后会发生神马。

此时ebp已经出栈了,来看看那他们的值,esp=0012FDFC,ebp=0012FEDC.首先,ebp出栈了,这个时候栈空了,所以栈顶会变成初始时的值001212FDFC。相当于上图中的esp=0012FDF8+4=0012FDFC.注意出栈,则栈顶+4,然后呢。ebp为啥变成了0012FEDC初始的值?ebp不是一直保存着esp的初始地址么?

所以重点就在pop这个语句了。pop ebp究竟表达神马意思?ebp的值起初存在了栈中,出栈以后,它的值就恢复了原样。所一句灰常重要啊。pop的意思也许就是把弹出的值赋给我们的变量,pop  ebp,也就是把存在栈中的值弹出来赋给ebp。

所以我们在啰唆几句:

1、两句的mov ebp,esp实际上是把ebp进栈后的栈顶地址给了ebp。

2、在ebp没有出栈钱,它会一直保存ebp进栈以后的栈顶值,也就是1的值。

3、在ebp出栈前,需要把esp恢复到只有ebp在栈中时的值。

4、出栈后,esp自然恢复到ebp进栈以前的初始值,而pop ebp则恢复了ebp的初始值。

5、pop的语义很重要,pop  ebp的意思是把当前栈顶的元素出栈,送入ebp中,而不是让ebp出栈,这点必须明确!

       说完这个以后,我也有了疑问,因为从上面的解释来看,似乎栈里面的东西没有清空?就直接把esp恢复到了ebp的值,这是为神马呢?发现这就是所谓的栈平衡问题,先不纠结了,只要有前两句push ebp, mov ebp,esp跟最后两句mov esp,ebp,pop  ebp就够了,这样肯定不会有问题。

      搞点学习笔记,比较下cmp跟test的指令,这两个都是比较检测指令。

     cmp  eax,xxxx,意思是让两者相减,但是并不保存运算的结果,只用来影响相应的标志位,从而判断是否执行跳转,比如说一下的例子是很常见的:

   cmp eax,1

   JE xxxx

JE的跳转条件是:ZF=0,也就是当两者相等的时候,执行跳转。那么这个命令组合起来就是表示:如果eax=1,执行跳转

顺便 再说下JNE,JNE的意思是jump if not eaqual,也就是跟JE的判断条件相反

       然后说下TEST吧,test eax,xxx:意思是让eax跟xxx执行与运算,同样也是不保存运算结果,而影响相应的标志位,TEST呢经常用来干下面这件事情.

    test eax,eax

    JZ    xxxx

    意思很明显,就是检测EAX的值是不是0,所以这个语句就是检测判断语句。JZ嘛就是jump if zero。组合起来也就是表示如果eax为0,执行跳转到xxxx。

      觉得还是CALL指令最难理解,它先把IP压栈,然后跳到子程序里面去执行东西,最后IP出栈,指令返回到先前执行的地方。继续OD吧。

 __________________________________________________________________________________________________________

       经过了激励的思想斗争,我终于想清楚了这个过程。现在可以毫无压力的,淡定的说,ebp保存的是栈帧起始的其实地址,也就是一个函数属于自己的内存那一块的最高地址,而esp就保存了当前的这一块地址中已经使用的最低地址,说起来可能有些拗口。但是这对于深刻理解这个过程是至关重要的。

       有一句话让我想明白了这个道理,ebp总是跟旧的栈帧的顶部相邻。这样我们就可以理解为什么,调用一个函数的时候需要push ebp,那就保存旧的栈帧,同时也给出了我们得到旧的ebp的方法,一旦当前的栈帧使用完毕以后,这个最后弹出来的ebp就指明了我们怎么样回到旧的函数的栈帧,或者知道那个调用我们的上一层函数的栈帧。mov ebp,esp这句话很有迷惑性。其实很好理解,这个告诉了我们新的栈帧是怎么创建的,其实就是直接的拿当前函数(ebp已经入栈后)的栈顶当做新的栈帧头部,因为此时已经有esp=ebp了,而旧的ebp被我们保存在了栈里面。

      关于这个布局,CSAPP说的很清楚,深刻的理解了以上两句的作用,很多事情都能顺理成章的想通了。

其实说白了,ebp只有一个作用,就是用来暂时保存当前函数栈的起始地址,因为旧的栈帧跟新的栈帧是相邻的,ebp相当于起一个咋暗示的temp的作用。

esp跟ebp跟踪记录的更多相关文章

  1. esp和ebp详解

    最近在研究栈帧的结构,但总是有点乱,所以写了一个小程序来看看esp和ebp在栈帧中的作用.这个程序如下: 这个程序很简单,就是求两个数的值,然后输出即可.所以首先把它用gcc编译链接成a.out,进入 ...

  2. Android内存管理(5)*官方教程:Logcat内存日志各字段含义,查看当前内存快照,跟踪记录内存分配,用adb查看内存情况时各行列的含义,捕获内存快照的3种方法,如何让程序暴漏内存泄漏的方法

    Investigating Your RAM Usage In this document Interpreting Log Messages                 内存分析日志中各消息的含 ...

  3. StackTrace堆栈跟踪记录详细日志

    使用StackTrace堆栈跟踪记录详细日志(可获取行号) 2014-04-25 22:30 by 螺丝钉想要螺丝帽, 350 阅读, 3 评论, 收藏, 编辑 上一篇我们提到使用.NET自带的Tra ...

  4. node+mysql,实现基本的增删改查,附带跟踪记录和运行时间记录

    Node + mysql 实现基础的增删改查,以及性能测试. 网上有很多这样的例子,我也是找来学习的. 感觉node对mysql的操作非常简单,也很实用,比如自带防止sql注入的功能,一开始还担心注入 ...

  5. ASM X86&&X64 Registers 对寄存器ESP和EBP的一些理解

    ESP EIP EBP : frame pointer(base address of stack) Calling Convention: 调用约定 为什么fun调用之后 esp -ebp = 20 ...

  6. 对寄存器ESP和EBP的一些理解

    PS:EBP是当前函数的存取指针.即存储或者读取数时的指针基地址:ESP就是当前函数的栈顶指针. 每一次发生函数的调用(主函数调用子函数)时,在被调用函数初始时,都会把当前函数(主函数)的EBP压栈, ...

  7. [Android Pro] ESP和EBP 栈顶指针和栈底指针

    cp:  http://blog.csdn.net/hutao1101175783/article/details/40128587 (1)ESP:栈指针寄存器(extended stack poin ...

  8. 【转】 关于寄存器ESP和EBP的一些理解

    原文: http://blog.csdn.net/zsJum/article/details/6117043 一直对寄存器ESP和EBP的概念总是有些混淆,查看定义ESP是栈顶指针,EBP是存取堆栈指 ...

  9. (转)对于ESP、EBP寄存器的理解

    原文地址https://blog.csdn.net/yeruby/article/details/39780943 esp是栈指针,是cpu机制决定的,push.pop指令会自动调整esp的值: eb ...

随机推荐

  1. Spring MVC拦截器配置

    Spring MVC拦截器配置 (1)自定义拦截器 package learnspringboot.xiao.other; import org.springframework.web.servlet ...

  2. 「学习笔记」ST表

    问题引入 先让我们看一个简单的问题,有N个元素,Q次操作,每次操作需要求出一段区间内的最大/小值. 这就是著名的RMQ问题. RMQ问题的解法有很多,如线段树.单调队列(某些情况下).ST表等.这里主 ...

  3. Clover软件使用中遇到的问题

    安装Clover应用后不生效,Win + E 时仍然默认打开系统的资源管理器 解决: 进入ie浏览器的管理加载项窗口,显示栏选择所有加载项 找到 Explorer Watcher Class 项,确保 ...

  4. schedule of 2016-10-09~2016-10-16(Sunday~Sunday)——1st semester of 2nd Grade

    most important things to do 1.prepare for toefl 2.joint phd preparations 3.ieee trans thesis to writ ...

  5. AcWing 240. 食物链 | 并查集

    传送门 题目描述 动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形. A吃B, B吃C,C吃A. 现有N个动物,以1-N编号. 每个动物都是A,B,C中的一种,但是我们并不知道它到底 ...

  6. 使用SqlDependency实时监听SQL server数据库变化并执行事件

    sql server设置:ALTER DATABASE <DatabaseName> SET ENABLE_BROKER;语句让相应的数据库启用监听服务,以便支持SqlDependency ...

  7. es snapshot备份到hdfs及从hdfs恢复snapshot

    snapshot可以将es整个集群,具体索引数据备份到磁盘,hdfs等.需要时,可以从磁盘,hdfs恢复数据到es. 具体参考: https://elasticsearch.cn/article/61 ...

  8. 【Java基础总结】IO流

    字节流 1. InputStream 字节输入流 代码演示 InputStream in = System.in; System.out.println("int read(byte b) ...

  9. 使用wireshark 对flutter 框架APP进行抓包

    引言 最近公司开发一个APP,由于原生人力不足,直接由前端使用flutter 开发的,而使用flutter框架开发的客户端 fiddler无法抓到包,所以我采用wireshark从路由层面抓包 fid ...

  10. fill 的用法

    博客 : http://blog.csdn.net/liuchuo/article/details/52296646 fill函数的作用是:将一个区间的元素都赋予val值.函数参数:fill(vec. ...