可重定位目標檔案(多位高手回答版,未綜合)

2021-07-14 14:41:43 字數 1016 閱讀 1096

乙個c/c++程式要經過預處理,編譯,彙編和連線四步生成可執行檔案,第三部彙編後生成的 .o 檔案即obj檔案,也稱為可重定位目標檔案,這裡的可重定位該如何理解。

簡單來說,就是說檔案裡面的**段和資料的位址還沒有最終確定。

編譯器編譯後產生的目標檔案是可重定位的程式模組,並不能直接執行,鏈結就是把目標檔案和其他分別進行編譯生成的程式模組(如果有的話)及系統提供的標準庫函式連線在一起,生成可執行的可執行檔案的過程。

重定位是鏈結器在完成符號解析後(知道了各個輸入模組的**段和資料段的大小)的乙個步驟,其作用顧名思義就是重新定位,確定比如指令,全域性變數等在執行時的儲存器位址。

比如說兩個編譯後的可重定位目標檔案obj1.o和obj2.o

在obj1.o裡面定義了乙個全域性變數glob(在obj1裡面記錄了glob相對於該檔案資料段的相對位址), 而obj2.0裡面又引用了這個全域性變數glob。

鏈結的重定位就是要確定在鏈結後的可執行程式中glob的位址,而不是相對於obj1的位址,從而使obj2也能通過位址呼叫glob。

當然重定位並不只是全域性變數,還包括外部函式,指令等執行時位址的確定

當你在程式中寫上乙個全域性變數或者是乙個函式時,這個定位過程會經歷幾個階段:

1.在這個目標檔案中的相對定位,乙個目標檔案中會此檔案中的所有函式,變數進行符號描述,比如乙個變數a,它所佔的相對位址是多少?是全域性的?或者是靜態的,或者是外部的??

2.在連線多個目標成乙個可執行檔案時,會再次對這個變數進行重定位,也就是在這個可執行檔案中進行對此變數進行描述,同目標檔案中的描述差不多,只不過此變數不再有外部,內部之分,都成了本地變數,並且會將所有全域性變數存放在一定的邏輯位址中,這是通過連線指令碼檔案與各個目標檔案中的相對位址共同決定的

3.最終的作業系統載入這個可執行檔案時,會對這些變數與函式位址再次進行重定位,其方式就是首先分析這個可執行檔案中的不同段,讀出相應的描述表,然後通過邏輯位址與實體地址進行對映出,最終就將可執行的二進位製碼加進了真實的物理記憶體了,關於分析可執行檔案格式與實體地址的轉換,不同的cpu與作業系統的實現方式會有不同之處

可重定位目標檔案

目標檔案有三種形式 1.可重定位目標檔案 2.可執行目標檔案 3.共享目標檔案 編譯器和彙編器生成可重定位目標檔案 共享目標檔案,聯結器生成可執行目標檔案。在這裡我們首先介紹可重定位目標檔案。可重定位目標檔案 包含二進位制 和資料,可以在編譯時與其他可重定位目標檔案合併起來,建立乙個可執行目標檔案。...

可重定位目標檔案

可重定位目標檔案經由源程式預處理,編譯,彙編之後得到的檔案。其中包括不可讀的二進位制 擴充套件名為.o。現有兩個模組的 main.c int sum int a,int n int array 2 int main sum.c int sum int a,int n return s 一.在linu...

7 4 可重定位目標檔案

下圖展示了乙個典型的elf可重定位目標檔案的格式。elf頭 elf header 以乙個16位元組的序列開始,這個序列描述了生成該檔案的系統的字的大小和位元組順序,elf頭剩下的部分包含幫助鏈結器語法分析和解釋目標檔案的資訊。其中包括elf頭的大小,目標檔案的型別 如可重定位,可執行性,或者共享的 ...