初始化的全局變量一定放在.data段中嗎?

學過C語言的都知道,已經初始化的全局變量是放在.data段中的,沒有初始化的全局變量是放在.bss段中的。一直以來我也是這麼認爲的,但在開發MyOS的過程中,一些明明已經初始化的數據在執行時得到的卻是隨機值,使我對這個說法產生了懷疑。例如,在MyOS的VBE驅動中,背景色明明設成了黑色,可系統啓動後屏幕卻是紅色的。昨天,在真機上調試最新的MyOS代碼時,任務調度老是調度不到別的線程去,只有一個Idle線程在跑。輸出了很多的調試信息,可就是找不到哪錯了。最後發現,系統的確是進行調度了,可被選中的新的線程還是Idle線程。而進程和線程管理的代碼經過檢查是沒錯的。而且還有一個奇怪的現象就是在調試信息中爲了看到系統的確的不斷輸出,我在每個輸出語句後加了一個從0開始不斷增加的數,每次輸出就遞增,這樣就能看到變化了。在VMWare上,工作的很好,是從0開始遞增的,可在真機上是從一個很大的數開始遞增的。就在我即將崩潰之際,突然想到是不是flag這個控制線程創建的全局變量也沒有按照我想的那樣初始爲0,導致根本沒有別的線程被創建,所以就只有Idle一個線程在運行。當我把flag設成局部變量後,系統就正常了。

我猜想是不是編譯器發現變量是被初始化成了0,所以就把變量放到.bss段中了。因爲.bss段一般情況下會清0的。所以,編譯器認爲沒有必要把這個變量放在.data段中。而MyOS在啓動的時候,並沒有把.bss段佔用的內存清0。因爲我一直認爲.bss段中放的是未初始化的數據,清不清0關係不大,只要我保證在使用時初始化就是了。沒想到編譯器把已經初始化爲0的變量也放到了.bss段中了。

當然,這樣可以減少可執行文件的體積。而且正如上面所說,一般的系統都會把.bss段清0,所以不會有問題。而MyOS是個操作系統,沒有人幫我們把它清0,纔出現了上面說到的很多問題。

接下來的幾天,應該修復MyOS的這個Bug,添加把.bss段清0的代碼。當然,只需4行C代碼即可,即時是彙編也不會超過10行。

大家可以看出來,這個說法其實是我的猜測,所以還是需要實際驗證。但我想應該是這樣的。

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