1. 程式人生 > >bss段為什麼要清零(轉載)

bss段為什麼要清零(轉載)

BSS段清零的原因是因為這個段是BSS

要說為什麼要有BSS的話,歷史就比較久遠了。

BSS段我所知道的起源是Unix最初的時候(當然,不排除可能有更早的情況)。變數分兩種:區域性變數、全域性變數。根據C語法的規定,區域性變數不設定初始值的時候,其初始值是不確定的,區域性變數(不含靜態區域性變數)的儲存位置位於棧上,具體位置不固定。全域性變數(和靜態區域性變數)有專門資料段儲存,初始值是0,具體位置是固定的。其實說到底,就兩種,一種是位置固定(資料段裡),一種是位置不固定的(棧上)。

要知道,早期的計算機儲存裝置是很貴的,而很多時候,資料段裡的全域性變數都是0(或者沒有初始值),那麼儲存這麼多的0到目標檔案裡其實是沒有必要的。所以為了節約空間,在生成目標檔案的時候,就把沒有初始值(實際就是0)的資料段裡的變數都放到BSS段裡,這樣目標檔案就不需要那麼大的體積裡(節約磁碟空間)。只有當目標檔案被載入的時候,載入器負責把BSS段清零(一個迴圈就可以搞定)。

之後,這個規則慢慢的成為一個標準配置,大多數編譯器也就都支援了BSS段。

然後解釋幾個問題:

Q:為什麼區域性變數初始值不是0?
A:區域性變數初始值也可以是零(在某些語言中就是),但這實際上需要消耗硬體指令去完成,有些時候這種清零的動作意義不大,對於編譯器來說也是一種負擔,每次呼叫函式都要消耗指令去清零,負擔太大。要知道全域性變數在記憶體中只有一份,區域性變數(非靜態)可以是多份的,前者一次清零就可以了,後者多次清零,負擔太大。

Q:如果BSS不清零可不可以?
A:可以,如果編譯器規定BSS段不清零,也是可以的,但這樣的話C語言語法就要改了:未初始化的全域性變數和靜態區域性變數,其值是未知的。甚至其它語言也要跟著改語法。

所以,BSS段清零的原因是因為這個段是BSS

現在儲存介質這麼便宜了,是不是BSS已經沒有必要了?當然不是了,介質便宜僅限於PC和數碼產品這一塊,嵌入式行業永遠都不存在儲存介質沒有限制的情況!

來自:http://www.zhihu.com/question/23147702/answer/23738366