ld的-print-memory-usage输出异常及忽略栈堆计算方法求助
问题:如何在GCC 12.2链接器内存使用率计算中忽略.stack和.heap分区?
我使用xPack RISC-V GCC-12.2工具链获取CH32V307微控制器的RAM、FLASH内存使用率百分比,链接器脚本中栈的两种定义写法导致内存使用率输出差异极大:
第一种写法:
.stack ORIGIN(RAM) + LENGTH(RAM) - __stack_size : { . = ALIGN(4); PROVIDE(_susrstack = . ); . = . + __stack_size; PROVIDE( _eusrstack = .); } >RAM
此时RAM使用率显示为100%;
第二种写法:
.stack : { . = ALIGN(4); PROVIDE(_susrstack = . ); . = . + __stack_size; PROVIDE( _eusrstack = .); } >RAM
RAM使用率仅显示3%,但两种写法仅调整了栈在RAM分区内的位置,实际内存占用逻辑一致。
使用旧版GCC 8.3时,两种写法的ld -print-memory-usage输出均正常,GCC 12.2的链接器在该参数的输出行为上存在明显差异。现需了解是否有办法让内存使用率计算时忽略.stack和.heap分区?
解决方法
给栈/堆段添加NOLOAD标记
在链接器脚本中,为.stack和.heap段添加NOLOAD属性,链接器计算内存使用率时会跳过这些未实际加载的区域。修改后的.stack段示例:.stack (NOLOAD) : { . = ALIGN(4); PROVIDE(_susrstack = . ); . = . + __stack_size; PROVIDE( _eusrstack = .); } >RAM对.heap段执行同样的修改即可。
自定义脚本计算内存使用率
不依赖ld -print-memory-usage的默认输出,用size工具获取实际占用的RAM段大小,再通过脚本手动计算:- 执行
size -A your_project.elf获取所有RAM段(排除.stack和.heap)的大小总和 - 用RAM总容量除以该总和,得到真实的内存使用率
这种方法完全规避链接器版本差异,结果可控。
- 执行
临时回退链接器行为(不推荐长期使用)
GCC 12.2配套的binutils版本(2.39+)调整了-print-memory-usage的计算逻辑。若需临时兼容旧行为,可尝试给链接器添加--no-check-sections参数,但该参数可能引发其他兼容性问题,仅建议作为临时方案。
内容的提问来源于stack exchange,提问作者Alexander Buraga
相关产品推荐
相关产品推荐

