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

文章目录

  1. 局部变量是怎么创建的?
  2. 为什么局部变量是随机值?
  3. 函数是怎么传参的?传参的顺序是怎么样的?
  4. 形参和实参是什么关系?
  5. 函数调用是怎么做的?
  6. 函数调用结束后是怎样返回的?

以上是本次要讲解的知识点,相信看完博客的你一定会有所收获。


文章内容

   准备阶段:

       由于各个编译器对函数的封装各有所不同,所以我们本次采用vs2013编译器进行演示和教学,此编译器对函数的封装显示的比较直观,有助于观察和学习。

       寄存器是CPU内部用来存放数据的一些小型存储区域,用来暂时存放参与运算的数据和运算结果。寄存器有很多,本次我们需要了解两个寄存器,ESP:栈指针寄存(extended stack pointer),EBP:基址指针寄存器(extended base pointer),这两个寄存器中存放的是地址,这两个地址是用来维护函数栈帧的。其中esp俗称栈顶指针,ebp俗称栈底指针。函数的每一次调用都需要在栈区开辟一块空间,且都是由这两个指针来维护的。

      在栈区,数据是从高地址到地址值依次来存储的。

         我们本次采用Add函数来演示,代码如下。

#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 c = 0;

	c = Add(a, b);

	printf("%d\n",c);
	return 0;
}

        按f10开始调试代码。当光标显示到如下位置是时,右击鼠标转到反汇编。

        成功后如下。

     之后打开监视和内存窗口。

     我们可以看到第一条指令便是 push (俗称压栈:给栈顶压如一个元素),esp指向栈顶,通过esp的地址,可以看见ebp的值已经被压栈。

     

       第二条指令是将esp的值给ebp,此时esp,ebp指向同一位置。

        第三条指令是将esp减去 E4 (十六进制) 个byte。

          之后的三条指令我们将 ebx esi edi (这三个东西不做过多讲解)分别压入栈顶。可以观察到的时esp的值减小12。

       此时esp ebp已经开辟好了main函数所用的栈区,如下

       lea(load effecitve address)为加载有效信息。这四步的意义是将从 ebp-0e4h 的位置开始向下减 39h(十六进制)个 int 类型 的双字节 全部赋值为cc

      这三步的意义是将 a、b 、c 的值依次存入栈中 。

       这两步是将 ebp-14 的值赋给 eax,再将eax 压栈 。ebp-14的值是什么呢?从上面可知是 20。这步操作便说明了形参是实参的一份临时拷贝。ebp-8 也是这样的。

       当走到call指令时,我们注意一下call指令下一条指令add的地址,这是我们按f11进入函数,可以发现add的地址竟然被压入栈中。这是为了执行完函数回来的时候能找到下一条指令,从而继续的执行。

  

      进入到函数后,这几步与上述的雷同,不再做过多的赘述。注意push 的ebp 时main函数的ebp 。这是为了Add函数销毁时,ebp能够直接回去。

      这几步操作是将 形参的值拿过来,相加后放入 z中。并且将 z的值给到寄存器eax,即使函数销毁,eax也能将所求的和带回去。

       此时依次从栈顶弹出元素,第四步将,ebp的值给到esp时,所创建Add函数的栈帧即销毁了,此时esp ebp指向同一处,下一步时将栈顶元素弹出,弹出的值便是 我们刚开始压入main函数的ebp的地址,这个ebp的地址被ebp接收,使之返回main函数的栈底。

       当执行ret指令时,实际上是把我们在栈上寸的 call指令的下一条指令 弹出,从而去执行它。

      这一步是将eax的值给到c。

 完。


  • 30
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 20
    评论
评论 20
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值