栈和栈帧的基本理解
创作时间:
作者:
@小白创作中心
栈和栈帧的基本理解
引用
CSDN
1.
https://blog.csdn.net/Cpingan1/article/details/141632760
栈(Stack)是一种遵循“后进先出”(LIFO,Last In, First Out)原则的数据结构,在函数调用、表达式求值、内存管理等场景中有着广泛的应用。栈帧(Stack Frame)则是栈中的一个基本单位,用来存储函数调用的上下文信息。本文将详细介绍栈和栈帧的基本概念及其工作原理。
栈(Stack)
栈是一种线性数据结构,只允许在一端进行操作,这一端称为“栈顶”(Top)。主要的操作包括:
- 压栈(Push):将一个元素放入栈顶。
- 弹栈(Pop):从栈顶移除一个元素。
- 查看栈顶元素(Peek):检查栈顶的元素但不移除它。
栈的应用:
- 函数调用管理:当一个函数被调用时,它的执行信息被保存到栈中,这样在函数返回时,可以继续执行之前的代码。
- 递归处理:递归函数每次调用自身时都会在栈上创建一个新的栈帧,从而保存每次调用的状态。
栈帧(Stack Frame)
栈帧是栈中的一个片段,每次函数调用时,都会在栈中创建一个新的栈帧。栈帧用来存储函数执行所需的局部变量、参数、返回地址以及其他状态信息。一个栈帧通常包含以下部分:
- 返回地址:指示函数返回时,程序应该继续执行的位置。
- 函数参数:传递给函数的参数值。
- 局部变量:函数内部定义的变量。
- 保存的寄存器值:在调用函数之前保存的寄存器状态,以便函数返回时恢复。
- 栈指针和基指针:ESP(栈指针,Stack Pointer)和 EBP(基指针,Base Pointer)分别指向栈的顶部和当前栈帧的底部,用来管理栈帧。
栈帧的工作原理
当程序调用一个函数时,系统会执行以下步骤:
- 保存返回地址:调用者的程序计数器(Program Counter,PC)保存到当前栈帧中,以便函数结束后能够返回到调用者的位置。
- 为函数创建新的栈帧:系统会在栈顶为被调用的函数分配一个新的栈帧。
- 保存寄存器状态:调用者的寄存器状态保存到新栈帧中。
- 传递参数和保存局部变量:函数参数传递到新的栈帧,并在其中分配局部变量的空间。
- 执行函数:函数执行其代码,当遇到 return 或到达函数末尾时,函数返回。
- 恢复状态:从栈中弹出当前栈帧,恢复调用者的寄存器状态和返回地址,程序继续执行。
例子说明
void foo(int a, int b) {
int c = a + b;
}
int main() {
foo(5, 10);
return 0;
}
执行 foo(5, 10) 时,栈和栈帧的变化如下:
- 调用 foo:
- 在栈顶创建新的栈帧。
- 保存 main 函数的返回地址。
- 将参数 5 和 10 压入栈帧。
- 将 foo 函数的返回地址压入栈帧。
- 执行 foo:
- 在栈帧中为局部变量 c 分配空间。
- 执行
c = a + b;。 - 完成后,准备返回。
- 返回到 main:
- 弹出 foo 的栈帧。
- 恢复 main 的状态,程序继续执行。
热门推荐
赵东凯:中医抗疫的硬核担当
节奏盒子新角色上线!地狱模组带来更多创意玩法
纪念傅抱石诞生120周年|论傅抱石的绘画艺术成就
赵启斌 | 傅抱石的经历与交游
交通事故法律援助中心:为受害者的权益保驾护航
陕西打造万亿级文旅产业集群:重点项目引领,数字赋能发展
丝路春晚、戏曲春晚…… 2025陕西春晚精彩不容错过
四五个名称、111年历史,沈阳这座广场的前世今生
来南昌登高“看海”尝鲜吃辣!好景拍不完,故事听不完,美食品不完!
半价游玩,淡季错峰出行接下来三个月,很多地方是绝佳出行季
武汉至五台山3天2晚深度游:交通、住宿、餐饮全攻略
武汉到五台山自驾游全攻略:1142公里的信仰之旅
如何腌制鸡翅,提升烤鸡翅的美味与口感秘诀分享
秋冬打卡南阳最美红叶胜地:老界岭、宝天曼、五朵山
秋日打卡南阳:武侯祠与白河湿地公园
从配角到巨星:小黄人的动画进化史
《神偷奶爸4》:小黄人超能变身,搞笑瞬间大集合
永乐宫艺术展火爆广州,解密运城古迹魅力
运城最美自然景观:五老峰旅游全攻略
运城必打卡!盐湖漂浮+鹳雀楼登高,感受自然与人文的双重魅力
7个伤肠胃的坏习惯你有吗?快来看看怎么改善
上吐下泻?小心急性胃肠炎
什么是显卡超频?显卡超频技巧与风险全解析
威远炮台打卡:东莞一日游完全攻略
东莞必打卡历史文化景点推荐
中医如何治疗青光眼
大年初三如何科学“送穷鬼”?
江油:文旅融合让李白文化“活”起来
浅析《古诗十九首》的抒情艺术
苏州白鹭园:独墅湖畔的诗意栖居