C語言 程式中的預處理 編譯 彙編和鏈結過程

2021-09-26 16:30:23 字數 2235 閱讀 4976

這篇部落格主要記錄下c語言程式從原始檔變成可執行程式的過程,在linux系統中,gcc執行這個過程分為四個階段:預處理、編譯、彙編和鏈結,整個過程是通過編譯工具鏈實現的。

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

說明:進行預處理操作時,預處理器會對以#開頭的預處理命令進行處理。比如:#include ,預處理器會將系統中的stdio.h的具體內容讀取到文字中,替換原有的#include ,得到乙個新的c檔案,也就是i檔案。

備註:之後還會詳細記錄下預處理中的一些事情。

命令 gcc -s main.i -o hello.s

或者 gcc -s main.c -o hello.s

說明:第一種方式是由編譯器單獨完成的,第二種是由預處理器和編譯器一起完成的,編譯器將main.i翻譯成了main.s彙編檔案,匯程式設計序是一條條通用的機器語言指令。

備註:編譯時,編譯器需要檢查語法、函式與變數宣告的正確,語法的正確是對於每個檔案中基本指令的準確性,函式與變數的宣告則需要告訴編譯器標頭檔案所在的位置。(宣告在標頭檔案,定義在c/c++檔案),所有的語法正確,編譯器就可以編譯出中間目標檔案。

命令 gcc -c main.s -o main.o

說明:彙編器會將main.s翻譯成機器指令,將這些機器指令打包成*.o格式的可重定位檔案,並將結果儲存在目標檔案中。目標檔案是由不同的段組成的,通常乙個目標檔案至少有兩個段–資料段和**段,main.o用文字檔案開啟之後是看不懂的,因為是二進位制檔案。

命令 gcc main.o -o main.out

說明:鏈結是最後乙個過程,鏈結器會將main.o和其他庫檔案、目標**檔案鏈結後形成可執行程式(把大量的objectfile合成執行檔案),比如:假設main.c中呼叫了函式printf,鏈結器會將printf.o檔案併入我們的main.out可執行檔案中,最後將可執行檔案載入到儲存器中,然後由系統執行。

備註:一般每個原始檔,應該都有對應於乙個中間目標檔案(.o或.obj檔案)。

01 平時我們說的編譯器實質上指的是編譯工具鏈,由於習慣的原因,平時我們經常只說了編譯鏈結,這裡的編譯不是第二階段,而是包含了預處理、編譯和彙編的三個過程,也就是由源程式檔案生成中間**檔案的過程(有點坑,習慣的東西之前一直沒理清楚)。而且,實際上,預處理用預處理器,編譯用編譯器,彙編用彙編器,鏈結用鏈結器,這幾個工具再加上一些其他額外會用到的工具,合起來就叫做編譯工具鏈,平時經常用到gcc就是乙個編譯工具鏈。

02 為了適應習慣吧,我以後也會叫這整個過程為編譯鏈結。但要明白裡面這些東西(其實好比cpu和soc),要不然別人說起預處理,我第一次的反應一直不知道是在**。

03 編譯鏈結中各種副檔名

副檔名含義.c檔案

c語言源**檔案

.a檔案

由目標檔案構成的靜態檔案

.c檔案

c++源**檔案

.**件

程式所包含的標頭檔案

.i檔案

預處理的c源**檔案

.ii檔案

預處理的c++源**檔案

.m檔案

objective-c源**檔案

.o檔案

編譯後的目標檔案

.out檔案

鏈結器生成的可執行檔案

.s檔案

組合語言源**檔案,後期不再進行預處理操作

.s檔案

組合語言源**檔案,後期還會進行預處理操作,可以包含預處理指令

04 windows的中間**檔案是.obj,unix/linux的中間**檔案是.o。

05 鏈結時,主要是鏈結函式和全域性變數,可以使用這些中間目標檔案來鏈結我們的應用程式,整個鏈結過程不需要理會原始檔,只需關注中間目標檔案,大多數情況下,由於原始檔太多,編譯生成的中間目標檔案太多,而且在鏈結的時候,需要明確地指出中間目標檔名,這對編譯十分不方便。所以,我們要給中間目標檔案打個包,在windows下這種包叫做「庫函式」(library file),也就是.lib檔案,在unix\linux下,是archive file靜態庫檔案,也就是.a檔案。

06 小結:原始檔生成可執行程式的過程中,原始檔首先會生成中間目標檔案,再由目標檔案生成執行檔案。在編譯的時候,只檢測語法、函式與變數宣告是否被宣告。如果函式未被宣告,編譯器會給出乙個警告,但可以生成目標檔案,在鏈結程式時,鏈結器會在所有的目標檔案中找尋函式的實現,如果找不到,那就會再報鏈結錯誤碼(linker error)。

C語言的預處理 編譯 彙編 鏈結

一 預處理 預處理指令的執行主要包含下列事情 1.標頭檔案的包含 2.注釋的刪除 3.巨集定義的替換 4.條件編譯的選擇 指令 gcc e test.c o test.i 呼叫的是預處理器cpp,e 只進行預處理操作,o 輸出到 檔案 i表示產生的臨時檔案 intermediate 二 編譯 編譯之...

預處理,編譯,彙編和鏈結

1 我們有乙個hello.c檔案,用最簡單的命令gcc hello.c 生成 a.out 這個過程可以分為四個步驟 預處理 prepressing 編譯 compilation 彙編 assembly 和鏈結 linking 一 預編譯 1.將所有的 define刪除,並展開所有的巨集定義 2.處理...

C語言編譯預處理

title date br description c語言編譯預處理 2019 11 06 14 35 32 0800 預處理 c語言 c語言預處理是對源 進行初步轉換 碼農有道 c源程式 編譯預處理 編譯 優化程式 匯程式設計序 鏈結程式 可執行檔案其中編譯預處理階段,讀取c源程式,對其中的預處理...