Jiangxiaopi 发表于 2025-10-11 21:44

STM32 程序内存分布详解

1. STM32 内存的逻辑分布
从高地址到低地址,程序运行时的内存布局一般可以划分为如下区域:



2. 各存储区详解
(1) 栈区(Stack)
用于存放局部变量、函数形参和返回值。
特点是 先进后出(FILO),函数调用时自动开辟,函数返回后自动释放。
例如:

int Demo(int x) {
int y = 5;   // y 在栈区
return x + y;
}


(2) 堆区(Heap)
程序运行时通过 malloc/new 动态申请的内存块存放于堆区。
堆内存不会自动释放,需手动调用 free/delete 否则可能造成内存泄漏。
例如:

void *p = malloc(20);// p指针本身在栈,分配的20字节在堆
free(p);


(3) 全局/静态区
由两部分组成:

.bss 段:存放未初始化的全局变量、初始化为 0 的全局/静态变量。该区域在程序启动时由系统自动清零,不占用可执行文件大小。
.data 段:存放已初始化的全局变量和静态变量,占用可执行文件空间。
(4) 常量区(.rodata)
存放 const 全局变量、字符串常量等。
该区域内容只读,不允许修改。
(5) 代码区(.text)
存放编译生成的程序指令。
在 STM32 中,通常位于 Flash 存储器中。
3. 示例程序解析
来看一个示例:


staticunsignedint val1 = 1;    // .data 段
unsigned int val2 = 1;         // .data 段
unsigned int val3;               // .bss 段
const unsigned int val4 = 1;   // .常量区 段

unsigned charDemo(unsignedint num) {
char var[] = "123456";       // var 数组在栈,字符串常量在.rodata
unsigned int num1 = 1;       // 栈区
static unsigned int num2 = 0;// .data 段
const unsigned int num3 = 7; // 栈区
void *p = malloc(8);         // 堆区
free (p);
return 1;
}
int main(void) {
unsigned int num = 0;      // 栈区
    num = Demo(num);             // 返回值在栈区
}



通过该例子,可以直观理解不同修饰符与变量的存储区域。

4. 存储介质的差异
(1) RAM
随机存取存储器,断电数据丢失。
STM32 内部的 SRAM 用于存放运行时数据(栈、堆、全局区等)。
(2) ROM
只读存储器,通常在出厂时就写入程序,几乎无法修改。
(3) Flash Memory
现代 MCU 常用的程序存储介质,掉电数据不丢失。
STM32 的程序代码和常量就存放在 Flash 中。
总结:

RAM:栈区、堆区、.data、.bss
Flash:代码区、常量区(rodata)
5. Keil 编译输出分析
在 Keil 的 Build Output 窗口中,我们常见到如下统计信息:



Code    : 程序代码大小
RO-data : 只读数据(常量、字符串)
RW-data : 已初始化的可读写数据(.data)
ZI-data : 未初始化数据(.bss)



由此可以计算出 RAM 和 ROM 的占用情况:

ROM 占用 = Code + RO-data + RW-data
RAM 占用 = RW-data + ZI-data
这对于开发过程中评估内存使用、优化代码结构非常关键。
————————————————
版权声明:本文为CSDN博主「平凡灵感码头」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/Cha3043445754/article/details/152262112

jf101 发表于 2025-10-12 22:14

栈区用于存放局部变量、函数形参和返回值。
页: [1]
查看完整版本: STM32 程序内存分布详解