1. IAR编译信息
c
52'000 bytes of readonly code memory
64 bytes of readwrite code memory
1'240 bytes of readonly data memory
23'151 bytes of readwrite data memory
- readonly code memory:对应KEIL的Code
含义:表示程序中只读代码的大小为52,000字节
存储位置:位于FLASH(程序存储器)中 - readwrite code memory:可读写代码区域(如ITCM/DTCM中的代码)
含义:表示可读写代码的大小为64字节
存储位置:位于RAM(随机存取存储器)中
内容:通常包含使用__ramfunc关键字声明的函数,这些函数在系统启动时从FLASH复制到RAM中执行
特点:这部分代码从FLASH复制到RAM中执行,以提高关键代码的执行速度,但会占用宝贵的RAM资源 - readonly data memory:对应KEIL的RO-data
含义:表示只读数据的大小为1,240字节
存储位置:位于FLASH中
内容:包含所有常量数据,如字符串常量("Hello World")、const关键字定义的变量、宏定义的常量、查找表(LUT)等
特点:这些数据在程序运行时不会改变,因此可以安全地存储在FLASH中,不占用RAM资源 - readwrite data memory:对应KEIL的RW-data + ZI-data
含义:表示可读写数据的大小为23,151字节
存储位置:位于RAM中
内容:包含两大部分:
.data段:已初始化的全局变量和静态变量(初始值存储在FLASH中,运行时复制到RAM)
.bss段:未初始化的全局变量和静态变量(系统启动时自动清零)
特点:这是程序运行时主要的RAM消耗,直接影响系统可用内存
技术细节:在系统初始化过程中,.data段会从FLASH复制到RAM,.bss段会被清零
总ROM(FLASH)使用量: RO Size = readonly code + readonly data = 53,240字节
总RAM使用量 :RW Size = readwrite code + readwrite data = 23,215字节
ROM Size = readonly code + readonly data + readwrite data = 76,391字节
2.KEIL编译信息
c
Program Size: Code=48008 RO-data=5660 RW-data=604 ZI-data=2124
Code:代码段,存放程序指令,位于Flash中
RO-data:只读数据段,存放常量和字符串,位于Flash中
RW-data:已初始化的全局变量,位于RAM中
ZI-data:未初始化/初始化为0的全局变量(.bss段),位于RAM中
Total RO Size (Code + RO Data) 53668 ( 52.41kB)
Total RW Size (RW Data + ZI Data) 2728 ( 2.66kB)
Total ROM Size (Code + RO Data + RW Data) 53780 ( 52.52kB)
1)RO Size 包含了 Code 及 RO-data,表示程序占用 Flash 空间的大小;
2)RW Size 包含了 RW-data 及 ZI-data,表示运行时占用的 RAM 的大小;
3)ROM Size 包含了 Code、RO-data 以及 RW-data,表示烧写程序所占用的 Flash 空间的大小;
(STM32 在上电启动之后默认从 Flash 启动,启动之后会将 RW 段中的 RW-data(初始化的全局变量)搬运到 RAM 中,但不会搬运 RO 段,即 CPU 的执行代码从 Flash 中读取,另外根据编译器给出的 ZI 地址和大小分配出 ZI 段,并将这块 RAM 区域清零。)
3. GCC编译信息
- GCC编译生成的核心段解析
当使用GCC编译C/C++程序时,生成的目标文件(如ELF格式)会包含多个段,其中最重要的有:
-
.text段(代码段)
- 内容 :存放程序的所有可执行代码 ,即编译后的机器指令。此外,一些只读的常量数据 (如字符串字面量)也可能被编译器放入此段或专门的
.rodata段[2][4]。 - 属性:该段在内存中通常是只读(Read-Only)和可执行的。
- 对应关系 :相当于IAR/KEIL中的
Code和RO-data之和[3]。
- 内容 :存放程序的所有可执行代码 ,即编译后的机器指令。此外,一些只读的常量数据 (如字符串字面量)也可能被编译器放入此段或专门的
-
.data段(已初始化数据段)
- 内容 :存放已初始化 的全局变量 和静态变量(包括全局静态变量和函数内的静态局部变量)[2][4][5]。
- 属性 :这些变量在程序加载时就有确定的初始值,这些值会被直接保存在最终的可执行文件中,因此会增加文件大小。
- 对应关系 :相当于IAR/KEIL中的
RW-data[3]。
-
.bss段(未初始化数据段)
- 内容 :为未初始化 的全局变量 和静态变量 预留空间[2][4][5]。更准确地说,
.bss段在文件中并不实际存储这些变量的值,仅记录它们所需空间的大小信息。 - 属性 :程序在加载到内存运行时,操作系统会为这部分数据分配指定大小的内存,并初始化为0。因此,
.bss段不会增加最终可执行文件(如.bin)的大小,但会占用程序运行时的内存(RAM)[3]。 - 对应关系 :相当于IAR/KEIL中的
ZI-data[3]。
- 内容 :为未初始化 的全局变量 和静态变量 预留空间[2][4][5]。更准确地说,
-
.rodata段(只读数据段)
- 内容 :存放只读数据 ,例如用
const关键字声明的全局常量、字符串常量等[2][5]。 - 属性 :该段在内存中是只读的。有时编译器为了优化,可能会将字符串常量合并到
.text段中[5]。
- 内容 :存放只读数据 ,例如用
- 与IAR、KEIL编译信息的对比总结
为了方便你跨平台理解,以下是GCC输出与IAR/KEIL常用术语的对应关系:
| GCC编译输出段 | 含义 | 对应 IAR / KEIL (ARM) 术语 |
|---|---|---|
| .text | 代码 + 常量 | Code + RO-data |
| .data | 已初始化的全局/静态变量 | RW-data |
| .bss | 未初始化的全局/静态变量 | ZI-data |
| 文件总大小 | .text + .data |
ROM/Flash占用 (Code+RO-data+RW-data的初始值) |
| 运行时RAM总需求 | .data + .bss |
RAM占用 (RW-data+ZI-data) |
关键区别提示 :GCC的.text段通常包含了IAR/KEIL中分开报告的Code和RO-data。在估算烧录到Flash的固件大小 时,应计算 .text + .data ,因为.data段中变量的初始值需要被保存在Flash中,并在启动时拷贝到RAM。而.bss段仅影响运行时RAM的分配,不占Flash空间[3]。
- 进阶:自定义段(Section)
GCC提供了强大的 __attribute__((section("段名"))) 扩展语法,允许开发者将变量或函数显式地放置到自定义的段中,这在嵌入式开发中用于内存布局控制、固件升级等场景非常有用[1][5]。