当前位置: 首页 > news >正文

【ARM 嵌入式 编译系列 7.5 -- GCC 打印链接脚本各段使用信息】

文章目录

    • Overview
      • 1 在 linker script 中定义符号
      • 2 编译并生成 ELF 文件
      • 3 使用 nm + awk 输出各段地址及大小(含单位)
      • 4 实际输出示例
      • 5 进阶建议

Overview

在 GCC 编译生成 elf 后 打印出出数据段的开始地址及结束地址,bss 段的开始地址和结束地址,stack 段的开始地址及结束地址,以及它们的大小,注意大小要带上单位,比如 K。

要在 GCC 编译生成 .elf 文件后 打印出各段的开始地址、结束地址、大小(带单位,如 K),可以结合 nmobjdump 工具,以及 linker script 中的符号定义,一步步实现。

1 在 linker script 中定义符号

我们先假设你正在使用一个自定义的 linker.ld 文件,请确保你在其中定义好以下符号:

/* Data segment */
__data_start = .;
*(.data)
__data_end = .;/* BSS segment */
__bss_start = .;
*(.bss)
__bss_end = .;/* Stack segment (示例: 向下分配 1KB) */
__stack_end = ORIGIN(RAM) + LENGTH(RAM);  /* stack 顶部地址 */
__stack_start = __stack_end - 1K;         /* 1KB 栈空间 */

也可以使用更复杂的 stack 分配逻辑,核心是要定义 __stack_start__stack_end

2 编译并生成 ELF 文件

使用 GCC 编译,指定 -T linker.ld 使用上面的脚本:

arm-none-eabi-gcc -T linker.ld -o prog.elf main.c

3 使用 nm + awk 输出各段地址及大小(含单位)

nm -n prog.elf | awk '
/__data_start/ { data_start = strtonum("0x" $1) }
/__data_end/   { data_end   = strtonum("0x" $1) }
/__bss_start/  { bss_start  = strtonum("0x" $1) }
/__bss_end/    { bss_end    = strtonum("0x" $1) }
/__stack_start/ { stack_start = strtonum("0x" $1) }
/__stack_end/   { stack_end   = strtonum("0x" $1) }END {printf "DATA segment:  0x%08X ~ 0x%08X, size: %.2fK\n", data_start, data_end, (data_end - data_start)/1024.0printf "BSS segment:   0x%08X ~ 0x%08X, size: %.2fK\n", bss_start, bss_end, (bss_end - bss_start)/1024.0printf "STACK segment: 0x%08X ~ 0x%08X, size: %.2fK\n", stack_start, stack_end, (stack_end - stack_start)/1024.0
}'

这个脚本的作用是:

  • 查找每个段的 startend 地址

  • 计算并格式化输出段的大小(单位为 KB)

4 实际输出示例

假设生成的 prog.elf 中的段布局如下:

__data_start = 0x20000000
__data_end   = 0x20000100
__bss_start  = 0x20000100
__bss_end    = 0x20000200
__stack_start = 0x20001000 - 0x400 = 0x20000C00
__stack_end   = 0x20001000

执行脚本后输出:

DATA segment:  0x20000000 ~ 0x20000100, size: 0.25K
BSS segment:   0x20000100 ~ 0x20000200, size: 0.25K
STACK segment: 0x20000C00 ~ 0x20001000, size: 1.00K

5 进阶建议

你还可以将输出集成到 Makefile 中,例如:

print-segments:nm -n prog.elf | awk '......同上脚本......'
http://www.lryc.cn/news/574019.html

相关文章:

  • Java面试复习:基础、并发、JVM及框架核心考点解析
  • AI辅助编程工具技术评估(2025年):CodeBuddy在开发者生态中的差异化优势分析
  • 【达梦数据库】忘记SYSDBA密码处理方法-已适配
  • 图像处理基础篇
  • 麒麟系统上设置Firefox自动化测试环境:指定Marionette端口号
  • 纯血HarmonyOS5 打造小游戏实践:扫雷(附源文件)
  • 电脑的虚拟内存对性能影响大吗
  • 深入理解JavaScript设计模式之迭代器模式
  • Docker部署prometheus+grafana+...
  • 【论文阅读35】-PINN review(2021)
  • 华为云 Flexus+DeepSeek 征文|增值税发票智能提取小工具:基于大模型的自动化信息解析实践
  • 虚拟 DOM 与 Diff 算法:现代前端框架的核心机制
  • [3-01-02].第15节:调优工具 - 查看 SQL 执行成本
  • 编程捏脸系统:从美术资源到实时变形的深度实现
  • 系统规划与管理师(第2版)第9章思维导图发布
  • STM32HAL库 -- 9.IIC通信 软件IIC与硬件IIC驱动0.96寸OLED屏幕
  • 【Linux指南】文件管理高级操作(复制、移动、查找)
  • GO 语言学习 之 代码风格
  • 时序数据库IoTDB数据导入与查询功能详解
  • 「ECG信号处理——(18)基于时空特征的心率变异性分析」2025年6月23日
  • IDEA中如何为 Spring Boot 项目添加 VM 参数?
  • 微服务架构下的分布式事务管理
  • CSS 中aspect - ratio属性的用途及应用
  • 【面板数据】上市公司投资者保护指数(2010-2023年)
  • 兆瓦闪充技术革命:解码新能源汽车补能赛道的技术跃迁与从业机会图谱
  • LNMP 一键部署脚本 shell脚本
  • Postgresql中不同数据类型的长度限制
  • 基于springboot+uniapp的“川味游”app的设计与实现7000字论文
  • HarmonyOS NEXT应用元服务布局优化ArkUI框架执行流程
  • Java性能优化权威指南-操作系统性能监控