SECTIONS bss段初始化分析
SECTIONS bss段初始化分析
都知道bss段需要初始化,但是這是為什么呢?
通過瀏覽資料,都會發現,bss段是不會出現在程序下載文件(*.bin .hex)中的,因為全都是0。如果把出現在程序下載文件中,會增加程序下載文件的大小。實際應用中,通常只需要把bss段的起始地址和結束地址保存起來,而不需要將程序下載文件中出現bss段(一堆0)將來真正運行程序的時候,再根據這兩個數據進行bss段的初始化就行了。
以上這段文字是網上的資料說的。但是,可不可以讓bss段出現在程序下載文件中呢?如果這樣可以的話,當程序由存儲器(例如nandflash)拷貝到內存中時,捎帶著會把bss段像data段那樣初始化。
實際上是可以這樣做的??聪逻叺膬蓚€鏈接腳本。
鏈接腳本一:
SECTIONS {
. = 0x00000000;
.init : AT(0){ head.o init.o nand.o}
. = 0x30000000;
.text : AT(4096) { (.text) }
.rodata ALIGN(4) : AT((LOADADDR(.text)+SIZEOF(.text)+3)&~(0x03)) {(.rodata)}
.data ALIGN(4) : AT((LOADADDR(.rodata)+SIZEOF(.rodata)+3)&~(0x03)) { *(.data) }
__bss_start = .;
.bss ALIGN(4) : { *(.bss) (COMMON) }
__bss_end = .;
}
鏈接腳本二:
SECTIONS {
. = 0x00000000;
.init : AT(0){ head.o init.o nand.o}
. = 0x30000000;
.text : AT(4096) { (.text) }
.rodata ALIGN(4) : AT((LOADADDR(.text)+SIZEOF(.text)+3)&~(0x03)) {(.rodata)}
.bss ALIGN(4) : AT((LOADADDR(.rodata)+SIZEOF(.rodata)+3)&~(0x03)){ *(.bss) }
.data ALIGN(4) : AT((LOADADDR(.bss)+SIZEOF(.bss)+3)&~(0x03)) { *(.data) }
}
鏈接腳本一,把bss段放在最后邊,arm-linux-gcc編譯器默認的會把bss段給忽略掉,也即不會讓bss段出現在程序下載文件中(可以通過Jlink軟件查看編譯后的bin文件)。這種鏈接腳本也是通常見到的方式。
鏈接腳本二,把bss段放在了rodata段和data段中間,這個時候,arm-linux-gcc編譯器并不會把bss段在程序下載文件中刪除,也即會把bss段保留下來,最終出現在程序下載文件中??紤]原因可能是這樣的:編譯后的地址rodata段、bss段、data段是連續的,也即程序運行時這幾個段是連續的;倘若把bss段在程序下載文件中刪除,那么程序下載文件中rodata段后邊緊接著的是data段;這就要求程序的這兩個段需要分別處理,而不能一次性將連續拷貝過去。
鏈接腳本二的方法可以讓bss段出現在程序下載文件中。但是,通常都不會這樣做,這里之所以這樣深鉆,只不過是在探究bss段初始化的必要性。通常采用的鏈接腳本一,由于最終程序下載文件中沒有bss段,所以必須在應用程序運行前,根據bss段的起始地址和結束地址將bss段初始化。
下邊,著重講一下鏈接腳本中與初始化bss段相關的幾句話。
(1) __bss_start = .;
(2).bss ALIGN(4) : { *(.bss) *(COMMON) }
(3)__bss_end = .;
實際上句(1)是在bss段的起始地址處定義了一個int類型的全局變量__bss_start。雖然,bss段的起始地址處肯定是一個未初始化的全局變量,但是這里算是編譯器又在這個位置上又重新定義了一個全局變量。就是說,一個地址有兩個名字,都能訪問這個地址空間。句(3)的解釋同句(1)。
接著再看一下用C語言寫的初始化bss段的程序。
(1)void clean_bss(void)
(2){
(3) extern int __bss_start, __bss_end;
(4) int *p = &__bss_start;
(5)
(6) for (; p < &__bss_end; p++)
(7) *p = 0;
(8)}
首先,句(3)對編譯器產生的兩個全局變量進行聲明。句(4)通過__bss_start取出bss段的起始地址,句(6)通過__bss_end取出bss段的結束地址。
參考鏈接:
https://www.cnblogs.com/amanlikethis/p/3384743.html
總結
以上是生活随笔為你收集整理的SECTIONS bss段初始化分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 自动驾驶参数分析
- 下一篇: 企业如何选择音视频会议系统分析