編譯—連結—載入工具鏈

目的檔及其區段(object file and its sections)

目的檔是組譯器為單一編譯單元交出的半成品,在類 Unix 系統上通常帶 .o 副檔名(Windows 上是 .obj)。它含有那一個原始檔中各函式的真實機器碼,但本身還不能執行:它在提及其他檔案所定義的東西時仍有空缺,而且還沒有人決定它將落在記憶體的哪裡。可以把它想成一本書的一個章節,已完整排版,但還沒和其他章節裝訂在一起、也還沒編頁碼。

在內部,目的檔被組織成具名的區段,每個區段裝一種內容。.text 區段裝你各函式的真實機器指令。.data 區段裝以非零值起始的全域與靜態變數。.bss 區段為以零起始的全域變數保留空間(它只存大小,而非一長串零,以保持檔案小巧)。.rodata 區段裝唯讀常數,如字串字面值。在這些旁邊還有符號表(這個檔案所定義名稱、以及它仍需從別處取得名稱的目錄)與重定位資訊(一份待辦清單,記著一旦最終位置確定就必須修正的位址)。

這種分區段的佈局正是讓後續連結步驟得以進行且整潔的關鍵。連結器可以把許多目的檔的所有 .text 區段彙集成一塊程式碼、所有 .data 區段成一塊資料,依此類推,然後指派真實位址並修補空缺。同樣的區段稍加重排,最終會進入可執行檔。你可以用像 nm(列出符號)、objdump 與 readelf(傾印區段)這類工具窺視目的檔內部,這是把抽象概念變具體的好方法。

$ gcc -c utils.c # -c 在組譯器後停下:產生 utils.o,不連結 $ nm utils.o 0000000000000000 T add # T = 定義在 .text(這個檔案提供 add) U printf # U = 未定義(需要從別處取得 printf)

目的檔列出它提供什麼(T)與它仍需要什麼(U),準備好交給連結器。

目的檔本身不可執行:它的跨檔參照仍未解析,也沒有最終的記憶體位址,這兩者都只有連結器能提供。

又稱
.o fileobject code目的檔目標檔