关于栈
一、栈的布局
// C 代码
void myFunc() {
int a; // 步骤2:在栈帧中为 a 预留空间(比如在 SP+4 的位置)
int b; // 步骤2:在栈帧中为 b 预留空间(比如在 SP+8 的位置)
a = 10; // 步骤3:将值 10 MOV 到 [SP+4] 这个内存地址
b = 20; // 步骤3:将值 20 MOV 到 [SP+8] 这个内存地址
}
void func1() { func2(); } // func1 先“入”
void func2() { } // func2 后“入”
// 返回时:func2 先“出”,func1 后“出”
正确的内存地址布局(高→低)
正确的栈增长方向(向下)
正确的变量存储顺序(后定义的地址高)
正确的栈指针位置(指向栈顶)

二、什么是先入后出
===============================================
情况1:您的图片(单个函数内部)
===============================================
高地址 | 调用者(如main函数)的栈帧 |
|-----------------------------| ← 栈帧边界
| 局部变量 b (地址较高) | ← 同属func1
| 局部变量 a (地址较低) | ← 同属func1
|-----------------------------| ← SP (栈顶)
低地址 | |
===============================================
说明:func1函数内,a和b是“室友”关系,同时入住,同时退房。
===============================================
情况2:函数调用(先入后出)
===============================================
1. main函数调用func1:
高地址 | main函数的局部变量 |
|-----------------------------| ← 调用func1前的SP
| func1的返回地址 | ← func1“入栈”
| func1的栈帧(包含a, b) |
|-----------------------------| ← func1执行时的SP
低地址 | |
2. func1调用func2:
高地址 | main函数的局部变量 |
|-----------------------------|
| func1的返回地址 |
| func1的栈帧(包含a, b) |
|-----------------------------| ← 调用func2前的SP
| func2的返回地址 | ← func2“入栈”
| func2的栈帧(包含c, d) |
|-----------------------------| ← func2执行时的SP
低地址 | |
3. 返回顺序(先入后出):
func2 返回 → 释放func2栈帧 ← 后入先出
func1 返回 → 释放func1栈帧 ← 先入后出
main 继续执行
当前图片展示的是:单个函数内部
展示了同一个函数的栈帧内部布局
局部变量 a和 b是同时分配、同时释放的
地址高低(a在低地址,b在高地址)只是它们在“内存公寓”中的房间位置
不同函数之间调用遵循:先入后出(LIFO)
当函数A调用函数B时,B的整个栈帧被“压入”栈顶
当函数B返回时,B的整个栈帧被“弹出”
这正是“先入后出”原则的体现
您的判断完全正确:
图片展示了局部变量在栈帧内的布局(房间内家具摆放)
不同函数调用遵循先入后出(套娃的套入和取出顺序)
这正体现了计算机系统的精巧设计:在宏观的函数调用层面使用栈的LIFO特性管理调用关系,在微观的函数内部则使用连续内存高效存储数据。

浙公网安备 33010602011771号