谈谈函数的调用过程,栈帧的创建和销毁。

一、 什么是栈帧?

  首先引用百度百科的经典解释:“栈帧也叫过程活动记录,是编译器用来实现过程/函数调用的一种数据结构。”。
  栈帧表示程序的函数调用记录,而栈帧又是记录在栈上面,很明显栈上保持了N个栈帧的实体,那就可以说栈帧将栈分割成了N个记录块,但是这些记录块大小不是固定的,因为栈帧不仅保存诸如:函数入参、出参、返回地址和上一个栈帧的栈底指针等信息,还保存了函数内部的自动变量(甚至可以是动态分配内存,alloca函数就可以实现,但在某些系统中不行),因此,不是所有的栈帧的大小都相同。
  那么函数调用过程中,栈帧是怎样创建和销毁的?下面我们来具体了解了解。
#include<stdio.h>
int add(int x,int y)
{
 int z = 0;
 z = x + y;
 return z;
}
int main()
{
  int a = 10;
  int b = 20;
  int ret = add(a,b);
  printf("ret=%d\n",ret);
  return 0;
}

每一次函数调用都是一个过程这个过程我们称为函数的调用过程,这个过程要为函数开辟栈空间,用于本次函数的调用中临时变量的保存,现场保护。这块栈空间我们称为函数栈帧。

栈帧的维护必须先了解两个寄存器。
寄存器ebp称为“基址指针”,在未受改变之前始终指向栈底,用途是:在堆栈中寻址。
寄存器esp称为“栈指针”,会随着数据的入栈出栈移动,也就是说始终指向栈 顶。

当我们要详细研究函数调用过程,必须得对照的汇编代码。
从main函数的地方开始,要展开main函数的调用就得为main函数创建栈帧。
这里写图片描述
1.我们知道ebp和esp是用来维护函数的栈底指针和栈顶指针,push ebp,将__mainCRTStarup函数的ebp压栈,在它的栈顶开辟一块空间放入它的ebp;
2.将esp给ebp,此时ebp与esp同时指向刚刚开辟空间的顶端;(创建栈帧的过程)
3.esp减去0e4h大小的值,我们知道栈空间中元素存放顺序是由高地址到低地址,则该步骤在ebp的上面开辟了0e4h大小的内存空间;
4.ebx,esi,edi三块空间进行压栈,随着压栈的进行,esp指向edi的顶端;
5.将ebp-0e4h这个地址放到edi中(方便之后ret步骤的使用);
这里写图片描述
6.将10赋给a,20赋给b。
7.b的值,将它mov给eax寄存器并且压栈;同理a的值,将它mov给ecx寄存器并且压栈。
8.接着调用call指令。注意,在调用call指令的时候,在ecx的上方又开辟了一块空间用于存放call指令下一条指令的地址(这个地址的作用是在call指令调用add函数结束的的时候jump指令能够找到call指令下一条指令的地址,从而回到main函数中)
9.由call指令进入add函数之后,第一步就是进行压栈,将main函数的ebp压栈保存在上面开辟的空间中。
创建z空间,放进去内容为0;
‘x’指向x=10的存储空间,将10放到寄存器eax中;同理“y”指向y=10的存储空间,将20add到eax中,此时eax中的内容为30;
将eax给“z”意思为将z的内容由零改为30;
将z的值放回到eax中,这一步骤代表着返回机制,z的值将来由寄存器eax带回到main函数中。
之后执行pop出栈操作,edi,esi,ebx三块空间出栈后,esp向下移动,这三块空间已经不属于add函数,但是依然存在。
将ebp给esp,此时esp回退到当前ebp的位置。
之后对下一块空间执行出栈操作, 由于保存的是main函数的ebp,栈底指针ebp得以回到main函数ebp的位置。
这里写图片描述
这里写图片描述
call指令的下一条指令就是“add esp,8”
movdword ptr [ret],eax
//将eax的值传给了ret
至此整个add函数的调用已经结束。再往下直到esp和ebp回到__mainCRTStarup函数相应的位置.

* 女帝镇楼*
这里写图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值