对比.map
文件判断出函数或数据段有没有被优化掉,特别是配合下面几个要点,判断会非常清晰:
✅ 如何用 .map
看函数/变量是否被优化?
关键看点:
🧱 1. .text
段下的符号大小
.text.main 0x08001234 0x80 src/main.o
-
0x80
= 128 字节 → 函数存在且未优化 -
若变成
0x0
或不在.map
文件中,可能:- 被内联(inline)
- 被优化掉(未引用或有副作用)
- 被链接器丢弃(
--gc-sections
)
📦 2. .data
, .bss
, .rodata
区段大小变化
.data.my_var 0x20000000 0x4 src/utils.o
- 如果 Release 中没了,说明变量被优化掉或合并为常量了
volatile
的变量一般不会被优化
🔗 3. 查段总大小差异
你可以快速 grep 看段体积:
grep -A10 'Linker script and memory map' firmware.map
或直接查各段汇总:
Memory Configuration
Name Origin Length Attributes
FLASH 0x08000000 0x00008000 xr
RAM 0x20000000 0x00002800 xrw
Linker script and memory map
.text 0x08000000 0x00002134
.data 0x20000000 0x00000020
.bss 0x20000020 0x00000100
.text
变小 → 说明函数代码被裁剪/优化.data
变小 → 某些变量可能变成常量或消失.bss
变小 → 未初始化的全局变量消失了
📉 4. 用 diff
看哪段函数缺了
diff firmware_debug.map firmware_release.map | grep .text
快速找到被优化掉的函数名(Release 没出现就是被裁掉或内联了)
🧠 小技巧:常见被优化掉的模式
原因 | 症状 |
---|---|
函数未被调用 | 在 .map 中根本没了 |
被 inline 优化 | .map 无函数符号,但仍在别的 .text 中 |
未使用的变量 | .bss 、.data 减小或丢失 |
未 volatile 的延时循环 | 被编译器优化成空 |
static 函数仅局部使用 | Release 下被合并到主函数中 |
✅ 总结
.map
文件对比函数符号和 size 差异:
- 有没有被编译进来
- 大小是否被优化缩小
- 段地址是否变了
- 是否被裁剪或内联