【ARM 嵌入式 编译系列 10.4.2 -- 查看 bss 段中有哪些内容】

文章目录

  • Overview
    • [一、什么是 .bss段?](#一、什么是 .bss段?)
    • [二、查看 .bss 段大小](#二、查看 .bss 段大小)
      • [方法 1:使用 size 命令](#方法 1:使用 size 命令)
    • [三、查看 .bss 段里都有哪些符号(变量)](#三、查看 .bss 段里都有哪些符号(变量))
      • [方法 2:用 `nm` 和 `grep` 查看 `.bss` 中的符号](#方法 2:用 nmgrep 查看 .bss 中的符号)
      • [方法 3:用 `objdump` 查看段内容(结构)](#方法 3:用 objdump 查看段内容(结构))
    • [为什么 .bss 很大?](#为什么 .bss 很大?)
    • 解决建议

Overview

在代码编译的时候,我们可能会发现 BSS 占用的空间比较大,那么如何使用GCC 相关的工具来

查看bss 端有哪些内容以及为什么这么大呢?

要查看 GCC 构建出来的程序中 .bss 段的内容和大小,需要理解两部分:

  1. .bss 是什么,它里面为什么"看起来很大"

  2. 怎么实际查看 .bss 里有哪些符号(变量)以及它们占用的空间

一、什么是 .bss段?

  • .bss(Block Started by Symbol)段用于存放 未初始化的全局变量和静态变量

  • 它在编译时 不占用实际空间,但在运行时由加载器或运行时初始化为全 0。

  • 编译器只是告诉链接器:"这段内存我以后要用,占 X 字节,但你不用给我写入文件。"

举例:

c 复制代码
int a;          // 位于 .bss 段
static int b;   // 位于 .bss 段
char buf[4096]; // 如果是全局/静态,位于 .bss 段

二、查看 .bss 段大小

方法 1:使用 size 命令

bash 复制代码
size your_program.elf

输出示例:

pgsql 复制代码
text    data     bss     dec     hex filename
   1024     512   65536   67072   10500 your_program.elf
  • .text:代码段大小

  • .data:已初始化的全局变量

  • .bss:未初始化的变量大小

  • dec/hex:总大小(十进制/十六进制)

上面显示 .bss 有 64KB,很可能是因为你有一个大数组,或某个库全局变量预留了大内存空间。

三、查看 .bss 段里都有哪些符号(变量)

方法 2:用 nmgrep 查看 .bss 中的符号

bash 复制代码
nm -S --size-sort your_program.elf | grep ' [Bb] '
  • -S:显示每个符号的大小

  • --size-sort:按大小排序

  • ' [Bb] ':匹配 .bss 段(大写 B 是全局变量,b 是局部静态变量)

示例输出:

css 复制代码
20001000 00010000 B big_buffer
20011000 00000004 b static_flag
  • big_buffer 是个大数组,占了 64KB

  • static_flag 是局部静态变量,占了 4 字节

方法 3:用 objdump 查看段内容(结构)

bash 复制代码
objdump -h your_program.elf

输出:

pgsql 复制代码
Idx Name          Size      VMA       LMA       File off  Algn
  5 .bss          00010000  20001000  20001000  00000000  2**4
                  CONTENTS, ALLOC, LOAD, DATA

显示 .bss 占了 0x10000(64KB),起始地址 0x20001000

为什么 .bss 很大?

常见原因

  1. 定义了大型全局/静态数组

    c 复制代码
    char buffer[64 * 1024];  // 占用 64KB
  2. 某些库(如 newlibprintf)内部定义了缓冲区

  3. 堆栈大小在链接脚本中定义为 .bss 变量

    ld 复制代码
    __stack = . + 0x8000;  // 32KB stack
  4. 链接脚本中手动分配了大段内存到 .bss

解决建议

  • 检查源代码中是否有大数组(尤其是未初始化的)

  • 检查链接脚本中是否 .bss 里分配了栈或堆(如 _stack_size)

  • 使用 nm/size 排查真正占空间的变量

  • 如果你用的是嵌入式系统,考虑是否能用动态内存或精简库(如 nano.specs

相关推荐
szxinmai主板定制专家14 小时前
基于ZYNQ的ARM+FPGA+yolo AI火灾实时监测与识别系统
arm开发·yolo·fpga开发
学不动CV了15 小时前
ARM单片机中断及中断优先级管理详解
c语言·arm开发·stm32·单片机·嵌入式硬件·51单片机
里予.c16 小时前
ARM—时钟(CLOCK)—定时器(EPIT / GPT)
arm开发·gpt
三毛200417 小时前
玳瑁的嵌入式日记---0925(ARM--时钟)
arm开发
亿道电子Emdoor18 小时前
【ARM】MDK-授权报错解决:用户/主机不在包含列表中
arm开发·stm32·单片机
望获linux19 小时前
【Linux基础知识系列:第一百三十九篇】使用Bash编写函数提升脚本功能
linux·运维·服务器·arm开发·chrome·性能优化·bash
望获linux21 小时前
论文解读:利用中断隔离技术的 Linux 亚微秒响应性能优化
java·linux·运维·前端·arm开发·数据库·性能优化
sheepwjl1 天前
《嵌入式驱动(二):驱动开发基本概念》
arm开发·驱动开发·单片机·嵌入式硬件·imx6ull·驱动·裸机
s9123601011 天前
RUST map_while 还是fillter_map
arm开发
GilgameshJSS1 天前
STM32H743-ARM例程2-UART命令控制LED
arm开发·stm32·单片机·嵌入式硬件