13 固件内存布局与段
一句话记忆:Flash 主要放代码、只读数据;RAM 主要放可写数据、堆和栈。 以下为常见 MCU 布局,不是所有芯片的固定规则。
1. 一张图记住六个区域

| 区域 | 中文记忆 | 典型位置 |
|---|---|---|
.text | 代码区:存机器指令 | Flash |
.rodata | 只读区:Read-Only Data | Flash |
.data | 初值区:可写,有非零初始数据 | RAM |
.bss | 清零区:可写,初始为零 | RAM |
| Heap(堆) | malloc() 等动态分配 | RAM |
| Stack(栈) | 函数调用、部分局部变量、任务栈 | RAM |
注意: 这是 4 个常见段 + 堆 + 栈 的记忆模型,不表示芯片只有六个物理区域,也不表示所有固件都一定使用堆。
2. 最容易混淆:.data 与 .bss

.data:例如int a = 10;,通常要在 Flash 保存初始数据,开机时复制到 RAM。.bss:例如int b = 0;,通常在开机时清零;无须在固件映像中保存大量零,但仍占 RAM。
int count = 10; // 通常 .data
int flags = 0; // 通常 .bss
const int version = 2; // 通常 .rodata
int add(int a, int b) // 机器指令通常位于 .text
{
return a + b;
}
3. 嵌入式开发记住的三个关键点
| 容易误解 | 实际情况 |
|---|---|
.bss 不保存一堆零,所以不占内存 | 错:它通常仍占运行时 RAM |
const 一定放 Flash | 错:只读语义不等于存储位置,取决于编译与链接 |
.text 就是字符串文本 | 错:通常是机器指令;字符串常量常在 .rodata |
例如,被保留的全局 uint8_t buffer[1024] = {0}; 通常放在 .bss,会占用 1024 字节 RAM。
最终以 MAP 文件和链接脚本为准。
.data初始映像也可能占 Flash;RTOS 任务栈、自定义段、RAM 执行函数等会让实际布局比这张图更复杂。