函数栈帧的创建和销毁讲解

目录

理解代码 


我们平时在使用函数时编译器是怎么工作的?内存是怎么处理的呢?使用的时候从来没有探究过这个底层逻辑,今天我们就从底层来讲解函数栈帧的创建和销毁吧。带领大家一起来探讨原理。首先我们先写一个简单的代码,如右图所示,创建了一个Add函数,然后main函数调用了他。

在了解这个之前,我们先了解一个东西:寄存器,esp和ebp,这两个是维护我们函数的栈帧的,我们后面要频繁地用到的。我们函数调用时都要在栈开辟空间。

esp是栈顶指针,ebp是栈底指针, 这时我们想看看底层是怎么运行的,我们可以按下F10键,然后右击鼠标,点转到反汇编,我们就可以看到了,如下图所示:

理解代码 

首先,我们要调用main函数,我们要用到__tmainCRTStart函数,首先为这个函数开辟一个空间,

下面是高地址,上面是低地址 ,我们看上面的反汇编代码,首先push圧栈,圧栈时esp会自动减小地址

接下来是mov 和sub,将esp放入ebp,esp地址减小,移向低地址,就会发生这样的事情,就是main函数的函数栈帧。

然后又圧栈了三个进去,分别是ebx,esi,edi三个, 

 接下来的三行:

 这三行的总体内容就是从edi位置开始,向下的39h个地址全部初始化成  0CCCCCCCh。

 这样之后才开始执行有效代码,有了函数栈帧之后我们要在函数栈帧之内找到一些空间,将这些创建的变量创建进去,

就是这样创建的。

然后我们就开始调用函数

 第一个mov就是让b参数让放入eax,然后将他圧栈,再然后将a的参数放入ecx,然后圧栈。下一条call指令就是将call指令的下一条指令圧栈,让他执行完之后继续执行call指令的下一条指令。记住,这些都是在为开辟add函数栈帧做准备。

以上就是在开辟add栈帧,其实差不多就是在做之前开辟main函数差不多的事情。 

这就是开辟add函数的情况 ,然后就是执行函数里面的内容了。但是我们传过来的参数怎么执行呢?

整体意思就是我们之前语句进行的传a和传b,通过ebp去找到他们,将他们加起来之后存储到add函数里面去。 所以我们通常说,形参是实参的一份临时拷贝。这句话说的很正确。然后将结果返回,但是出函数之后函数就销毁了,我们将结果放到了寄存器里面,然后再销毁的,这样就不会丢了。

最后就是销毁了,

先把前面圧栈进去的pop掉,然后将中间这一段空间,全部释放掉, 然后esp和ebp会回到维护main函数的栈帧的地方,完美闭环。add函数怎么销毁的,那么main函数就是这么销毁的。

这就是整个函数栈帧创建和销毁的全部过程了。

  • 6
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值