当前位置:网站首页>c语言:通过一个例子来认识函数栈帧的创建和销毁讲解
c语言:通过一个例子来认识函数栈帧的创建和销毁讲解
2022-07-28 05:18:00 【某某小卢】
我们利用一个简单的c语言函数来认识函数栈帧的创建和销毁讲解。
- 函数栈帧的创建和销毁讲解
例:

a.寄存器分为eax,ebx,ecx,edx,以及ebp,和esp
其中ebp和esp这两个寄存器中存放的是地址
这两个地址是用来维护函数栈帧的。
b.每个函数调用,都会在栈区创建一个空间
有两个寄存器esp和ebp记住了两个地方的地址,在调用哪一个函数,ebp和esp就是在维护哪一个函数的函数的函数栈帧(无论是库函数还是自己创造的函数)

main函数也是被其他函数(__tmainCRtartup)调用的,然后__tmainCRtartup这个函数也是被mainCRtartup这个函数调用的。

c.调用总过程大概是这样的

调用总过程的具体是这样

先进行push(压栈)放入一个ebp在上面,然后esp是栈顶指针,esp向上走一步,然后因为上面是低地址,所以esp减小了。
就像下面这样

然后是mov操作,将esp的地址给ebp。
然后进行了sub操作,就是将前面的减去后面的,如下图:就是esp-0E4h,这样esp就上移到了某一个特殊的地方了吧
![]()
这样esp和ebp形成了新的范围,创建出来main函数的空间啦。

然后再进行三次push(压栈),分别压进去ebx,esi,edi这三个值,然后esp也先上移动了

然后就进行了lea操作了,就是将(ebp-0E4h)这个地址赋给edi,因为三次push之前的esp的地址就是(ebp-0E4h),
所以其实就是将三次push前的esp的地址赋给了edi了。

然后下面不是有两个mov操作嘛,第一个mov是将39h这么多个数据赋给了eca,然后第二个mov操作是将0ccccccch赋给了eax。然后rep stos这个创造是将edi以下ecx(39h)这么多个数据全都附上eax(0ccccccch)这个值。

这样就将main这个函数的空间创建好了。
再下来就是进入main括号里面的内容了,开始定义东西了。

将0A(16进制就是10)赋到ebp-8的地址
再将14h赋到ebp-14h这个地址,再将0赋给ebp-20h这个地址。

然后再下来,mov将ebp-14h的值赋给了eax,再将eax进行压栈,然后同样的道理,将ecx(ebp-)8压栈。

接下来就是执行call指令了,将call的下一条指令的目的地的地址进行压栈,并且在call的下一条指令做一个标志,后面刚好可以回来call指令的下一条指令。

然后就到了了add函数啦
然后又进行了push等系列的操作,开辟了add函数的空间。
而之前的ebp和esp也上移了
而其中x和与y是由a和b传值过去的(add(a,b)这个是由右向左传的,也就是b先传),第一个mov将ebp+8赋到了eax,然后进行add操作将ebp+0ch(这个是ebp+12)与eax相加
,然后将相加的结果赋给eax,然后再进行一个mov操作,将eax的值赋给ebp-8。
注:像这里形参不是在这个创建的,而是找到了传参的时候那个值的空间。这里的形参只是实参的一次拷贝,所以形参不会改变实参的值。
然后现在把z算出来了。

然后又进行进行了一次mov操作,将ebp-8赋给了eax。
注:注意到本例子是在add函数内部创建了变量z,那为啥这里临时变量z可以将值传过去main函数呢?(临时变量在函数使用完成后就会销毁。)
因为它现将ebp-8赋给eax,而eax是一个寄存器,寄存器是不会因为函数结束了,就迅速销毁的,所以可以将值传过去。
然后就要进行pop操作了,pop操作就是将edi等销毁(弹出)的,而esp向下移动了

然后mov,将ebp的地址赋给了esp,这样就将add的空间销毁了。
然后进行pop,将ebp这个销毁了,同时esp下移了,ebp也回到了main里面了,找到了main的ebp和esp。

进行ret操作后,就又跳了call指令的下一条指令的位置。
然后将进行add操作和mov操作,将esp+8来导致esp下移,这个add操作会导致esp+8和esp+12这两个形参销毁。

注:所以说形参什么时候销毁呢?
形参在这个add操作后销毁了,没了。
然后进行mov操作,将eax赋给ebp-20h,这里就实现了返回值带回来了。
同理,main函数的return也是这样返回了,就不多做解释。
边栏推荐
- CentOS7安装MySQL5.7
- 多模块打包:程序包:xxx不存在
- Thesis writing function words
- openjudge:过滤多余的空格
- BigDecimal 进行四舍五入 四舍六入和保留两位小数
- PyTorch 使用 MaxPool 实现图像的膨胀和腐蚀
- 排序之插入排序
- [idea plug-in artifact] teaches you how to set all attributes in an entity class with one click of idea
- (黑马)MYSQL初级-高级笔记(博主懒狗)
- Openjudge: maximum span of string
猜你喜欢
随机推荐
mysql 为查询结果增加序号
Openjudge: perpetual calendar
Advanced multithreading: the role and implementation principle of volatile
repackag failed: Unable to find main class
ByteBuffer. Position throws exception illegalargumentexception
mysql中使用list作为参数进行查询
restFul接口使用个人总结
pytorch 计算模型的GFlops和total params的方法
TopK问题
Openjudge: maximum span of string
List < long >, list < integer > convert each other
PyTorch 使用 MaxPool 实现图像的膨胀和腐蚀
Redis 之布隆过滤器
The Monte Carlo method solves the PI and draws points with turtle, and completes the progress bar problem
How Visio can quickly generate the same pattern and image matrix
(黑马)MYSQL初级-高级笔记(博主懒狗)
The essence of dynamic convolution
URL form
JUC笔记
数据库面试









