.bss:未初始化的全局C变量。在目标文件中这个段不占据实际的空间,它公公是一个点位符。目标文件格式区分初始化和未初始化是为了空间效率:在目标文件中,未初始化变量不需要占据任何实际的磁盘空间。
$gcc main.c -g $readelf -a a.out ...
49: 0804a01c 4 OBJECT LOCAL DEFAULT 24 b
50: 0804a020 4 OBJECT LOCAL DEFAULT 24 a.1707
...
65: 08048570 4 OBJECT GLOBAL DEFAULT 16 A
66: 0804a018 4 OBJECT GLOBAL DEFAULT 24 a
...
78: 0804a02c 4 OBJECT GLOBAL DEFAULT 25 c
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[14] .text PROGBITS 08048390 000390 0001bc 00 AX 0 0 16
[16] .rodata PROGBITS 08048568 000568 00001c 00 A 0 0 4
[24] .data PROGBITS 0804a010 001010 000014 00 WA 0 0 4
[25] .bss NOBITS 0804a024 001024 00000c 00 WA 0 0 4
.bss段从地址0x804a024开始(紧挨着.data段),长度为0xc,也就是到地址0x804a030结束。变量c位于这个段。从上面的 readelf输出可以看到,.data和.bss在加载时合并到一个Segment中,这个Segment是可读可写的。.bss段和.data段的不同之处在于,.bss段在文件中不占存储空间,在加载时这个段用0填充。所以我们在第 4 节 “全局变量、局部变量和作用域”讲过,全局变量如果不初始化则初值为0,同理可以推断,static变量(不管是函数里的还是函数外的)如果不初始化则初值也是0,也分配在.bss段。
为什么未初始化的数据称为.bss?
用术语.bss来表示未初始化的数据是很普遍的。它起始于IBM704汇编语言中的“块存储开始(Block Storage Start)”指令的首字母缩写,并沿用至今,一个记住区分.data和.bss节的简单方法是把“bss”看成是“更好地节省空间(Better Save Space)”的缩写。