重定位和鏈結指令碼

2021-08-07 04:58:13 字數 965 閱讀 7388

重定位實際就是在執行位址處執行一段位置無關碼pic,讓這段pic(也就是重定位**)從執行位址處把整個程式映象拷貝乙份到鏈結位址處,完了之後使用一句長跳轉指令從執行位址處直接跳轉到鏈結位址處去執行同乙個函式,這樣就實現了重定位之後的無縫連線。

鏈結位址:鏈結時指定的位址(指定方式為:makefile中用-ttext,或者鏈結指令碼)

執行位址:程式實際執行時位址(指定方式:由實際執行時被載入到記憶體的哪個位置說了算)

為什麼需要重定位

鏈結位址和執行位址有時候必須不相同,而且還不能全部用位置無關碼,這時候只能重定位。

重定位中兩個重要的偽指令

ldr是長載入,ldr指令在載入符號位址時,載入的是鏈結位址。

adr是短載入,adr指令載入符號位址,載入的是執行時位址

鏈結指令碼其實是個規則檔案,他是程式設計師用來指揮鏈結器工作的。鏈結器會參考鏈結指令碼,並且使用其中規定的規則來處理.o檔案中那些段,將其鏈結成乙個可執行程式。

鏈結指令碼的關鍵內容有2部分:段名 + 位址(作為鏈結位址的記憶體位址)

sections 這個是整個鏈結指令碼

. 點號在鏈結指令碼中代表當前位置。

= 等號代表賦值

程式段的概念:**段、資料段、bss段(zi段)、自定義段

段就是程式的一部分,我們把整個程式的所有東西分成了乙個乙個的段,給每個段起個名字,然後在鏈結時就可以用這個名字來指示這些段。也就是說給段命名就是為了在鏈結指令碼中用段名來讓段站在核實的位置。

一種是程式設計師自己指定的、自定義的段名。

先天性段名:

**段:(.text),又叫文字段,**段其實就是函式編譯後生成的東西

資料段:(.data),資料段就是c語言中有顯式初始化為非0的全域性變數

bss段:(.bss),又叫zi(zero initial)段,就是零初始化段,對應c語言中初始化為0的全域性變數。

後天性段名:

段名由程式設計師自己定義,段的屬性和特徵也由程式設計師自己定義。

重定位和鏈結指令碼

但是也有一種特別的指令他可以跟指定的鏈結位址沒有關係,這些 不管放在 都可以正常執行。分析 在linux中的應用程式 gcc hello.c o hello bootloader必須大於16kb小於96kb,假定為80kb。啟動過程如下 開機上電後bl0執行,bl0載入外部啟動裝置中的bootloa...

重定位引入和鏈結指令碼

1 乙個事實 大部分指令是位置有關編碼 位置無關編碼 pic,position independent code 彙編原始檔被編碼成二進位制可執行程式時編碼方式與位置 記憶體位址 無關。位置有關編碼 彙編原始碼編碼成二進位制可執行程式後和記憶體位址是有關的。我們在設計乙個程式時,會給這個程式指定乙個...

鏈結指令碼與重定位

一 位置有關 和位置無關 以前,我們編寫程式的時候,根本不知道還有位置有關 和位置無關 不知道 的執行居然和 的鏈結位址有關,當然也不知道鏈結位址是什麼,但是在linux的學習中,這些都是必須的。舉個例子 我們在設計乙個程式的時候,就必須給這個程式指定乙個執行位址 這個指定的執行位址就是鏈結位址 這...