零、基本概念

1、ESP

栈指针寄存器(extended stack pointer),其内存放着一个指针,该指针永远指向系统栈最上面一个栈帧的顶部。

2、EBP

基址指针寄存器(extended base pointer),其内存放着一个指针,该指针永远指向系统栈最上面一个栈帧的底部。

一、栗子

以下摘自网上一篇文章: 

明白了吗?主要是用来保存 / 恢复堆栈,以便传递参数给函数。 
在 MASM 里面,有一条更方便的语句,就是 invoke,使用它后,你就不用自己做这些事情了。 

总的来说,esp 始终指向栈顶,ebp 是在堆栈中寻址用的。


我的理解:

调用一个函数时,先将堆栈原先的基址(EBP)入栈,以保存之前任务的信息。然后将栈顶指针的值赋给 EBP,将之前的栈顶作为新的基址(栈底),然后再这个基址上开辟相应的空间用作被调用函数的堆栈。

函数返回后,从 EBP 中可取出之前的 ESP 值,使栈顶恢复函数调用前的位置;再从恢复后的栈顶可弹出之前的 EBP 值,因为这个值在函数调用前一步被压入堆栈。这样,EBP 和 ESP 就都恢复了调用前的位置,堆栈恢复函数调用前的状态。

二、通过 ollydbg 跟踪 esp 和 ebp

可以看到,初始情况下,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 出栈了,这个时候栈空了,所以栈顶会变成初始时的值 0012FDFC。相当于上图中的 esp = 0012FDF8 + 4 = 0012FDFC。注意出栈,则栈顶 + 4,然后呢。ebp 为啥变成了 0012FEDC 初始的值?ebp 不是一直保存着 esp 的初始地址么?

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

三、流程图

EBP 和 ESP 后面的序号是两个寄存器各自更新的次序。  

四、总结

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 出栈,这点必须明确!

转载于:EBP 和 ESP 详解_测试开发小白变怪兽-CSDN博客_ebp

(SAW:Game Over!)

搞懂函数调用前后堆栈恢复的过程相关推荐

  1. 一文搞懂H264量化原理以及计算过程

    1.概述 量化是使数据比特率下降的有效工具.量化过程的输入值动态范围很大,需要较多的比特才能表示一个数值,量化后的输出则只需要较小比特表示. 量化是不可逆过程,处理过程中有信息丢失,存在量化误差. H ...

  2. 一篇文章搞懂人脸识别的十大过程

    2019-02-01 10:32:41 "人脸识别"大家已经听的很多了,但是这种识别方式到底是如何实现的,大家都知道吗? 1. 人脸检测 "人脸检测"是检测出图 ...

  3. 一文搞懂BN的原理及其实现过程(Batch Normalization)

    1. 在讲BN之前我要向大家提出几个问题,就是为什么要引入BN呢?在神经网络训练的时候输入图片不是引入了image normalization吗?所以BN到底是什么呢? Batch Normaliza ...

  4. 彻底搞懂平衡二叉树(AVL)建树过程(左旋、右旋)

    AVL树是最先发明的自平衡二叉查找树,得名于它的发明者G.M. Adelson-Velsky和E.M. Landis. 在AVL树中任何节点的两个子树的高度最大差别为一,所以它也被称为高度平衡树. 查 ...

  5. factorybean 代理类不能按照类型注入_彻底搞懂依赖注入(一)Bean实例创建过程

    点击上方"Java知音",选择"置顶公众号" 技术文章第一时间送达! 上一章介绍了Bean的加载过程(IOC初始化过程),加载完成后,紧接着就要用到它的依赖注入 ...

  6. 一文搞懂从浏览器输入一个URL到页面出现都经历了哪些过程

    1 过程一览 DNS解析(如果IP直接访问则此过程省略) 客户端与服务端进行TCP三次握手连接 客户端发送HTTP请求 服务器处理请求并返回HTTP报文 浏览器解析渲染页面 连接结束 2 细节剖析 2 ...

  7. 彻底搞懂JDBC的运行过程

    前几天笔者发布了博客手写mybatis彻底搞懂框架原理.为了帮助初学者更好理解mybatis框架,这次讲解一下Java的JDBC的运行过程. JDBC的作用 JDBC的全称是Java DataBase ...

  8. 【嵌入式】初学者一步一步搞懂内存管理

    [嵌入式]初学者一步一步搞懂内存管理 一.C语言局部变量.静态局部变量.全局变量与静态全局变量 基本概念 局部变量 全局变量 局部变量和全局变量的对比 二.虚拟地址空间.(深入理解计算机系统) bss ...

  9. 【四】彻底搞懂synchronized

    [四]彻底搞懂synchronized 废话不多说,我们先来看一个段代码,了解一个奇怪的现象 public class Synchronized03 implements Runnable {priv ...

最新文章

  1. 王思聪语录 - CV版
  2. PPT文字怎样规划 哪里可以代做PPT
  3. MySqli 连接失败 MySQL connection not working: 2002 No such file or directory
  4. 分享自己整理的《UIT备份容灾解决方案培训稿》
  5. 缺少物联网杀手级应用的运营商,到底该怎么办?
  6. 【MPS最佳实践】媒体工作流转码
  7. 5-8经典卷子神经网络结构介绍
  8. 计算机网络管理员技师题库那个好,计算机网络管理员高级技师题库.docx
  9. 短视频追剧的末日来了?
  10. C#中 String 格式的日期时间 转为 DateTime
  11. 解决echarts官网打不开访问失败问题
  12. aodv协议c语言实现,TinyOS在CC2530下的移植及AODV路由协议的实现
  13. 计算机组成原理与汇编语言设计,计算机组成原理与汇编语言网络教学整体设计方案...
  14. 产品部和业务部门是什么关系
  15. OpenGL_Qt学习笔记之_03(平面图形的着色和旋转)
  16. 【论文分享】GeoGAN:从卫星图像中生成地图的标准层
  17. 好省app靠谱吗到底怎么回事,好省平台是骗局吗
  18. android将图片转成字符串,再将字符串转成图片
  19. ANO匿名上位机V7协议STM32
  20. Matlab中绘制颜色渐变曲线

热门文章

  1. java多线程 -- 创建线程的第三者方式 实现Callable接口
  2. 【转】多种文件上传绕过手法
  3. mysql 性能分析 命令_MySQL中使用SHOW PROFILE命令分析性能的用法整理
  4. 一份MyBaits框架PDF文档,阿里架构师直言,Java程序员快收藏吧
  5. linux find批量替换java文件中字符串
  6. linux centos7内核降级和升级
  7. centos7.x 升级svn版本到指定版本(1.10)
  8. Jenkins添加从节点相关配置
  9. Scala入门示例反编译分析代码执行流程
  10. arthas命令整理:基础命令、jvm相关、class相关命令