Linux下程式編譯鏈結過程

2021-10-10 06:34:53 字數 1805 閱讀 2816

在linux下使用gcc將原始碼(.c檔案)編譯成可執行檔案的過程可以分解為4個步驟,分別是預處理(prepressing),編譯(compilation),彙編(assembly),鏈結(linking)

.i命令:gcc -e hello.c -o hello.i

--->

-e:可以使編譯器在預處理完成後就停止編譯 -o:指定gcc輸出的結果

預處理過程主要處理那些源**中以#開頭的**:

1.處理#define,展開所有的巨集定義

2.處理條件編譯指令,如#ifdef、#else、#endif

3.處理#include,將包含的標頭檔案插入到該預處理指令的位置,該過程遞迴進行,因為被包含的檔案可能還包含其他檔案

4.新增行號和檔案標識,如#2 「hello.c」 2,以便編譯時編譯器產生除錯用的行號資訊及用於編譯時產生編譯錯誤或警告時能夠顯示行號資訊

5.保留所有的#pragma編譯器指令,因為編譯器要使用它們

.i --

-->

.s命令:gcc -s hello.i -o hello.s 或者 gcc -s hello.c -o hello.s

--->

-s:可以使編譯器在編譯完成後就停止編譯 -o:指定gcc輸出的結果

編譯過程就是把預處理完的檔案進行一系列詞法分析,語法分析,語義分析及優化後生成相應的彙編**檔案(.s)

1.語法分析:分析表示式是否遵循語法規則

2.詞法分析:分析關鍵字,識別符號,立即數是否合法

3.語義分析:在語法分析基礎上進一步分析表示式是否合法

.s --

-->

.o命令:gcc -c hello.s -o hello.o 或者 gcc -c hello.c -o hello.o

--->

-c:可以使編譯器在彙編完成後就停止編譯 -o:指定gcc輸出的結果

彙編就是將彙編**轉變成機器可以執行的命令,生成目標檔案(.o),彙編器as根據彙編指令和機器指令的對照表一一翻譯即可完成

多個.o --

--> 可執行檔案

命令:gcc -o hello hello.c //一步到位

在這裡涉及乙個很重要的概念,函式庫。

大多數時候,由於原始檔太多,編譯生成的中間目標檔案太多,而在鏈結時需要明顯地指出中間目標檔名,這對於編譯很不方便,所以,我們要給中間目標檔案打個包,在windows下這種包叫「庫檔案」(library file),也就是 .lib 檔案,在unix下,是archive file,也就是 .a 檔案。

舉個列子:我們常用的printf函式,一般我們只會包含乙個標頭檔案(#include ),但這其中只有該函式的宣告,而沒有函式的具體實現,那麼該函式的實現在**呢?------->答案是函式庫,這裡是libc.so.6 庫

.

/hello //當編譯通過後,執行./+可執行檔名就可以執行檔案了

其實可以把gcc當成乙個翻譯組織,它有很多成員(翻譯官)。他根據不同的引數去呼叫不同的翻譯官來翻譯。最後,了解這四個過程中所做的工作,對我們理解標頭檔案、庫等的工作過程是有幫助的,而且清楚了編譯鏈結過程還對我們在程式設計時定位錯誤,以及程式設計時盡量調動編譯器的檢測錯誤也有很大幫助。

程式編譯,鏈結過程

c語言的編譯鏈結過程要把我們編寫的乙個c程式 源 轉換成可以在硬體上執行的程式 可執行 需要進行編譯和鏈結。編譯就是把文字形式源 翻譯為機器語言形式的目標檔案的過程。鏈結是把目標檔案 作業系統的啟動 和用到的庫檔案進行組織形成最終生成可載入 可執行 的過程。過程 如下 預處理器 將.c 檔案轉化成 ...

程式的編譯鏈結過程

一段源 到可執行性程式需要經歷預處理 編譯彙編和鏈結等步驟,接下來詳細介紹這些過程 假設檔案main.czhong有如下 include int main 1 巨集定義指令 2 條件編譯 3 標頭檔案包含指令 4 特殊符號處理 不能在標頭檔案中定義全域性變數,因為在標頭檔案中定義全域性變數將會使所有...

編譯鏈結過程

在談編譯鏈結過程之前我們需要了解一下虛擬位址空間以及程式在編譯鏈結過程時經過了什麼步驟。虛擬位址空間之前在程序空間的部落格中詳細介紹過了,詳見 上圖就是32位系統中4g虛擬位址空間的分布情況 text 段 指令段,存放的是指令 在程式中,我們把區域性變數定義 區域性變數的 定義是指令而不是資料 還有...