☰
嵌入式软件C语言篇--函数栈帧的创建与销毁
2026/10/12 7:41:08 网站建设 项目流程

1.栈帧创建

1.1栈帧

栈帧:每调用一次函数,就在栈区开辟一块独立内存区域

用来存放:返回地址,旧栈基址,局部变量,临时数据

栈整体向下生长(高地址到低地址)

两个关键寄存器:

SP 栈指针:永远指向当前栈顶

FP/BP基址指针:指向当前栈帧的起始位置(栈帧底部,用来索引 本函数局部变量)

1.2栈帧创建(调用函数时)

一共4步,底层靠push压栈+修改SP,FP硬件指令完成

1.压入返回地址

CPU执行函数跳转指令

(ARM:bl),自动把调用完这个函数之后要回去执行的那条指令地址压入栈,函数执行完靠这个地址回到原代码

2.保存旧栈帧基址FP(压栈旧FP)

把调用者函数的FP压栈保存,记录上一层函数栈帧的边界

3.更新FP=SP

让FP寄存器指向当前SP的位置,FP成为新函数栈帧的起点,后面所有局部变量都用FP做偏移来访问

4.SP继续向低地址移动(SP减小)

划出空间,存放本函数的局部变量,临时变量

一句话理解:移动SP开辟空间,FP标记栈帧起点,这片区域就是新函数的栈帧

2.函数栈帧的销毁

销毁不会清空内存数据,只修改寄存器SP,FP配合pop出栈

1.恢复SP到FP的值

SP直接赋值为当前FP,一次性回收本函数局部变量占用的全部空间,局部变量对应的内存不再属于当前栈帧

2.出栈,恢复上一层函数旧FP

从栈里取出之前保存的旧FP,还给FP寄存器,FP回到调用者函数栈帧的边界

3.出栈拿到返回地址,跳转回去

从栈顶取出预先压入的返回地址,CPU跳回调用函数的地方继续运行

❗❗栈帧销毁不会把内存里的数据清零,只是SP,FP不再指向这片内存,原来局部变量的值还留在内存,新函数调用开辟栈帧时,会直接覆盖这块内存

这就是为什莫:返回局部变量指针,拿到脏数据,产生野指针!

三.完整流程串联

mian 函数正在运行(main的栈帧)

调用func()

【栈帧创建】

1.压栈:保存返回地址(回到mian的地址)

2.压栈:保存main的FP

3.FP=SP,标记func的栈帧起点

4.SP-=N,开辟空间放func局部变量

执行func里面的代码

【栈帧销毁,return】

1.SP=FP,释放局部变量占用空间

2.POP,恢复main函数旧FP

3.POP取出返回地址,CPU跳回mian

回到main 继续执行,func栈帧作废

4.高频易错坑

1.❌栈帧销毁,系统把局部变量内存清零

✔只动SP/FP,数据残留

2.❌创建栈帧需要操作系统临时申请新内存

✔线程启动时栈整块内存就分配好了,栈帧只是在这片内存里移动SP划分空间

3..❌FP(基址指针)指向栈顶

✔FP标记当前栈帧的起始边界(栈底),用来访问局部变量

4..栈帧是每一个函数调用单独一份,递归调用就会连续创建多层栈帧,递归太深SP不断下移,栈空间耗尽,栈溢出

已完结

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询