关于 栈帧变化完整流程图(函数嵌套)

一、什么是栈帧(Stack Frame)

当一个函数被调用时,会在栈上开辟一段空间,叫做 栈帧

每个栈帧保存了:

  • 函数的参数

  • 返回地址(从哪里跳回来)

  • 上一个栈帧的栈底指针(保存调用者的 EBP / FP)

  • 局部变量

  • 保存的一些寄存器(可选)


二、函数嵌套调用例子

以 C 为例:

cpp 复制代码
void C() {
    int c = 3;
}

void B() {
    int b = 2;
    C();
}

void A() {
    int a = 1;
    B();
}

int main() {
    A();
    return 0;
}

三、每次函数调用的栈帧结构(以 x86 为例)

栈增长方向:从高地址向低地址

每次调用栈帧大致如下(从下到上):

bash 复制代码
高地址
│
│  上一帧的 EBP(caller 的栈底)
│  返回地址(RET)
│  参数(如有)
│  局部变量(如 int x)
│
↓
低地址

四、函数嵌套时完整栈帧流程图

以调用链**main → A → B → C** 为例,假设每层函数内部有 1 个**int** 局部变量。

bash 复制代码
初始状态:
栈空

main() 被调用:
+-------------------+ ← ESP,EBP(main 的栈底)
| 返回地址          |
+-------------------+
| 局部变量 return=0 |
+-------------------+

main() → A()
+-------------------+ ← ESP(当前)
| 返回地址(main)    |
+-------------------+
| 上一帧的 EBP      |
+-------------------+
| 局部变量 a=1      |
+-------------------+

A() → B()
+-------------------+
| 返回地址(A)       |
+-------------------+
| 上一帧的 EBP      |
+-------------------+
| 局部变量 b=2      |
+-------------------+

B() → C()
+-------------------+
| 返回地址(B)       |
+-------------------+
| 上一帧的 EBP      |
+-------------------+
| 局部变量 c=3      |
+-------------------+

栈顶 (ESP)

五、函数返回时的栈帧回退过程

函数返回时,会弹出当前栈帧,恢复上一个函数的栈帧(EBP 和 RET 地址)。

bash 复制代码
C() return → ESP 恢复到 B()
B() return → ESP 恢复到 A()
A() return → ESP 恢复到 main()
main() return → 程序结束

六、流程图总结

bash 复制代码
main
│
├── 调用 A()
│   │
│   └── 调用 B()
│       │
│       └── 调用 C()
│
└── 每层函数进栈,栈帧不断叠加
    每层函数返回,栈帧依次弹出

七、可视化理解

bash 复制代码
栈顶
│
│  C 的局部变量
│  返回地址(B)
│
│  B 的局部变量
│  返回地址(A)
│
│  A 的局部变量
│  返回地址(main)
│
│  main 的局部变量
│  返回地址(操作系统)
↓
栈底

八、汇编视角分析

以 x86 为例,函数调用时常见的指令:

Clojure 复制代码
CALL func   ; 压入返回地址 → 跳转
PUSH EBP    ; 保存当前帧
MOV EBP, ESP; 建立新栈帧
SUB ESP, n  ; 为局部变量分配空间
...
MOV ESP, EBP; 恢复 ESP
POP EBP     ; 恢复上层栈帧
RET         ; 弹出返回地址

九、总结

步骤 栈帧变化 关键指令
函数调用 新栈帧入栈 CALLPUSH EBP
建立栈帧 保存旧帧 & 分配空间 MOV EBP, ESPSUB ESP, n
函数返回 弹出栈帧 MOV ESP, EBPPOP EBPRE

补充:

  • 在 x86_64 下,函数参数会用寄存器传递(如 RDI、RSI)

  • 在 ARM64 下,栈帧也有 FP/LR(Frame Pointer / Link Register)结构

  • 调用链跟踪调试可用 gdb、ida、ghidra 中的栈回溯(backtrace)

相关推荐
MaiTube&Maipdf2 小时前
麦瓜PDF 的安全分享流程图:从上传到权限控制
pdf·流程图
程途拾光1582 天前
一键生成幼儿园安全疏散平面图设计美观合规又省心
论文阅读·安全·平面·毕业设计·流程图·课程设计·论文笔记
Yuer20252 天前
EDCA OS 介入虚拟货币案件的标准流程图
流程图·edca os·可控ai
风流 少年2 天前
Markdown之Mermaid流程图
流程图
EmmaXLZHONG3 天前
Reinforce Learning Concept Flow Chart (强化学习概念流程图)
人工智能·深度学习·机器学习·流程图
Nice__J4 天前
Mermaid (代码转流程图)语法详解
网络·流程图
IT_Octopus5 天前
JVM G1 CMS 垃圾收集器工作流程简化流程图
java·jvm·流程图
数说星榆1815 天前
前后端分离开发流程-泳道图设计与应用
论文阅读·职场和发展·毕业设计·流程图·职场发展·论文笔记·毕设
数说星榆1815 天前
项目管理流程图-泳道图模板免费下载
论文阅读·毕业设计·流程图·论文笔记·毕设
程途拾光1585 天前
产品功能验收泳道图-流程图模板下载
论文阅读·职场和发展·毕业设计·流程图·课程设计·论文笔记·毕设