嵌入式:text /data/ BSS 三段通俗详解(单片机 / 裸机 / RTOS 通用)
·
内存模型基础
MCU 程序编译后生成可执行文件(.elf),烧录在Flash(非易失,断电保存);
运行时,变量加载到 RAM(易失,上电使用)。
程序被划分三大核心段:text、data、BSS
1. .text 代码段
✅ 存放:程序代码(编译后的机器码)、常量字符串、const 常量
- 所有函数代码
main()、中断函数、各个子函数 const char *str = "hello";字符串字面量const int a = 100;只读常量
📍 存储位置:Flash
只读,运行不会修改。单片机不能写入 text 段,尝试修改会 HardFault。
示例代码:
const char msg[] = "test"; // 常量放text
void func(void) // 函数代码 text段
{
}
2. .data 数据段(初始化全局变量段)
✅ 存放:全局 / 静态变量,并且手动赋予初始值
int g_val = 10; // 全局初始化变量 → .data
static int s_num = 5; // static初始化变量 → .data
📍运行机制: 上电启动时,启动文件(startup.s)自动把 Flash 上这份初始值拷贝到 RAM,之后程序在 RAM 读写。 📍位置:原始数据存 Flash,运行副本在 RAM。
⚠️ 重点:必须有显式初始值!
3. .bss 段(Block Started by Symbol)未初始化段
✅ 存放:全局、static 静态变量,没有写初始值(默认 = 0)
int g_buffer[1024]; // 无初始化 → BSS
static int stat_var; // 无初始化 → BSS
📍关键特性: 为了节省 Flash 空间:elf 文件里不保存一堆 0,只记录需要占用多大内存。 上电后启动代码直接在 RAM 把整片内存全部清零。
👉巨大优势:大数组定义成全局无初始化,不会占用 Flash! 如果你写 int buf[1024]={0}; 部分编译器依然归类 BSS; 如果你写 int buf[1024]={1}; 则进入.data,初始数据占用 Flash。
快速区分对照表
| 段名 | 存放内容 | 存储特点 |
|---|---|---|
| .text | 函数代码(编译后的机器码)、const 常量、字符串 | Flash,只读 |
| .data | 全局 /static 带初始值变量 | Flash 存初始值,运行拷贝到 RAM |
| .bss | 全局 /static 无初始化变量 | 仅占用 RAM,不占用 Flash |
❗高频嵌入式坑点
-
局部变量不在这三段! 函数内部
int a;局部变量 = 栈 (stack),不属于 text/data/bss,运行时临时分配。 -
不要在函数内定义超大数组
void test(){
int big[2048]; // 栈!极易栈溢出死机
}
解决:放到全局 → 进入 BSS,使用 RAM 堆之外的空间。
- BSS 大小可以在 map 文件查看 编译输出
.map文件,搜索bss、data,用来评估 RAM 占用,排查内存溢出。
上电完整启动流程(Startup.s 做的事)
- 从 Flash 复制
.data段数据到 RAM - 将 RAM 中
.bss整块内存清零 - 调用
main()开始执行
一句极简总结背诵
- text:代码常量放 Flash
- data:有初值全局变量,Flash 存模板,拷贝进 RAM
- bss:无初值全局变量,只占 RAM,上电清零,不占 Flash
更多推荐

所有评论(0)