函数栈帧的创建与销毁

在这里插入图片描述


函数栈帧的创建与销毁

  • 前置知识
    要想理解函数栈帧的创建与销毁的实现过程,我们要对一些寄存器和汇编指令有所了解
    如下:
    在这里插入图片描述

那么接下了,我们将通过简单的代码来理解函数栈帧的形成
代码如下:

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;
}

下面我将详细讲解Add函数的栈帧的创建与销毁过程。

  • 变量a,b,c的创建
    在这里插入图片描述
    mov(001718F5)指令是开辟四个字节大小的空间并将0Ah(十六进制)(也就是10)放入ebp-8(地址为0x00F8F74C)处
    mov(001718FC)指令是开辟四个字节大小的空间并将14h(十六进制)(也就是20)放入ebp-14h(地址为0x00F8F740)处
    mov(00171903)指令是开辟四个字节大小的空间并将0(十六进制)(也就是0)放入ebp-20h(地址为0x00F8F734)处
    如下:
    在这里插入图片描述
  • Add函数参数的形成

在这里插入图片描述
mov(0017190A)指令是将ebp-14h(变量b)的值赋给eax,push(0017190D)是将eax的值压入栈顶,esp寄存器大小-4。
mov(0017190E)指令是将ebp-8(变量a)的值赋给ecx,push(00171911)是将ecx的值压入栈顶,esp寄存器大小-4。
如下:
在这里插入图片描述

也就是说,函数参数的实例化是从左向右依次进行的。

  • Add函数的调用
    在这里插入图片描述
    call(00171912)指令是压入返回地址并跳转入目标函数,也就是先转入001710B9,再转入00171790,压入返回地址(00171917)。
    如下:
    在这里插入图片描述

  • Add函数栈帧的创建
    在这里插入图片描述
    push(00171790)指令压入ebp的值,保存ebp的返回地址。
    mov(00171791)指令将esp的值赋给ebp。
    sub(00171793)指令将esp-0CCh。
    push(00171799),push(0017179A),push(0017179B)就是分别压入ebx,esi,edi。
    如下:
    在这里插入图片描述

lea(0017179C)是加载有效地址,将ebp-0Ch的值放入edi中,mov(0017179F)将3放入ecx中,mov(001717A4)将0cccccccch的值放入eax中,rep stos(001717A9)从ebp到edi(ebp-0Ch),中的内容改为eax,循环ecx次。
如下:
在这里插入图片描述

至此,我们就理解了函数栈帧的创建。

  • Add函数内部语句的实现
    在这里插入图片描述
    mov(001717B5)开辟4个字节大小的空间并将0赋给ebp-8(变量z)处。
    add(001717BC)将ebp+8处(形参x)的值赋给eax,add(001717BF)让eax的值加上ebp+0Ch处(形参y)的值。
    mov(001717C2)将eax的值放入ebp-8处(变量z)。
    如下:
    在这里插入图片描述
    假如我们只是定义了变量z,而没有进行初始化,那么其z的值就是cc cc cc cc也就是随机值。也就是未初始化的局部变量的值是随机值。

  • Add函数的返回值
    在这里插入图片描述
    mov(001717C5)将ebp-8处(变量z)的值赋给eax,eax的值并不会随着函数的销毁而改变。

  • Add函数的销毁
    在这里插入图片描述
    pop(001717C8),pop(001717C9),pop(001717CA)连续弹出三次,并将值依次赋给edi,esi,edx。
    如下:
    在这里插入图片描述
    在这里插入图片描述
    mov(001717D8)将ebp的值赋给esp。Add的函数栈帧也就销毁了。
    如下:
    在这里插入图片描述

在这里插入图片描述
pop(001717DA)弹出此时esp的值,并赋给ebp。也就是将ebp在main函数的地址赋给ebp。
如下:

在这里插入图片描述

在这里插入图片描述

ret(001717DB)回复返回地址。返回到add(00171917)处,也就是call(00171712)指令压入的地址。
add(00171917)将esp的值加8。
mov(0017191A)就是将eax的值(0x0000001e)放入ebp-20h处(变量c)。
如下:
在这里插入图片描述

至此Add函数栈帧的创建与销毁就全部完成。


总结

以上就是我对于函数栈帧的创建与销毁的理解。如果有那里不对,请大佬们指出。感谢观看!!!
在这里插入图片描述

  • 12
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 9
    评论
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

水月梦镜花

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值