函数栈帧的理解

前期学习时,我们可能有很多困惑,

比如:局部变量是怎么创建的?函数是怎么传参的?传参的顺序是怎样的?形参和实参是什么关系?函数调用时怎么做的?函数调用时结束后怎么返回的?

这些问题在了解了函数栈帧的创建和销毁就能全部解决了。

在不同的编译器下,函数调用过程中栈帧的创建是略有差异的。

本篇文章参考了这本书。

[Wil06] Rob Williams. Computer Systems Architecture: A Networking Approach. Prentice Hall, 2nd edition.

1. 什么是栈帧(Stack frame)

  • 栈中存放与一个子程序调用有关的所有数据的区域被称为栈帧。
  • 这些数据包括
    • 子程序的参数。
    • 返回地址。
    • 局部变量。

2. 寄存器

首先要了解两个寄存器EBP, ESP, 这两个寄存器中存放的是地址,这两个地址是用来维护函数栈帧的。

  • 每调用一个函数,都要在栈区开辟一个空间。

  • 由于嵌套调用,几个栈
    帧可能同时存在。

  • EBP: 栈低指针。

    • 用于指示当前栈帧的底部。
  • ESP: 栈顶指针。

    • 用来保存堆栈顶部的地址。

3. 栈帧是如何工作的

ESP总是指向堆栈的顶部。

EBP最初包含一个堆栈底层的地址。
栈底的地址。

  • 在调用一个子程序之前和期间,会发生以下情况
    发生以下情况:

    • 参数被压到栈上。

    • 返回地址被压到栈上。

    • 存储在EBP中的地址被压到栈上。

    • 一个新的栈帧被创建。

    • 新的栈帧顶部的地址被保存在EBP中。

    • 局部变量被传到新的栈上。

  • 一旦子程序完成其工作

    • 将所有局部变量从栈中弹出。
    • 从栈顶部弹出先前的EBP的地址,并将其恢复到EBP中。
    • 清理堆栈中的参数。
    • 弹出返回地址并保存在EIP中。
  • 注意:弹出顺序是至关重要的。

1

可以用vs反编译试试看,参考下面文章
[想要自己操作一遍的可以看看这篇博客函数栈帧的创建与销毁(超详解)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小豪GO!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值