對於乙個c程式而言,要想能夠在機器上執行,它需要經歷很多步驟。首先,需要compiler將其轉換為組合語言程式,然後利用assembler再將其轉換為機器語言程式(也就是二進位製碼),然後應該是利用linker將它和必要的庫檔案鏈結在一起。最後才是用loader將連線的檔案從磁碟中讀到記憶體中,然後才能被計算機執行,從而產生結果。
對於compiler是如何轉換的可以參見compiler--dragon book. 而assembler應該比較簡單,它主要就是將符號語言對應到機器碼而已。經過assembler處理後的檔案分為以下幾個部分:一些統計資訊(如包含的過程名,text size, data size),text segment, data segment, relocation info, symbol table。統計資訊的作用是在linker的時候很容易計算應該分配給text以及data的記憶體的大小。text segment也就是code。data setment應該是static variables區域吧。而relocation info記錄的是當前object file中還不知道位址的code或data的位址。symbol table記錄的是檔案中的每個label以及其位址的對應。這裡的label可以是code也可以是data。而linker的作用就是根據object files中的資訊將多個object files進行組合成為乙個整體,這裡他的主要任務是解決還不知道具體位置的lable的位址,主要通過object files中記錄的資訊。而loader的作用就是將最後的可執行檔案放入記憶體,並設定相應的機器狀態,以便執行程式。
對於linker,有乙個dynamically linked libraries的概念。普通的linker是將所有的庫檔案以及原object files全部連在一起,當然這是在程式執行之前。這樣做的話一方面會使可執行檔案不能適應變化,比如當libraries進行了改進後,原有的可執行檔案就必須重新連線一邊。另外在使用者檔案中並不會用到libraries中的所有庫函式,如果將所有引用的庫全組合在一起的話,必然會不必要的增加可執行檔案的長度。而dynamically linked libraries技術就是為了解決這個問題的。他用到的主要思想就是indirection。也就是說在使用者檔案中對所有庫檔案的呼叫都首先轉到乙個dummy routines。當然這些routines是和原檔案靜態鏈結的。每乙個庫函式都對應有乙個dummy routine。這些dummy routines首先會將乙個特定的數字放入特定的register中,這個數字對應於該dummy routine所對應的庫函式。然後這些dummy routine會呼叫乙個dynamic linker-loader。這個linker-loader根據前面的數字從dll檔案中找到對應的函式並將其加入到記憶體中。
關於源程式到可執行程式的過程
源程式,是指未經編譯的,按照一定的程式語言規範書寫的,人類可讀的文字檔案,我們通常理解為源程式就是我們所寫好的 可執行程式,我們常說的.exe程式,可以執行程式,完成計算機功能。在c語言中,c檔案就是所謂的原始檔,接下來,我們剖析一下,源程式到可執行程式的過程。在這個過程中,會發生如下的變化 c檔案...
關於源程式到可執行程式的過程
源程式,是指未經編譯的,依照一定的程式語言規範書寫的,人類可讀的文字檔案,我們通常理解為源程式就是我們所寫好的 可執行程式。我們常說的.exe程式,能夠執行程式。完畢計算機功能。在c語言中,c檔案就是所謂的原始檔,接下來,我們剖析一下,源程式到可執行程式的過程。在這個過程中。會發生例如以下的變化 c...
C C 源程式到可執行程式exe的全過程
本文參考了部落格,其位址如下 原始檔生成可執行檔案的過程總共是經歷了預處理 編譯 彙編 鏈結四個過程。源程式 source code 預處理器 preprocessor 編譯器 compiler 匯程式設計序 assembler 目標程式 object code 聯結器 鏈結器,linker 可執行...