对函数栈帧的创建和销毁的初步了解和认识

首先,我们得了解什么是栈帧。

 栈帧也叫过程活动记录,是编译器用来实现过程/函数调用的的一种数据结构。 

C语言中,每个栈帧对应着一个未运行完的函数。栈帧中保存了该函数的返回地址和局部变量。

函数的调用需要在栈区创建一个空间,又叫做函数栈帧的创建,而调用完之后又得销毁这块空间,又叫做函数栈帧的销毁。

而在了解函数栈帧的创建和销毁之前我们需要了解一下相关知识。

寄存器:eax,ebx,ecx,edx,ebp,esp。

eax:累加器寄存器   

ebx:基地址寄存器 

ecx:计数器     

edx:通用寄存器         

ebp:基址指针,或者是栈底指针 

esp:堆栈指针,或者是栈顶指针

而ebp和esp是用于维护函数栈帧的寄存器,正在调用哪个函数,ebp和esp就去维护哪个函数的函数栈帧。

栈区的使用是从高地址到低地址。

push:为栈增加一个元素的操作 

pop:从栈中取出一个元素的操作       

mov:mov是传送数据的指令,mov ax,0123H表明把0123h这个值给ax,h代表0123是十六进制数                                                                                                                                                      dword:双字,也就是四个字节     

ptr:pointer的缩写,也就是指针 

[]:[]里的数据是一个地址数,这个地址指向一个双字型数据                         

sub:减法指令,sub ax,bx     等同于: ax = ax - bx             

add:加法指令,sub ax,bx     等同于: ax = ax + bx    

lea:目标地址传送指令                             

rep:指令的目的是重复其上面的指令,ecx是重复的次数


stos:stos指令的作用是将eax中的值拷贝到ES:EDI指向的地址

call:call也是转移的效果,转到call之后写的标识符     

ret:ret是子程序或函数返回指令

现在让我们从研究vs2013环境下的自定义的加法函数来研究函数栈帧的创建和销毁。

代码如下:

 按F10逐行调试完代码后,我们会发现一下情况

其中__tmainCRTStartup和mainCRTStartup其实是两个函数,他们与main函数的关系其实是

现在让我们用反汇编看一下代码的汇编情况

 第一步的操作则是为栈区增加一个元素也就是压栈操作

而后的move操纵则是将esp的值给ebp,即

之后的sub则是将低地址的值赋给esp

为main函数预存储一块空间

 而之后的三次push操作则是压入ebx,edi,esi三个元素

之后的lea操作把[ebp-0E4h]的地址传入edi

根据上述的前置知识可知,这三步的目的则是将ebp和esp之间的内容全部变为0CCCCCCCCh,即

 

而这三步操作

即 

就是将三个值分别赋到这个地址的内容中去

而以下的操作

则是分别将ebp-8和ebp-14h的值分别先存入eax和ecx,然后进行压栈操作

而后的call指令则是将call指令之后下一条指令的地址放入栈区

而后就是进入add函数的汇编操作,汇编代码如下

而add函数的函数栈帧的创建与main函数的函数创建相同

其中ebp-8也是同main函数一样对add函数临时变量z的创建

这步是将ebp+8的值赋给eax

而这部则是家ebp+0ch的值加到eax中实现加法运算

而后通过这步将两数之和传给ebp-8,也就是z

以此完成加法运算

而这步则是将z的值赋给eax,由于寄存器不随函数栈帧的销毁而销毁,故我们通过寄存器eax将z的值返还给main函数 

 接下来进行pop操作,即出栈操作,可以理解为压栈的反操作,操作后变为

 而接下来的操作则是将ebp和esp转移,用于维护主函数

而这个ebp-main处存放的main函数的地址,此时就可以保证ebp能成功回到main函数的栈底

而ret则是让程序进入下一步操作的地址,即 

 保证调用函数结束能继续下一步的操作

至此,add函数的函数的创建和销毁全部完成

之后main函数的销毁也与此相同,读者可自行尝试之后的相关操作。

这是本人第一次对函数栈帧的创建和销毁进行相关的简单描述,如果有什么不足之处,还请各位老铁赐教

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值