【轉】程式執行過程
來源:https://www.cnblogs.com/xidian2014/p/8504580.html 【侵刪】
作者:lina2014
源程式是指未經編譯的,按照一定的程式設計語言規範書寫的,人類可讀的文字檔案,源程式就是所寫好的程式碼。
可執行程式,即常說的.exe程式,可以執行程式,完成計算機功能。在C語言中,.c檔案就是所謂的原始檔。
源程式到可執行程式的過程。在這個過程中,會發生如下的變化:
.c檔案生成.obj檔案的過程,稱為編譯,.obj檔案生成到.exe檔案的過程,稱為連結。
.obj檔案就是一個是程式編譯生成的二進位制檔案,當.exe檔案生成以後.obj檔案就會被刪除。
事實上,.c檔案生成.exe檔案的過程總共是經歷了預處理,編譯,彙編,連結,這四個過程。
1、預處理
為了接下來能夠解釋的更加清楚,使用linux平臺下的gcc編譯器解釋。
先書寫一個非常簡單的程式來介紹:
test.c 1 #include<stdio.h> 2 3 int main() 4 { 5 printf("hello"); 6 7 return 0; 8 }
直接編譯得到:
第一步發生的是預編譯,使用-E指令會使程式只進行到預編譯指令。經過預編譯指令後的會生成一個.i檔案。
在預編譯的過程中,主要處理原始碼中的預處理指令,引入標頭檔案,去除註釋,處理所有的條件編譯指令,巨集的替換,新增行號,保留所有的編譯器指令。
當進行預編譯以後的檔案中將不再存在巨集,所有的巨集都已經被替代。當想要判斷巨集是否正確或者標頭檔案包含是否正確時,也可以通過預編譯來檢視。
2、編譯
在預處理結束後,進行的是編譯。編譯過程所進行的是對預處理後的檔案進行語法分析,詞法分析,語義分析,符號彙總,然後生成彙編程式碼。
3、彙編
彙編過程將彙編程式碼轉成二進位制檔案,二進位制檔案就可以讓機器來讀取。每一條彙編語句都會產生一句機器語言。
在這裡最終會生成一個重定位目標檔案 .o檔案,類似windows下的.obj檔案。這裡生成的目標檔案裡面就是二進位制檔案。另外,在這裡會形成符號表,給這些符號會分配虛擬地址。
4、連結
由彙編程式生成的目標檔案並不能立即就被執行,其中可能還有許多沒有解決的問題。例如,某個原始檔中的函式可能引用了另一個原始檔中定義的某個符號(如變數或者函式呼叫等);在程式中可能呼叫了某個庫檔案中的函式等等。所有這些問題,都需要經連結程式的處理方能得以解決。連結程式的主要工作就是將有關的目標檔案彼此相連線,也即將在一個檔案中引用的符號同該符號在另外一個檔案中的定義連線起來,使得所有的這些目標檔案成為一個能夠被作業系統裝入執行的統一整體。
連結分為靜態連結和動態連結:
靜態連結:字尾是.a,主要在編譯的時候將庫檔案裡面程式碼搬遷到可執行的檔案中;
動態連結:字尾是.so,主要在執行的時候需要轉換到庫檔案程式碼執行;
兩種連結的優缺點:
(1)靜態的連結產生的可執行的檔案體積比較的大;而動態連結的可執行檔案的體積比較小;
(2)動態的連結的編譯的效率比較的高;
(3)靜態連結的可執行的檔案執行的效率高
(4)靜態連結的可執行的檔案的“佈局”比較好一點;