栈帧总结

栈帧总结

用下面这个简单的C语言程序来讲解函数栈帧

#include<stdio.h>
int Add(int n_a, int n_b)
{
	int z = n_a + n_b;
    return z;
}
int main()
{
	int a = 0;
	int b = 0;
	int c = Add(a, b);
	printf("%d", c);
	return 0;
}

在执行时,main函数被mainCRTStartup函数所调用,而一个函数要执行的话,必须在内存从中开辟一段空间,

因为函数是在栈上开辟空间的,所以ebp表示栈底地址,esp表示栈顶的地址(ebp,esp为寄存器来维护这块空间)


进入main函数后,转到反汇编,下图就是刚刚进入main函数的反汇编,第一句将ebp压入栈顶,第二句表示ebp与esp指向

同一位置,第三句表示,esp向上开辟了一块空间(为main函数开辟的),大小为76字节(下图一格代表4个字节)。第四句,第五句,第六句表示向栈顶压入ebx,esi,edi;




接下来第一句表示将ebp-4Ch的地址放入edi中,将19(13h)放入ecx中,将0CCCCCCCCh放入eax中,最后一句的意思是连续拷贝CCCCCCCC从edi(ebp-4Ch)开始,一次向下移动四个字节,连续19次。如下图所示





接下来的两句试将a,b,ret的值存入ebp-4和ebp-8,ebp-0c中(下图中一格是四个字节)




将ebp-8中的东西(20)存入eax,然后将eax压入栈顶,同样将ebp-4(10)存入ecx中,然后ecx压入栈顶,这个过程就是我们调用函数时形参创立。然后call表示调用Add函数,但是要先记录一个地址,为了调用函数之后可以返回原来的地方。





这时进入Add函数内,第一句将main函数的ebp压入栈,并且让esp与edp指向同一个位置,下面的操作与main函数创建的步骤相同,在这里就不做介绍了,创建好的图如下



将ebp-8中的东西放入eax中,然后第二句是将ebp-0c中的东西与eax中的东西相加,并且存入eax中,然后将eax中的结果存入ebp-4所指的(z )位置中。




将ebp-4所指位置中的30存入eax中,为什么呢?因为当一个函数结束之后,ebp-4现在这个位置会销毁,这样就无法传回我们想要的值了,所以要存入eax中,


接下来前三句的意思是edi,esi,ebx都出栈,第四句的意思是esp指向ebp的位置,第五句是ebp出栈,而ebp所存的内容是main函数的ebp,所以ebp直接指向main函数ebp的位置。而此时esp指向(call指令的下一个地址),最后一句是return的意思使esp向下移动一个位置,因为原来esp指向的内容是(call指令的下一个地址),所以当函数返回时可返回到原来的位置。这个过程也就是函数是如何销毁。


此时将esp+8的意思是esp向下移动八个字节,这是形参也就被销毁了,然后将eax中的值放入ebp-0c(也就是ret中)中。


这整个过成就是函数的栈帧是如何的创建和销毁。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值