函数的栈帧的创建和销毁

在这里插入图片描述

文章目录

1. 函数栈帧

我们知道寄存器有eax,ebx,ecx,edx,并且还有ebp,esp。其中ebp,esp这两个寄存器存放的是地址,这两个地址是用来维护函数栈帧的
我们知道,每一个函数调用,都要在栈区创建一个空间。

举个例子:
在这里插入图片描述
我们知道main函数也会开辟自己的栈帧:
在这里插入图片描述
那么main函数被调用了,是被谁调用了呢
在这里插入图片描述
在VS2013中,main函数是被__tmainCRTStartup调用的,而__tmainCRTStartup是被mainCRTStartup调用的。所以,__tmainCRTStartup和mainCRTStartup也会被创建函数栈帧。

下面我们就开始详细讲解上面函数创建的过程
在这里插入图片描述
在main被调用前,有esp和ebp来指向这个函数的栈帧。下面我们来看一下这个例子的反汇编:
在这里插入图片描述
第一步将寄存器ebp给push到main函数的栈帧中:
在这里插入图片描述
那么压栈是从高地址到低地址的,就说明esp的地址会从高变低:
在这里插入图片描述
在这里插入图片描述
第二步的意思是:把esp的值赋值给ebp:
在这里插入图片描述
在这里插入图片描述
第三步给esp减去一个0E4h的值:
在这里插入图片描述
这段空间就是给main函数申请的空间。后面三步是push三个值进去。
在这里插入图片描述
lea的意思是:加载有效地址。这个步骤的意思是:将后面的值赋给epi。后面两个步骤也是赋值。rep stos意思是:从edi里面地址开始的39h个数据全部变成eax里面的数据。
在这里插入图片描述
在这里插入图片描述
然后将10放到ebp-8的位置上,把20放到ebp-14h上,把0放到ebp-20h上。
在这里插入图片描述
下面我们就需要进行函数调用的传参:
在这里插入图片描述
这里首先把20放到eax中,把10放到ecx中。call就是去调用这个函数,并且会把下一个指令的地址压栈,因为当我们调用函数时会再回来往下执行。
在这里插入图片描述
然后我们进入到函数当中:
在这里插入图片描述
第一步是将ebp给push到栈里,然后将esp赋值给ebp,最后将esp减0CCh数据,这三步是给Add函数开辟函数栈帧。然后将三个寄存器压栈,初始化Add函数的栈帧为0CCCCCCCCh。
在这里插入图片描述
然后我们将ebp-8的位置上设置为0,ebp+8上面说过放的是10,ebp+0Ch放的是20。Add的意思是:在eax寄存器中加上20。最后将eax中的值放到ebp-8地方,也就是z处。
在这里插入图片描述
这里是先压栈的b,然后压栈的是a。所以函数在传参是时候是从右向左传的
在这里插入图片描述
把z通过寄存器返回后,pop出edi,esi,ebx。
在这里插入图片描述
然后将ebp赋值给esp:
在这里插入图片描述
这样Add函数栈帧就销毁了。最后再pop掉ebp,就弹出了main函数的ebp了。此时ebp和esp就重新指向main函数的栈帧了。
在这里插入图片描述
Add函数结束后,将esp地址加8。意思是:把两个形参销毁了。
在这里插入图片描述
最后的mov是把寄存器里的值赋给c。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

学代码的咸鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值