函数调用过程--函数栈帧的简单解析

首先,就这个简单代码观察函数的调用过程

#include <stdio.h>

int Add(int a, int b);

int main()
{
	int a = 10;
	int b = 20;

	printf("%d\n", Add(a, b));
	
	return 0;
}

int Add(int a, int b)
{
	return a + b;
}

很简单的代码,main函数中调用,Add函数。

这张图展示了函数的调用过程(蓝色代表main函数,绿色代表Add函数,图片从上到下由低地址向高地址增加),首先寄存器ebp指向一个内存的地址,之后将edp指向的地址赋值给寄存器esp使其指向同一块地址,之后esp减去一定数值使其指更低的地址,这时ebp与esp之间的一段栈空间便是为main开辟的内存,esp为栈顶,ebp为栈底。之后分别压栈ebx,esi,edi,将main函数所占的内存空间初始化为0xcc cc cc cc,函数中产生一定的偏移量为变量a,b分配内存将值赋给内存空间。创建形参,分别压栈eax,ecx,将a,b值传给形参的内存空间,压栈一块内存其中存储main函数中call指令下一条指令的地址(Add函数调用结束后可以通过这个地址返回原位置,执行main函数中下一条指令)。至此将进入Add函数中的指令。(每压栈一块地址,指向栈顶的esp减去4个字节即向上移动一次。ebx,esi等寄存器的压栈是使寄存器中保存该块内存的地址)

Add函数开始与main函数相同,将edp指向的地址赋值给寄存器esp使其指向同一块地址,之后esp减去一定数值使其指更低的地址,这时ebp与esp之间的一段栈空间便是为Add开辟的内存。之后分别压栈ebx,esi,edi,将Add函数所占的内存空间初始化为0xcc cc cc cc。函数从形参所占空间(eax,ecx所指向的空间)中取出形参a,b的值将其相加结果存于eax所指向的空间中。

Add函数开始返回调用,首先弹栈ebx,esi,edi释放他们所指向的空间。

然后将esp指向ebp所指向的位置,释放Add函数所占空间。

最后弹栈ebp,使其返回main的栈底,弹栈形参,esp,ebp返回继续维护main函数。

压栈eax将函数Add计算的结果返回给main函数,对函数Add的调用结束。

函数调用过程中,为函数开辟的用于本次函数调用中形参变量的保存,现场保护的栈空间,就称为函数栈帧。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值