品传集团网站建设所有复刻手表网站
- 作者: 五速梦信息网
- 时间: 2026年03月21日 10:15
当前位置: 首页 > news >正文
品传集团网站建设,所有复刻手表网站,网站后期的维护,免费ppt模板百度云资源文章目录1.函数的调用方式
2.函数在栈区上的动作
1.函数的调用方式
相信你对调用函数一点都不陌生#xff0c;但是在调用函数的过程中#xff0c;却存在着很多你无法见到的东西#xff0c;这是底层信息#xff0c;想要理解透彻#xff0c;就得深入底层去观察。
本文以…
文章目录1.函数的调用方式
2.函数在栈区上的动作
1.函数的调用方式
相信你对调用函数一点都不陌生但是在调用函数的过程中却存在着很多你无法见到的东西这是底层信息想要理解透彻就得深入底层去观察。
本文以一个最简单的加法函数为例深入讲解内存空间中的每一条指令。
int Add(int x, int y)
{int z 0;z x y;return z;
}int main()
{int a 10;int b 20;int c Add(a, b);printf(%d\n, c);return 0;
}这是源码以该源码为例。
首先我们进入调式 按如下图所示进行操作。
转到反汇编后开始观察每一条代码的执行指令在开始之前先提出几个常见的问题
1.局部变量是怎么创建的 2.局部变量未初始化为什么是随机的 3.函数是怎么传参的传参的顺序是怎么样的 4.形参和实参是什么关系 5.函数的调用是怎么做的 6.函数调用结束后是怎么返回的
以上问题都会通过下面的函数栈帧一一为你解答。
以下的讲解都是以低地址处在相对高的位置高地址在相对低的位置如下图 记住每一个函数的调用都会在栈区开辟一块内存空间。
栈空间的使用习惯是从高地址向低地址使用。
我们在main函数被调用时会在栈区开辟一块内存空间如下图 实际上main函数也是被其他函数调用的所以在main函数开辟栈空间之前一定会先开辟调用main函数的函数的栈空间。 在VS2019的环境下 通过调用堆栈我们可以看到main函数是被一个叫做invoke_main的函数调用的 而该函数又是被一个叫做main_result 的函数调用的 这样逐层调用下去。所以main函数也是被编译器中的其他函数调用的。
具体的函数调用多少取决于不同的编译器实现。
所以调用main函数的函数先在栈区开辟一块空间。
2.函数在栈区上的动作
首先回到反汇编代码中
在执行第一条 int a 10语句之前有许许多多的反汇编代码。 先看第一条 ebp是一个寄存器push ebp是将寄存器压栈压入栈空间的顶部。 那么寄存器是什么呢压栈是什么呢
先看下图 在栈空间中一块函数栈空间是由寄存器来维护和使用的。
两个不同的寄存器足以维护它们之间的栈空间并且寄存器和函数地址是毫不相干的寄存器是一个真实存在的东西任何代码任何地方都可以使用它。
在main函数的栈空间中使用的方式是从栈顶往栈底压栈的所以ebp和esp两个寄存器可以形象地称为栈底指针和栈顶指针。
在执行了第一条汇编指令后ebp寄存器中的值就被压到了调用main函数的函数的栈空间顶部。
不是ebp本身被压栈ebp寄存器是个真实存在的东西不可能会被真的压栈压栈压得是ebp存放的值。
我们查看寄存器的值发现ebp的值存放的是一个地址该地址就是上图中的栈底指针所指向的那个地方的地址 如下图 而在压栈结束后esp这个寄存器指向的地址会往上走也就是会往低地址处走因为它是栈顶指针。 如下图 我们可以验证一下
esp的值从0x00D0FADC变成了0x00D0FAD8
证实了上述的动作。
可能你会有个疑问将ebp压栈有什么用呢
将ebp压栈是为了记录ebp和esp最开始维护的栈空间的地址以后ebp被调用到其他地方的时候栈空间的地址仍然被记录很有效的防止栈空间丢失的现象。
在执行完第一条汇编语句后接下来执行第二条汇编语句 该汇编语句的意思是 将esp的值move 到ebp 也就是把esp的值赋给ebp。 也就是说ebp此时指向了esp指向的地址如下图
此时ebp和esp都指向了同一个位置 执行第二个语句后esp和ebp存放的值相同了。
前面我们讲过一块栈空间是由两个寄存器来维护的现在两个寄存器都指向了同一个位置那之前的空间不会丢失了吗
这就回答了第一个汇编语句将ebp压栈的作用此时已经记录了ebp和esp在最开始所维护的空间的地址保证开辟的栈空间不会被忘记。
接下来执行第三条汇编语句 这条语句的意思是将esp存放的值减去0E4h sub就是减法的意思。 0E4h其实是一个16进制数字只是方便编译器识别而这样设计的具体这个值是多少我们可以看一下不过不需要去了解这是为编译器使用的。 esp的值减去一个值结果当然会更小所以esp会往上走因为低地址是在上方所以esp会走到上面的某一个区域。如下图 可以验证一下esp存放的值现在是0x00D0FAD8执行了该汇编指令后esp的值是0x00D0F9F4明显小于之前的所以证实了esp往低地址走了。 接下来执行第四条汇编指令 ebx也是一个寄存器该汇编指令就是把ebx压栈。如下图
那么在执行完压栈操作后esp又会往上走一走 执行来看一下 esp存的地址的的确确又往低地址处走了之前是F4,现在是F0(地址的后两位)也就是走了4个字节。 那么介于ebp和esp的那么大一块的空间是干嘛的呢
下面的汇编指令会给你解答。
接下来继续执行两条压栈的汇编指令 依然是将edi这个寄存器的值压栈
随后执行的汇编指令是 先看第一个lea的意思是 load effective address 加载有效地址 将ebp-24h的值加载到edi中ebp的值是一个地址ebp-24h依然是一个地址。 接下来是mov ecx 9也就是将9赋值给ecx寄存器。 然后是将0CCCCCCCCh 赋给eax这个寄存器。 这三条语句是为下面这条语句做铺垫的真正起作用的也是这条语句 dword的意思是double wordword是字单词的意思dword就是两个字两个单词 一个字是两个字节那两个字就是四个字节。 该语句的意思是 将从edi开始的9个数量的地址全部改成0CCCCCCCCh。
多读几遍你就读懂了接下来验证一下 执行该汇编代码之后情况是这样的 把刚才那块空间全部复制成cccccccc现在可以解释上面的问题了这块空间就是专门为main函数开辟的。 接下来执行的汇编语句黄色箭头易于理解把0AC003H这个值存入到ecx寄存器中。
真正厉害的是接下来红色箭头指向的这一条汇编语句请注意在执行call指令的同时 call指令会自动把下一条汇编代码的地址进行压栈 如下图所示 call指令在执行的同时就会做这件事情把call指令的下一条指令的地址进行压栈
那么这件事情到底有什么作用呢 这里先把问题放这里
接下来我们按F11 似乎此时发现了新大陆
我们可能看不懂那些代码是什么意思没关系这不重要。
重要的是刚刚说的一句话:call指令在执行的时候会把它的下一条汇编指令的地址先进行压栈
回到call指令那个地方 这里的调用指令似乎可以理解成call指令调用内存区的已经建立好的函数。
再次点击F11可以看到确确实实是在调用内存中已经建立好的函数。 在众多汇编代码中真正重要的是这一句代码与刚才的call指令形成一致在ret就是return的意思执行完这一句汇编代码之后一定会出现的事情是返回到call的下一条指令处。 点击F11,可以看到真的回到了call的下一条指令的位置。 这就是代码的严谨的地方不仅能出去调用函数还会记住原来的位置并且回来。
接下来就是把a的值存入内存中
看这两个地方在执行了这条汇编代码之后a被存入内存中了。
接下来就存b然后接下来就是在为Add函数的调用做准备工作了。
首先push ebp对ebp寄存器进行压栈操作为什么压栈前面已经讲过压栈就是为了我们在开辟栈空间的时候为了有效地记录栈空间的栈底地址而进行的操作。
与main函数的开辟如出一辙接下来就是把esp的值给ebp其实就相当于把ebp移动到esp的位置。
注意在移动之前进行的压栈操作就是为了记录栈底空间的地址以后调用函数结束后返回时可以找到该地址。
在main函数调用的时候也进行了压栈的操作。这些过程是相当严谨的。
接下来就是把esp的值-0CCh就是为Add函数开辟了一块空间。 Add函数调用完成后最重要的工作来了如何销毁栈空间
是这样销毁的 pop有删除的意思在这里是把edi弹出栈空间然后再把edi的值赋给edi总的来说就是弹出寄存器。
前面三个均是如此但是最后一个弹出ebp不知你是否还记得我们在创建main函数和Add函数的时候先是对ebp寄存器进行压栈的 所以压栈的作用在这里就凸显出来了
在弹出ebp寄存器的之后会把ebp寄存器里面的值交给ebp。
也就是说弹出ebp之后ebp又记录了当时存在那个地方的值。 所以ebp就回到了之前存的栈底位置的地址。
这样Add函数的销毁就完成了。
因为一块函数栈帧空间是由两个寄存器共同维护的。现在寄存器esp回去了那么这块栈帧空间就会归还给操作系统。
同理对于main函数也是如此。
总结 每一次函数的调用都会在栈区开辟一块空间这块空间是为调用函数准备的而在开辟的过程中存在着许许多多的细节动作来保证整个过程的严谨性。 在创建栈帧的同时也考虑到调用完函数之后销毁的过程整个逻辑是很清晰的。
阅读汇编代码了解汇编指令在函数调用时发挥的作用对我们的帮助是很大的相当于我们在修炼内功。
- 上一篇: 拼多多网站建设做网站一年要多少钱
- 下一篇: 品古典家具网站模板在自己电脑上建设网站
相关文章
-
拼多多网站建设做网站一年要多少钱
拼多多网站建设做网站一年要多少钱
- 技术栈
- 2026年03月21日
-
拼多多网站建设重庆网站建设夹夹虫公司
拼多多网站建设重庆网站建设夹夹虫公司
- 技术栈
- 2026年03月21日
-
拼多多网站建设北京鲜花的网站建设
拼多多网站建设北京鲜花的网站建设
- 技术栈
- 2026年03月21日
-
品古典家具网站模板在自己电脑上建设网站
品古典家具网站模板在自己电脑上建设网站
- 技术栈
- 2026年03月21日
-
品牌百度网站建设网站建设不完整什么意思
品牌百度网站建设网站建设不完整什么意思
- 技术栈
- 2026年03月21日
-
品牌宝正式推出免费个人网站认证深圳展台制作公司
品牌宝正式推出免费个人网站认证深圳展台制作公司
- 技术栈
- 2026年03月21日






