c语言入门-函数栈帧

目录

函数栈帧概念

 分析函数栈帧


函数栈帧概念

函数栈帧:函数在每一次调用时,都会在栈空间开辟一段空间以供函数使用,这个空间被称为栈帧,栈帧中保持着函数所需要的各种信息。

寄存器:是cpu(中央处理器简称cpu,是计算机的运算核心和控制核心,是信息处理,程序运行的最终执行单元)内组成部分,用于存储的部件,可以用来暂时存指令,数据和地址。

win32系统提供了两个寄存器来维护函数栈帧。

⭕ESP:栈指针寄存器,它内部存放着一个指针,永远指向栈最上面一个栈帧的栈顶,即栈顶寄存器。

⭕EBP:基地指针寄存器,即栈底寄存器。

我们知道栈是由高地址向低地址生长的,即先使用高地址,后使用低地址。

 分析函数栈帧

#include<stdio.h>
int Add(int x, int y)
 {
	int z = x + y;
		return z;
}
int main(){
	int a = 10;
	int b = 20;
	int ret = Add(a, b);
	printf("%d", ret);
	return 0;
}

通过这个代码我们来分析函数栈帧。在调试程序时查看调用堆栈:可以看出main函数其实是在mainCRTStartup函数中调用的。(在VS编译器中可以看出其实main函数是在_tmainCRTStartup函数中调用的,而_tmainCRTStartup函数是在mainCRTStartup中调用的。) 所以说main函数执行之前,先要为_tmainCRTStartup函数安排栈帧,后为mainCRTStartup函数分配栈帧。

 调试窗口打开反汇编。

●main()函数被调用之前:_tmainCRTStartup函数栈帧

●main()函数被调用之时:

//008B1930  push        ebp   将edp存入栈中,esp自动更新到栈顶,即edp空间顶部
//008B1931  mov         ebp,esp   将esp的值赋给edp

push:压栈,在栈中存入数字 mov:将后面的值赋给前面  sub:减法操作 lea:load effecyive address,加载有效地址  pop:出栈

  //008B1933  sub         esp,0E4h   esp减去16进制的数字,esp更新

 //008B1939  push        ebx ebx压栈
 //008B193A  push        esi  esi压栈
 //008B193B  push        edi  edi压栈

 //008B193C  lea         edi,[ebp-24h]      给edi加载有效地址
//008B193F  mov         ecx,9           //ecx空间大小
//008B1944  mov         eax,0CCCCCCCCh  //eax的内容更改
//008B1949  rep stos    dword ptr es:[edi] 

  //00141950  call        00141316  
//    int a = 10;
//00141955  mov         dword ptr [ebp-8],0Ah  ,
在ebp-8 的位置上存入a
 //   int b = 20;
//0014195C  mov         dword ptr [ebp-14h],14h
在ebp-14 的位置上存入b

 //00141963  mov         eax,dword ptr [ebp-14h]  
//00141966  push        eax 
压栈压入b
//00141967  mov         ecx,dword ptr [ebp-8]  
//0014196A  push        ecx 
 压栈压入a

 调用Add函数

0014196B  call        001413B6  
00141970  add         esp,8  

调用call指令时,里面保存了call指令下一条指令(add)的地址。

到达call指令,按F11进入add函数的反汇编代码

//00141890  push        ebp
//00141891  mov         ebp, esp
//00141893  sub         esp, 0CCh
//00141899  push        ebx
//0014189A  push        esi
//0014189B  push        edi
//0014189C  lea         edi, [ebp - 0Ch]
//0014189F  mov         ecx, 3
//001418A4  mov         eax, 0CCCCCCCCh
//001418A9  rep stos    dword ptr es : [edi]

为add函数开辟空间并初始化为0cccccccc。

 //int z = x + y;
//001418B5  mov         eax, dword ptr[ebp + 8]
//001418B8  add         eax, dword ptr[ebp + 0Ch]
//001418BB  mov         dword ptr[ebp - 8], eax
//return z;
//001418BE  mov         eax, dword ptr[ebp - 8]

  把结果放到寄存器中,不会因为函数结束了导致值被销毁。

add函数销毁之后,main函数打印结果

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值