函数栈帧图解

本博文环境:Windows 7,64bit,visual studio 2015
我们知道内存空间大致可以用下图表示:
内存空间:
而函数在调用的时候都是在栈空间上开辟一段空间以供函数使用,所以下面来详细谈一谈函数的栈帧结构。
如图示,栈是由高地址向地地址的方向生长的,而且栈有其栈顶和栈底,在x86系统的CPU中,寄存器ebp保存的是栈底地址,称为帧指针,寄存器esp保存的是栈顶地址,称为栈指针。而且还应该明确一点,栈指针和帧指针一次只能存储一个地址,所以,任何时候,这一对指针指向的是同一个函数的栈帧结构。并且ebp一般由系统改变它的值,而esp会随着数据的入栈和出栈而移动,也就是说esp始终指向栈顶。在明白了这些之后,下面我们来看一个具体的例子:
`看这段简单的代码:这里有两个函数:main、fun,其中,main函数调用fun函数来求两个数的和
就像前面说的,函数在执行的时候,是在栈上开辟空间,也就是第一幅图的绿色部分,而且我们知道,程序是逐句执行的,变量是逐个被定义和分配内存空间的,这也是栈指针是移动的的原因,下面我们逐句执行这段代码(VS2015环境下),来看main函数和fun函数的栈帧结构的变化(注:为方便理解,下面的图都是可以按顺序直接拼接的):
这里写图片描述

在这里我们可以看到变量的定义分配内存顺序便是先定义先分配,结合汇编语言我们可以看得更清楚:
这里写图片描述
然后,程序继续执行进入fun函数,这里我们来看汇编语言:
这里写图片描述
这里写图片描述
这里我们主要要明白两点,(1)call指令的两个功能,(2)上图中红色的圈1,圈2的目的。call指令的功能上图描述的很清楚,这里不再赘述,圈1目的是将main函数的pc压入堆栈,因为pc指针里面放的始终是下一条要执行指令的地址,这里把pc压入堆栈进行保护,是因为在执行fun函数的时候pc指针里面放的将会是fun函数需要执行里面的内容,同样的道理,我们知道某一时刻只能有一个栈帧结构,当要去到fun函数的时候,寄存器ebp就要存储fun函数的帧指针,所以main函数的帧指针就要保存起来,查看main函数的汇编语言也可以清楚的看到这一点:
这里写图片描述
然后进入到fun函数:

总结一下就是这样:
画在一起就是这样的
在fun函数执行完成之后,会返回到main函数,这里要做的就是出栈,也就是就在形成fun函数之前压入堆栈进行保护的pc指针,main函数的ebp弹出堆栈,重新形成或者说还原main函数的栈帧结构。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值