C语言1.函数栈帧的创建和销毁

  1. 寄存器(集成到CPU上的): eax、ebx、ecx、edx
    函数栈帧:ebp、esp这两个寄存器中存放的是地址,这两个地址用来维护函数栈帧。
  • 每个函数调用都需要在栈区创建一个空间
  • 每个函数调用都需要栈帧
  • 栈空间使用从高地址到低地址 就像栈,先放底,再放顶
  • 一开始,因为main函数也是被别的函数调用的,叫__tmainCRTStartup,esp和ebp分别指向该栈帧的顶地址和底地址,当调用main函数,用esp上一个内存存ebp,并且ebp指向它,然后esp减0E4h(因为低地址未被用,因为是从高到低使用的, 0E4h显然是main占的空间大小)。总之,调用main的时候,esp和ebp一上(低地址)一下(高地址)地维护main()函数的栈帧。
    此时栈区中栈帧的情况
  • 之后esp上面(在栈顶上放)又有了ebx、esi、edi,即入栈,所以esp也在依次上挪,之后lea=load,之后,edi向下的一片范围为内,所有main内存中的值,全赋值成CCCCC的内容,图中一行是4个字节,之后就能运行你的main中的代码了,比如此时有int a = 10; 就给低内存最下面赋值10,如下图一行,即一个字节。而如果初始化只定义了 int a;直接输出a,就会输出烫烫烫烫烫烫烫烫,其实这是CCCC值对应的内容
    执行赋值语句后给蓝色框内容,从下到上使用栈内存赋值

同时,下图中内存中,最下面地中中给了变量值,赋值成了10。
8*4 = 32位, 32/8 = 4 字节正好是一个int类型,此后再如果有int b = 20;
会给它间隔两个字节的地址赋值,这种方法是vs2013,而其它编译器可能紧挨着放。

请添加图片描述

  • 此时已经知道,程序运行先创建栈帧,再执行内部语句。push:利用eax,ecx(传参)等等寄存器完成操作,这些是不断在esp上面做的,esp也在不断上挪。后面遇到call指令(因为现在开始用函数了),(先记下call地址,44B),call指令把下一条指令的地址压到栈顶,因为后面是要开始进入一个函数,比如要跳到add里面还要出来,需要回来就利用call压到栈顶的地址,之后来到add函数,和之前main中变量运行一样,也是准备地址,放值,esp一直也在挪,在add内部,push,先压ebp的地址,然后move,esp,然后执行做内部语句,次开辟空间为add()函数,里面还是一大坨CCC,然后复制完,传入的参数值,会存在add的低地址部分,执行函数之前,比如遇到add(3, 4),这个时候,存3,4到地址中,等在esp、ebp开辟了add空间后,用到这两个的时候,又返回去找3、4的地址中的值,所以在函数还没调用的时候,实参的值,已经存到了栈里面,所以形参是实参的临时拷贝。
    请添加图片描述
    返回过程:算好的值比如z变量带的值存eax中,因为一会销毁z值,等回到主函数,把寄存器eax值拿出来,然后是一直在pop(),然后顺便销毁空间,回收的时候:move,把ebp赋给esp,b在下面,所以相当于esp向下移动了(低地址到高地址,释放了空间),把之前存到的地址都用起来,因为在调用函数的时候,会存各个函数的ebp值,(因为之前不断在存栈底的值)main函数的,然后esp、ebp(两个寄存器)不断往回挪,然后回到main函数继续往下走,一个指令pop就能让他们回去,当遇到ret指令时,弹出之前call指令存的call的下一条指令地址,ret让回到了主函数call的下一条语句。此时形参用完了,因为add值都返回了,所以把之前参数的值从栈弹出,esp往下挪(即低地址到高地址),esp往下走,相当于释放空间,总之函数返回值在寄存器比如eax中,然后用就拿。

  • 如果再碰到其它函数,再创建栈帧。

  • 栈帧的销毁过程:1.18

局部变量怎么创建的?

在栈帧中分配空间

为什么局部变量不初始化是随机值:

因为之前在开辟空间给了CCCCC ,初始化会覆盖

函数是如何传参的?

当调用函数,还没调用的时候,已经把push压栈进去了参数,真的进入了函数的时候,通过指针偏移量找到在栈内的形参值,所以形参值先存,后才开辟函数空间。

形参和实参区别???

  • 形参在栈内有自己的地址,值是实参的临时拷贝,只是值相同,改变形参不会影响形参

函数调用的结果是怎么传回来的?

call指令下一条指定的地址记住了,走完函数,弹出上一条ebp地址是上一个函数的栈底地址,然后把函数值存在一个寄存器中,销毁之前函数空间,然后利用之前calll指令存到的下一条地址指令地址。

  • 开辟空间大小、不够之类的,问题,可以说:这取决于编译器。编译器很智能
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值