關於gcc ld的鏈結指令碼

2021-10-03 22:52:26 字數 1053 閱讀 3446

鏈結指令碼的主要目的是描述輸入檔案中的段如何被對映到輸出檔案中,並且控制輸出檔案中的記憶體排布。比如我們編譯生成的檔案一般都包含 text 段、 data 段等等。

sections

.rodata align(4

):// 常量資料 ro: read only

.data align(4

)://已被初始化為非零的全域性變數

__bss_start =.;

.bss align(4

)://沒有被初始化 和 已經被初始化為0 的全域性變數

__bss_end =.;

}

1、最簡單的鏈結指令碼可以只包含乙個命令「 sections」, 我們可以在這乙個「 sections」裡面來描述輸出檔案的記憶體布局。

2、「 .」在鏈結指令碼裡面叫做定位計數器,預設的定位計數器為 0。我們要求**鏈結到以 0x10000000 為起始位址的地方,因此這一行給「 .」賦值0x10000000,表示以 0x10000000 開始,後面的檔案或者段都會以 0x10000000 為起始位址開始鏈結。

3、「 .text」是段名,後面的冒號是語法要求,冒號後面的大括號裡面可以填上要鏈結到「 .text」這個段裡面的所有檔案,「 *(.text)」中的「 *」是萬用字元,表示所有輸入檔案的.text段都放到「 .text」中。

4、align(4)表示 4 位元組對齊。也就是說段「 .data」的起始位址要能被 4 整除。

5、設定鏈結到開始位置的檔案為 start.o,因為 start.o 裡面包含著第乙個要執行的指令,所以一定要鏈結到最開始的地方。

6、「 __bss_start」和「 __bss_end」是符號,這兩個符號用來儲存.bss 段的起始位址和結束位址,這兩行其實就是對這兩個符號進行賦值,其值為定位符「 .」。

7、我們需要手動對.bss 段的變數清零的,因此我們需要知道.bss 段的起始和結束位址,這樣我們直接對這段記憶體賦 0 即可完成清零。通過第 11、 13 行**, .bss 段的起始位址和結束位址就儲存在了「 __bss_start」和「 __bss_end」中,我們就可以直接在彙編或者 c 檔案裡面使用這兩個符號。

zynq 的鏈結指令碼

vivado使用的編譯器是gcc,因此zynq的鏈結指令碼如同其他使用gcc編譯的專案一樣。這裡使用u boot的鏈結指令碼為例,簡單描述怎麼使用鏈結指令碼增加cli的功能。這裡不描述鏈結指令碼的語法等內容。在u boot中,使用頻率頗高的巨集類似 u boot cmd bootm,config s...

uboot鏈結指令碼

gnu編譯器生成的目標檔案預設為elf格式,elf檔案由若干段 section 組成,如不特殊指明,由c源程式生成的目標 中包含如下段 text 正文段 包含程式的指令 data 資料段 包含固定的資料,如常量 字串 bss 未初始化資料段 包含未初始化的變數 陣列等。c 源程式生成的目標 中還包括...

鏈結指令碼(1)

1 什麼是ld?它有什麼作用?ld是gnu binutils工具集中的乙個,是眾多linkers 鏈結器 的一種。完成的功能自然也就是鏈結器的基本功能 把各種目標檔案和庫檔案鏈結起來,並重定向它們的資料,完成符號解析。linking其實主要就是完成四個方面的工作 storage allocation...