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的地址 ---------------------------------------- ...
随机推荐
- cocos2dx 编译时间长问题
{ F:\cocos2dx\cocos2d-x-3.7.1\templates\cpp-template-default 彻底解决方式 为把cocos的模版项目编译好(详细是所有生成好并清理Hello ...
- Sql2005常用函数大全
--聚合函数use pubsgoselect avg(distinct price) --算平均数from titleswhere type='business'go use pubsgoselect ...
- VS2010 使用TeeChart绘图控件 - 之一 - 控件和类的导入
vs2010的用法和vc6有很大的不同,特别是在一些函数调用那里,当然.控件导入也是很不一样的 安装好控件后就可以在工程里加入teechart控件了 加入方法有如下几种: 1.添加Teechart控件 ...
- LCT教程
lct是一种动态树,用来维护一些动态加边删边的操作的东西.他主要用到几个操作,其实这个算法和树链刨分有点像,但是不能用线段树简单维护,所以我们要用多棵平衡树来维护树上的一个个子树,然后就进行一些很秀的 ...
- HDU3487 Play with Chain splay 区间反转
HDU3487 splay最核心的功能是将平衡树中的节点旋转到他的某个祖先的位置,并且维持平衡树的性质不变. 两个操作(数组实现) cut l,r, c把[l,r]剪下来放到剩下序列中第c个后面的位置 ...
- bzoj3663
几何+lis 很巧妙.直接做很困难,那么我们转化一下,把每个点能看见的圆弧画出来.只有这些圆弧相交时才满足条件. 那么也就是找出圆上尽量多两两相交的区间. 所以我们先按左端点极角排序,然后固定一个必须 ...
- P2420 让我们异或吧(倍增)
题目描述 异或是一种神奇的运算,大部分人把它总结成不进位加法. 在生活中…xor运算也很常见.比如,对于一个问题的回答,是为1,否为0.那么: (A是否是男生 )xor( B是否是男生)=A和B是否能 ...
- 洛谷P1250种树(贪心)
题目描述 一条街的一边有几座房子.因为环保原因居民想要在路边种些树.路边的地区被分割成块,并被编号成1..N.每个部分为一个单位尺寸大小并最多可种一棵树.每个居民想在门前种些树并指定了三个号码B,E, ...
- [Swift通天遁地]二、表格表单-(17)制作在表单左侧添加单选和复选组件的表单行
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...
- Jenkins-SVN + Maven + Docker
第1步:安装插件 Subversion Plug-inMaven Integration pluginCloudBees Docker Build and Publish pluginDeploy t ...