關於BSS段的大小

1.BSS段中的內容

先明確 BSS 段“存放”的是未初始化的全局變量與局部靜態變量,此處指的存放是指爲其預留空間(佔位符)。但BSS段在磁盤上不是真的佔用變量大小的空間,它僅是在該段中記錄了所有未初始化全局變量與局部靜態變量的大小總和,至於每個變量的大小則存儲在符號表的size屬性中。即:

BSS段內容:無內容,它將在段表中佔一個段描述符,該段描述符的size屬性將記錄未初始化的全局變量與局部靜態變量的大小總和

每個未初始化全局對象與靜態對象的大小:存儲在符號表的 size 屬性中

(上述說法求證於C++牛人“藍色”,表感謝。。。)


注:段表描述了ELF各個段的信息,比如每個段的段名,長度,在文件中的偏移等。ELF文件的段結構就是由段表決定的。

注:段表的結構是一個以“Elf32_shdr”結構體爲元素的數組,數組元素個人等於段的數目,每一個結構體對應一個段。將這個結構體稱爲段描述符。而BSS則僅在段表中佔用一個段描述符。但是在實際的ELF文件中不存在該段。


2.BSS段在加載運行前的處理

當可執行文件加載運行前,會爲BSS段中的變量分配足夠的空間並全部自動清理(因此,纔有未初始化的全局變量的值爲0的說法)。


3.BSS段的作用

BSS段主要是爲了節省可執行文件在磁盤上所佔的空間,其僅僅記錄變量所需的大小。對未初始化的大型數組的節省效率比較明顯。舉例如下:

[cpp] view plain copy
  1. static int a[10000];  
  2. int main()  
  3. {  
  4.      //...  
  5. }  

在上述程序中,若不存在 BSS 段,則可執行文件將開闢一個 10000 * sizeof(int) 大小的空間,並全部存儲爲0,int 爲4字節的情況下,該變量將在磁盤上佔用39KB的空間。但是此時若是存在BSS 段,則在可執行文件中,將只是記錄現在的BSS段總大小爲40000即可,而無需真正的佔據39KB的空間

該可執行文件在執行前將重新開闢39KB的空間,並自動初始化爲0


4. 代碼優化對BSS段的影響

考慮以下兩個靜態變量分別存儲在哪個段中:

[cpp] view plain copy
  1. static int x1 = 1;  
  2. static int x2 = 0;  

很明顯可以看出,X1將被髮在.data段中。令人意外的是 X2 將被放置在 .bss 段中,因爲 x2 的值爲0,被認爲是未初始化的,因此將會被放在 .bss 段中以節省磁盤空間。


5.Linux 下查看段屬性的指令:

用readelf -s 或 objdump -t 查看符號表
用readelf -S 或 objdump -h 查看段表


from: http://blog.csdn.net/virtual_func/article/details/48529249

發佈了12 篇原創文章 · 獲贊 77 · 訪問量 125萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章