这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » STM32 » 在STM32中调用一次函数都用了多少栈空间

共3条 1/1 1 跳转至

在STM32中调用一次函数都用了多少栈空间

院士
2026-08-20 00:58:19     打赏
在STM32中调用一次函数都用了多少栈空间

平时在编写STM32的时候调用了一下函数用了多少栈空间呢?

先说答案:并非一个固定值。

在 Keil 编译器环境中,函数调用时的入栈空间(Stack Usage)并非一个固定值,而是取决于‌目标架构(如 ARM Cortex-M)‌、‌编译器、优化等级‌、‌函数参数数量与类型‌、‌局部变量大小‌以及‌是否发生中断嵌套‌(注:本文暂不讨论中断嵌套)。

在基于ARM Cortex-M内核的项目中(使用 ARM Compiler 5/6 或 GCC),栈空间主要用于保存‌上下文信息‌、‌函数参数‌、‌局部变量‌和‌返回地址‌。

  1. 单次函数调用的基本开销

当一个函数被调用时,入栈操作通常包含以下部分:

  • 返回地址 (LR):4 字节。硬件自动将链接寄存器 (LR) 压入栈中,以便函数执行完后知道返回哪里。

  • 寄存器保护 (Context Saving):如果被调用的函数使用了 R4-R11 等 callee-saved 寄存器,编译器会生成代码将这些寄存器压栈。每个寄存器 4 字节。如果函数内部调用了其他函数,可能还需要保存更多上下文。

  • 参数传递: ARM 调用约定规定,前 4 个参数通过寄存器 (R0-R3) 传递,‌不占用栈空间‌。第 5 个及以后的参数‌会通过栈传递,每个参数占用 4 字节(即使 char 或 short 也会对齐到 4 字节)。重点:前4个参数不占用栈空间。

  • 局部变量‌:函数内部定义的局部变量(非 static)全部存储在栈帧中。注意:大型数组或结构体会显著增加栈消耗。例如 uint8_t buffer[100] 会消耗 100 字节栈空间。

  • 对齐填充 (Alignment)‌:ARM 架构要求栈指针 (SP) 始终保持 8 字节对齐。因此,编译器可能会插入额外的填充字节以满足对齐要求。

  1. 中断服务程序 (ISR) 的特殊开销

当发生中断时,硬件会自动将部分寄存器压入栈(称为“自动压栈”或“Hardware Stacking”):

  • 自动压栈内容‌:xPSR, PC, LR, R12, R3, R2, R1, R0。

  • 空间占用‌:共 8 个寄存器 × 4 字节 = ‌32 字节‌

  • 额外开销‌:如果在中断服务函数中调用了其他 C 函数,或者中断嵌套发生,还需要考虑软件压栈(保存 R4-R11 等)和新的栈帧开销。

理论上我们说完了,在实践过程中,我们又要如何直观的查看呢?Keil已经为我们准备好了静态分析与查看工具:

编译完成后,打开工程目录下的 .map 文件,搜索 Stack Usage 或 Call Graph 章节。Keil 会静态分析出每个函数的最大栈帧大小(Frame Size)和整个程序的最大栈需求(Maximum Stack Usage)。

文章写到这里,有人会问了:您这个都是在Bare-Metal模式下的理论,如果换成RTOS呢?这些理论知识还成立吗?那我们下回再讲。

欢迎大家关注我,我是你们的老朋友jobs。





关键词: 函数          栈空间    

助工
2026-08-21 10:51:18     打赏
2楼

这个知识有点高级了。

在平时的代码编写中,是不会使用函数嵌套的


助工
2026-08-21 15:17:09     打赏
3楼

我都没有注意过这个知识点


共3条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]