您现在的位置是:群英 > 开发技术 > 编程语言
C语言中函数栈帧如何创建和销毁?
Admin发表于 2021-12-27 19:00:59684 次浏览

    这篇文章给大家分享的是C语言中函数栈帧的相关内容,下文介绍了函数栈帧的创建和销毁的方法,对大家学习和理解函数栈帧有一定帮助,有需要的朋友可以了解看看,接下来一起跟随小编学习一下吧。

        一、函数栈帧的创建

        1.寄存器

        一般来说,计算机中的寄存器有六种

        分别是:eax, ebx, ecx,edx,ebp,esp

        而ebp,esp这两个寄存器中存放的是地址,与此同时,这两个地址是来维护函数栈帧的。

        2.函数栈帧

        每一个函数的调用,都需要在栈区为其开辟一个空间,这块为其开辟的空间就是函数栈帧。

        ebp:栈底指针

        esp:栈顶指针

    对于栈这种数据结构一共有两种栈操作
    1.pop 出栈
    2. push 压栈


        如上图所示,当main函数创建是便是会为其开辟函数栈帧,而其函数栈帧的地址范围则由栈顶指针:esp,栈底指针:ebp来标识。同时,ebp和esp所指示的位置会随着函数栈帧的创建和销毁而不断的发生改变。

    需要明白的是,在VS编译器中,main函数也是由其他函数调用的

        在main函数的栈帧创建完成之后呢,就会用一个特定值将函数栈帧内的空间覆盖,这个特定值就是0xcccccccc(十六进制表示)。

    相信大家在跑代码的时候都遇到过打印好多“烫烫烫烫烫烫烫烫烫”的情况,这其实是访问的内存越界了,而错误访问的内存中存放的正好就是上面那个特定值。

        函数栈帧创建好以后,在函数中创建的变量便可以存放在函数栈帧中了。

        3.函数中调用函数

        1.如果调用的函数有参数的话,先要将参数压栈,这里的参数是实参的一份临时拷贝。

        2.同时将调用函数结束之后的下一步操作的地址压栈。(根据这个地址,我们们就可以在内存中找到相应的操作)

        3.将调用之前的函数栈帧对应的ebp地址压栈,这是为了方便我们在函数调用结束之后找到对应的函数栈帧的地址。

        4.再次执行函数栈帧的创建操作。

    函数形参并不是在函数栈帧中创建的,而是在函数栈帧创建之前就已经在栈中创建了(对应第一步),当要使用时,就可以从相应位置找到。

        5.函数的返回值会存在一个寄存器中(当函数栈帧释放后,返回值不会随之消失)。

        二、函数栈帧的销毁

        1.将一些函数调用中使用的寄存器弹出栈。

        2.修改相应的ebp,esp的值,使其还原为函数调用前所指向的位置。具体为:出栈操作后,esp将指向当前ebp所指向的位置,之后弹出栈中所存储的ebp的地址,让ebp也指向正确的位置。这也是为何要在函数调用之前存储当前ebp的地址。同时,因为出栈操作,esp的位置也相应的发生改变。

        3.此时的栈顶元素对应的是函数调用之后的下一条指令的地址(在调用函数之前我们就将其压栈了),根据地址我们就可以执行相应的操作。之后出栈,变更esp地址。

        4.执行完第三步操作后,esp所指向的地址发生改变。同时释放形参的空间,函数也相应的结束了。

        总结

        这是函数栈帧的创建和销毁,这里只是简单的介绍,如果要理解的更透彻的话,可以查看汇编的代码

        关于C语言中函数栈帧的相关内容就介绍到这,这里只是简单的介绍,如果要理解的更透彻的话,可以查看汇编的代码。如果还想要了解更多C语言的内容,大家可以关注其它的相关文章。

    文本转载自脚本之家

    免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。

    相关信息推荐
    2022-07-18 17:29:20 
    摘要:求和方法:1、用foreach遍历二维数组的外层数组元素,语法“foreach($arr as $v){//循环体}”;2、在循环体,用is_array()判断外层元素是否为数组类型,若是则利用array_sum()求出内层数组的元素和并与外层数组元素相加即可,语法“if(is_array($v)){$sum+=array_sum($v);}else{$sum+=$v;}”。
    2022-05-06 18:09:21 
    摘要:小程序中怎么使用text文本组件?下面本篇文章给大家介绍一下小程序中text文本组件的使用方法,希望对大家有所帮助!
    2022-09-20 17:56:33 
    摘要:这篇文章主要为大家介绍了Ezpop pop序列化链反序列化知识,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步早日升职加薪
    云活动
    推荐内容
    热门关键词
    热门信息
    群英网络助力开启安全的云计算之旅
    立即注册,领取新人大礼包
    • 联系我们
    • 24小时售后:4006784567
    • 24小时TEL :0668-2555666
    • 售前咨询TEL:400-678-4567

    • 官方微信

      官方微信
    Copyright  ©  QY  Network  Company  Ltd. All  Rights  Reserved. 2003-2019  群英网络  版权所有   茂名市群英网络有限公司
    增值电信经营许可证 : B1.B2-20140078   粤ICP备09006778号
    免费拨打  400-678-4567
    免费拨打  400-678-4567 免费拨打 400-678-4567 或 0668-2555555
    微信公众号
    返回顶部
    返回顶部 返回顶部