前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C/CPP函数括号{} | 栈帧 | 堆栈 | 栈变量

C/CPP函数括号{} | 栈帧 | 堆栈 | 栈变量

作者头像
CtrlX
发布2022-10-04 17:12:05
6760
发布2022-10-04 17:12:05
举报
文章被收录于专栏:C++核心编程C++核心编程

实例

image
image

由上可见{}在汇编指令中发挥的作用可不少,函数之间的随意调用和顺利收场都离不开它们。

image
image
image
image

红色水位线是:寄存器esp的值,用来标识:栈顶的内存地址

蓝色基准线是:寄存器ebp的值,用来标识:main函数的:栈帧基地址

从func()函数开始:

push将epb寄存器的值压入栈顶,栈顶水位线升高,至此main函数的栈帧保护工作完成,然后通过mov指令更新栈帧基准线,与栈顶水位线齐平。

image
image
image
image

然后通过sub指令把红色水位线提升8个字节,用来给两个临时变量分配:堆栈内存

image
image

之后就是对临时变量ab赋值,可见ab相对于蓝色基准线的偏移分别是4和8,刚好用完函数的栈帧。

image
image

函数执行完毕,该恢复main函数的栈帧了

mov指令将红色水位线降低到蓝色基准线的位置,然后通过pop指令把原先压入栈顶的ebp值返还给寄存器ebp,这样蓝色基准线就恢复到了最开始的位置,随着栈顶的下降,红色水位线也随之下降。至此红蓝两条线都恢复到了最开始的位置,main函数在栈帧恢复完成。

不准确的说,函数的栈帧就是红蓝两条线之间的内存块,它用来存放函数的临时变量,参数和返回地址。所谓的保护栈帧恢复栈帧,不过是在保存和恢复寄存器esp和ebp的值。

至于return address是用来做:函数返回的。(详见函数调用文章)

总结

1

cpu提供两个寄存器esp和ebp,用来标识当前函数对堆栈的使用情况。

image
image

随着函数的调用,函数的栈帧会逐层堆叠,但互不重合。

image
image

随着函数的逐层返回函数的栈帧会被就地放弃,但不会清理内存。

image
image

2

正括号{用来保护上层主调函数(main)的栈帧,并设置被调函数(func)的栈帧,反括号}用来放弃被调函数的栈帧,同时恢复主调函数的栈帧,这样被调函数执行完后,主调函数就能正常执行。

3

ebp寄存器作为当前函数的:栈帧基地址,配合一定的偏移就可以读写函数体里的:临时变量。

如果一个变量是通过ebp寄存器,间接访问的,那么它往往是临时变量,也叫栈变量。

4

不同编译器对栈帧的实现方法略有不同,但思路一致。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-10-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 实例
  • 总结
    • 1
      • 2
        • 3
          • 4
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档