BSS段不占磁盘空间的理解

BSS段存放两种变量类型:

  • 未初始化全局变量
  • 未初始化局部静态变量

如何证明BSS段不占磁盘空间?

  • 其他各段数据不变,单纯增加BSS段存放的变量,观察ELF文件大小的变化

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    > echo 'int global[1024]; int main() { return 0; }' > test.c
    > gcc test.c -o test
    > ls -rtl test
    ----------------
    -rwxrwxr-x 1 cruise cruise 4569 6月 26 23:21 test
    ----------------

    > size test
    ----------------
    text data bss dec hex filename
    960 248 4128 5336 14d8 test
    ----------------

    // 将global大小扩大一倍
    > echo 'int global[2048]; int main() { return 0; }' > test.c
    > gcc test.c -o test
    > ls -rtl test
    ---------------
    -rwxrwxr-x 1 cruise cruise 4569 6月 26 23:25 test
    ---------------

    > size test
    --------------
    text data bss dec hex filename
    960 248 8224 9432 24d8 test
    --------------

    将global数组的大小增加一倍的时候,文件的大小仍然不变。

  • 对BSS段中的变量进行初始化,变量将被存放在数据段,观察ELF文件大小的变化

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    > echo 'int global[1024]; int main() { return 0; }' > test.c
    > gcc test.c -o test
    > ls -rtl test
    ----------------
    -rwxrwxr-x 1 cruise cruise 4569 6月 26 23:21 test
    ----------------

    > size test
    ----------------
    text data bss dec hex filename
    960 248 4128 5336 14d8 test
    ----------------

    // 将对global进行初始化
    > echo 'int global[1024] = {1}; int main() { return 0; }' > test.c
    > gcc test.c -o test
    > ls -rtl test
    ----------------
    -rwxrwxr-x 1 cruise cruise 8701 6月 26 23:39 test
    ----------------

    > size test
    ----------------
    text data bss dec hex filename
    960 4372 8 5340 14dc test
    ----------------

    将global进行初始化之后,ELF文件增大将近一倍。而如果BSS段占用磁盘空间的话,大小不变才对。

通过上面两个实验可以证明,BSS段实际是不占用磁盘空间的,只在段表中记录大小,在符号表中记录符号。当文件装载运行时,才会分配空间以及初始化。

BSS历史

BSS(Block Started by Symbol)这个词最初是UA-SAP汇编器(United Aircraft Symbolic Assembly Program)中的一个伪指令,用于为符号预留一块内存空间。该汇编起由美国联合航空公司于20世纪50年代中期为IBM 704大型机所开发。

后来BSS这个词被作为关键子引入到IBM 709和7090/94机器上的汇编器FAP(Fortran Assembly Program),用于定义符号并且为该符号预留给定数量的未初始化空间。

Unix FAQ session 1.3( http://www.faqs.org/faqs/unix-faq/faq/part1/section-3.html)里面有Unix和C语言之父Dennis Rithcie对BSS这个词由来的解释。

-- 摘自《程序员的自我修养——链接、装载与库》