ESP、EBP、CALL 指令与局部变量浅析
概述
函数调用是计算机程序中一个最重要的概念之一,从汇编的角度看,能更加直观地理解函数调用的原理,理解 CALL 指令调用过程中 ESP、EBP 寄存器的作用。
我们先从一段简陋的 C 语言代码说起,我们首先调用了 printf 函数,为什么要调用 printf 函数呢?实际上是为了更方便地在 OllyDBG 反汇编工具中断点,能更好地定位到 fun 函数的位置(因为 fun 函数的 CALL 将紧跟着 printf 函数的 CALL)。
在 fun 函数中,我们定义两个 int 型变量(两个 4 字节的变量),给 a 赋值了 0,给 b 赋值了 2。

我们用 OllyDBG 载入,在 printf 函数处下断点,运行在断点处暂停下来,在堆栈窗口中按 Enter 跟随到反汇编处,我们来到了下图所示的位置,第一行就是 main 函数这个 CALL 的段首,首先把 EBP 压栈,为了保存外层代码的 EBP 的值,使这个 CALL 不影响外层代码的 EBP 的值。然后第二行,程序将 ESP 赋值给 EBP。此时,EBP 与 ESP 重合。
第三行是一个 PUSH 指令,它将指向字符串的指针压栈,这个指针指向的是“this is a break point”字符串,第四行程序执行 CALL 指令调用 printf 函数,printf 函数将从堆栈中取出参数进行处理,最终在终端中打印出字符串。换言之,参数通过堆栈传递给 printf 函数,就像 C 语言那样。

第五行将 ESP 增加了 4,然后下一行程序直接 CALL 了 fun 函数。我们按 Enter 键跟进到 fun 函数内部,如下图。

在 fun 函数内部,EBP 又被压栈,然后 EBP 被赋值成 ESP 的值(有点像之前 main 函数段首的情形)
注意第三行,ESP 被减少了 8,这样的话,EBP 就比 ESP 多 8。第四行与第五行是 MOV 赋值指令,首先立即数 0 赋值给了 EBP – 4 的位置,然后立即数 2 赋值给了 EBP – 8 的位置。
让我们来仔细分析一下,不难看出,ESP 减少 8,使得 ESP 与 EBP 相隔 8 字节的地址位置,换言之,ESP 与 EBP 中间有 8 字节的空隙,此时 ESP 比 EBP 小 8。而接下来的两行 MOV 指令将 EBP – 4 这个地址,EBP – 8 这个地址,分别赋值了 0 和 2,这两个 4 字节的 int 整数型数据,a 和 b 两个局部变量刚好填满了 ESP 与 EBP 中间 8 字节的空隙。我们可以作图理解它的结构:

局部变量的堆栈赋值完成以后,函数的基本功能就执行完了。这时,ESP 被赋值成 EBP 的值(跟 fun 函数开头刚好相反,开头是 EBP 被赋值成 ESP) ,相当于将 ESP 还原函数调用之前的状态。下一行,从堆栈中弹出 EBP 的值(也就是 fun 函数开头 PUSH 的 EBP 值),也相当于将 EBP 还原成函数调用之前的状态,最后执行 RETN 指令返回到 CALL 处的下一行,fun 函数就执行完毕了。
补充
本例中并没有演示函数参数在堆栈中的存放规则,只演示了局部变量的。
实际上,函数参数存放在比 EBP 大的位置,和局部变量存放的地址增长方向恰恰相反。也就是说,如果多定义一个局部变量,ESP 会越来越小于 EBP,它们之间的“空隙”会越来越大,以存放更多的局部变量。但是,如果给函数多增加一个参数,函数调用者的 ESP (也就是被调用者的 EBP)会越来越大于 ESP,“空隙”也将存放更多的参数,因为函数的参数会在调用者去 CALL 被调用者之前被压栈,ESP 将增大,这个 ESP 将成为被调用者的 EBP。最终,我们看到的就是函数中局部变量的地址比 EBP 小,而函数的参数的地址比 EBP 大,它们以 EBP 为界,且地址增长方向相反。
ESP、EBP、CALL 指令与局部变量浅析的更多相关文章
- .NET内存管理、垃圾回收
1. Stack和Heap 每个线程对应一个stack,线程创建的时候CLR为其创建这个stack,stack主要作用是记录函数的执行情况.值类型变量(函数的参数.局部变量 等非成员变量)都分配 ...
- 【转】.NET内存管理、垃圾回收
1. Stack和Heap 每个线程对应一个stack,线程创建的时候CLR为其创建这个stack,stack主要作用是记录函数的执行情况.值类型变量(函数的参数.局部变量 等非成员变量)都分配 ...
- 2017-2018-1 20179205《Linux内核原理与设计》第二周作业
<Linux内核原理与分析>第二周作业 本周视频学习情况: 通过孟老师的视频教程,大致对风诺依曼体系结构有了一个初步的认识,视频从硬件角度和程序员角度对CPU和Main Memory(内存 ...
- 浅析VS2010反汇编 VS 反汇编方法及常用汇编指令介绍 VS2015使用技巧 调试-反汇编 查看C语言代码对应的汇编代码
浅析VS2010反汇编 2015年07月25日 21:53:11 阅读数:4374 第一篇 1. 如何进行反汇编 在调试的环境下,我们可以很方便地通过反汇编窗口查看程序生成的反汇编信息.如下图所示. ...
- [Android Pro] ESP和EBP 栈顶指针和栈底指针
cp: http://blog.csdn.net/hutao1101175783/article/details/40128587 (1)ESP:栈指针寄存器(extended stack poin ...
- (转)对于ESP、EBP寄存器的理解
原文地址https://blog.csdn.net/yeruby/article/details/39780943 esp是栈指针,是cpu机制决定的,push.pop指令会自动调整esp的值: eb ...
- 对于ESP、EBP寄存器的理解
原文:http://blog.csdn.net/yeruby/article/details/39780943 esp是栈指针,是cpu机制决定的,push.pop指令会自动调整esp的值: ebp只 ...
- 栈帧%ebp,%esp详解
首先应该明白,栈是从高地址向低地址延伸的.每个函数的每次调用,都有它自己独立的一个栈帧,这个栈帧中维持着所需要的各种信息.寄存器ebp指向当前的栈帧的底部(高地址),寄存器esp指向当前的栈帧的顶部( ...
- EBP与ESP寄存器的使用
push ebp mov esp,ebp esp是堆栈指针 ebp是基址指针 这两条指令的意思是将栈顶指向ebp的地址 ---------------------------------------- ...
随机推荐
- C#之选择排序
算法描述 1.假定未排序序列中第一位为数组最小值,通过与后面的数值进行比较,找到未排序序列中最小值,与未排序序列第一位交换位置: 2.重复步骤一,对剩余未排序序列进行比较找出最小值,与未排序序列中第一 ...
- TomCatserver的安装,环境的配置,服务的启动以及验证---ShinePans
首先下载 TomCat 6: http://yunpan.cn/cg5icf3dha4k3 提取码 34c5 然后配置环境变量: 电脑>>>属性>>>高级系统设置 ...
- 专注UI——是alert()打败了你!
在上家公司.常常在页面上写aler()提示代码.没有认为有什么,好寻常.认为提示就本来应该是这种,可是,当我到了这家公司.在測试的时候,由于測试人员看到了一个aler弹出框.结果我的页面被退回重写,后 ...
- 【Bzoj2260】【Bzoj4349】商店购物 & 最小树形图
目录 List Bzoj 2260 商店购物 Description Input Output Sample Input Sample Output Bzoj 4349 最小树形图 Descripti ...
- MySQL 字符编码问题详细解释
http://www.codesoil.net/tag/charset Character Set Problem in PHP + MySQL4.1+ 和许多人一样,我也是在转移blog时才发现这个 ...
- PCB 规则引擎之编辑器(语法着色,错误提示,代码格式化)
对于一个规则引擎中的脚本代码编辑器是非常关键的,因为UI控件直接使用对象是规则维护者,关系到用户体验,在选用脚本编辑器的功能时除了满足代码的编辑的基本编辑要求外,功能还需要包含;语法着色,错误提示,代 ...
- A. Train and Peter
A. Train and Peter time limit per test 1 second memory limit per test 64 megabytes input standard in ...
- 设计模式 | 适配器模式(adapter)
定义: 将一个类的接口转换成客户希望的另外一个接口.Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作. 书中说到Gof的设计模式中,讲了两种类型的适配器模式: 1.类适配 ...
- flask中内置的session
Flask中的Session非常的奇怪,他会将你的SessionID存放在客户端的Cookie中,使用起来也非常的奇怪 1. Flask 中 session 是需要 secret_key 的 from ...
- [转]Window2008站点安全设置,IIS7/IIS7.5中目录执行权限的设置方法
本文转自:http://blog.snsgou.com/post-510.html 最近帮一个朋友管理Window 2008服务器,发现有个站点是用asp写的,更可怕的是还有传说中的“上传漏洞”,在上 ...