more: Jollen 的 Embedded Linux 教育訓練

« 「Truncate It」小技倆的原始碼與原理 | Home | Process Creation, #4:sys_fork《核心實作》 »

.bss section:C 語言所種下的因

jollen 發表於 January 10, 2007 10:44 PM

由於當初 C 語言標準提到「未初始化的全域變數(un-initialized global variables)其初始值為零(zero)」,所以得到的結果便是「程式執行時,必須將未初始化的全域變數都初始化成零」。

Linux 針對這種狀況的解決方式是「配置 zeroed pages 給 .bss section」,因此 un-initialized global variables 的值(value)便會為零。

註:Un-initialized global variables 會被編譯器放到 .bss section,可參考 Jollen 的「BSS Section 觀念教學」專欄。

此外,global variable 被初始化為零時,也會被 GCC 放到 .bss section 裡。所以,以下的寫法:

int foo;

main()
{
...
}

會等於:

int foo = 0;

main()
{
...
}

以上二種寫法都會讓 foo 被放到 .bss section。由此可知,以下二種狀況,變數都會被放在 .bss section:

1. 當 global variable 未被初始化時;
2. 或是 global variable 被初始化成零時。

-fno-zero-initialized-in-bss

如果(但是確實有這種應用場合)我們不想讓 variable 被放到 .bss section 呢?做法有二。第一種方式是「傳統做法」,程式設計師只要將 global variable 初始化為「非零」值即可,舉以下程式為例:

#include <stdio.h>

int foo = 1;

int main(void)

{

printf("foo is %d.\n", foo);

return 0;

}

將此程式編譯:

$ gcc -O2 -o bss bss.c

利用 objdump 來觀察後,會發現 foo 變數被 GCC 放到 .data section 裡了。這種做法是基於 coding 時的做法。

第二種做法是 GCC 3.4.x 後所支援的「-fno-zero-initialized-in-bss」最佳化選項。將程式修改如下:

#include <stdio.h>

int foo = 0;

int main(void)

{

printf("foo is %d.\n", foo);

return 0;

}

請特別留意,global variable 仍要做初始化,所以「foo」一定要做「assignment」為零值的動作。將程式編譯:

$ gcc -fno-zero-initialized-in-bss -O2 -o bss bss.c

GCC 會把 foo 放到 .data section。同樣可利用 objdump 來觀察。

良好的 Embedded Linux 程式寫作習慣

了解以上的觀念後,我要來說明一個重要的觀念。由於某些特定應用,或是 target 需要將變數放在 .data section 裡,因此若是 Embedded Linux 的應用,建議應對全域變數做初始化,例如:

int x;
int y;
int z;

int main(void)
{
...
}

應將這種傳統 C 的寫作習慣調整為:

int x = 0;
int y = 0;
int z = 0;

int main(void)
{
...
}

良好的習慣養成,未來將會得到許多好處。

這種寫法並非傳統 C 語言所講的「多此一舉」,應該以 Linux systems software 的角度來思考:這種寫法便能搭配 GCC 的「-fno-zero-initialized-in-bss」或是「-fzero-initialized-in-bss(預設)」選項,來決定 global variable 要放到 .bss section 或是 .data section。

--jollen

引用通告

如果您想引用這篇文章到您的Blog,
請複製下面的鏈接,並放置到您發表文章的相應界面中。

http://blog.jollen.org/mt-tb.cgi/323

評論 (1)

luke:

jollen大哥您好,感謝這篇文章提供的觀念,請教一下在什麼場合需要強制把變數放到data section,我想不到這樣有什麼好處,能提供進一步的資訊嗎?謝謝:)

發表一個評論

(您發表的意見將被立即接受,但需要一點時間與後端伺服器做同步,您的留言才會顯示在網站上。為避免 spam 攻撃,按「發表」後請輸入帳號密碼。使用者帳號:「nospam」、密碼:「nospam」。)

Top | 授權條款 | Jollen's Forum: Blog 評論、討論與搜尋
Copyright(c) 2006 www.jollen.org