发现文字描述还是太没有快感。上几幅图,来说明这个调试过程更好。此文对于深刻理解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. 【一起学源码-微服务】Ribbon 源码一:Ribbon概念理解及Demo调试

    前言 前情回顾 前面文章已经梳理清楚了Eureka相关的概念及源码,接下来开始研究下Ribbon的实现原理. 我们都知道Ribbon在spring cloud中担当负载均衡的角色, 当两个Eureka ...

  2. 洛谷P1035 级数求和 题解 简单模拟

    题目链接:https://www.luogu.com.cn/problem/P1035 题目描述 已知:\(S_n= 1+1/2+1/3+-+1/n\).显然对于任意一个整数 \(k\),当 \(n\ ...

  3. 1052 卖个萌 (20 分)C语言

    萌萌哒表情符号通常由"手"."眼"."口"三个主要部分组成.简单起见,我们假设一个表情符号是按下列格式输出的: [左手]([左眼][口][右 ...

  4. iscsi,nfs

    存储概述 存储的目标 存储是根据不同的应用环境通过采取合理.安全.有效的方式将数据保存到某些介质上并能保证有效的访问. 一方面它是数据临时或长期驻留的物理媒介. 另一方面,它是保证数据完整安全存放的方 ...

  5. js原生深拷贝

    /*****************************************************************************************/ 原生js实现深拷 ...

  6. OpenJ_Bailian 7617 输出前k大的数

    题目传送门 OpenJ_Bailian 7617 描述 给定一个数组,统计前k大的数并且把这k个数从大到小输出. 输入 第一行包含一个整数n,表示数组的大小.n < 100000.第二行包含n个 ...

  7. [转]Linux制作启动盘

    假设你想备份一个叫做 /home/joeuser/ 的目录,但是不想包括子目录 /home/joeuser/junk/,因为其中包括的都是不必要的文件.你想创建一个叫做 backup.iso 的映像, ...

  8. IDEA 2019.2及以下版本永久激活教程(亲测可用)

    写在前面 由于最近jetbrains公司开始严厉打击盗版激活码,所以导致一大批激活码失效,我身边的小伙伴对于如此苦恼,但是由于考虑到正版费用还是比较高昂的前提下,所以鉴于此,遂将之前整理的jar包激活 ...

  9. MySQL数据库保存emoji表情

    何为emoji表情?这里的全是. MySQL数据库为什么不能存储emoji?不是MySQL不能,而是MySQL的utf8编码不能!原来MySQL下的utf8编码每个字符占3个字节,而emoji占4个字 ...

  10. echarts更改折线图区域颜色、折线颜色、折点颜色

    series : [ { name:'订单流入总数', type:'line', stack: '总量', areaStyle: { normal: { color: '#8cd5c2' //改变区域 ...