GCC中C 源程式到可執行檔案的四個步驟

2021-09-24 10:00:19 字數 2876 閱讀 7249

最近在參加提前批的面試,今天面的是vivo的嵌入式。其中問到乙個問題,c++的源程式到生成可執行檔案的過程。喵哥吞吞吐吐的答出了一部分。現在面完了,在網上找了下標準答案:預處理、編譯、彙編、鏈結。

在windows下,vc編譯乙個源程式都是一鍵完成,不知道過程,而我用linux的gcc生成執行檔案時,都是用

g++ hello.cpp -o test
然後用

./test
執行。原來我給自己挖了這麼久的坑啊,完全省去了中間步驟。

test用vim開啟的結果是:

如果按照上面提到的四個步驟處理原始檔,過程如下。

1.預處理

g++ -e hello.cpp -o hello.i
vim開啟hello.i的結果

2.編譯

g++ -s hello.i -o hello.s
用vim開啟hello.s

3.彙編

g++ -c hello.s -o hello.o
用vim開啟hello.o

4.鏈結

g++ hello.o -o hello
用vim開啟hello

於是,發現hello跟test是一樣的,但是我之前都是一步生成可執行檔案,所以對這個過程不是太了解。

在生成過程中產生的檔案也就只有最終的可執行檔案可以執行(下面第二幅圖中綠色高亮的是可執行檔案)。

鏈結可以執行與編譯時(源**被翻譯成機器**時),也可以執行與載入時(在程式被載入器載入到儲存器並執行時),甚至執行與執行時,由應用程式來執行。在現代系統中,鏈結是由鏈結器自動執行的。鏈結器分為:靜態鏈結器和動態鏈結器兩種。

a.  靜態鏈結器

靜態鏈結器以一組可重定位目標檔案和命令列引數作為輸入,生成乙個完全鏈結的可以載入和執行的可執行目標檔案作為輸出。

(1)符號解析:目標檔案定義和引用符號。符號解析的目的在於將每個符號引用和乙個符號定義聯絡起來。

(2)重定位:編譯器和彙編器生成從位址零開始的**和資料節。鏈結器通過把每個符號定義和乙個儲存器位置聯絡起來,然後修改所有對這些符號的引用,使得他們執行這個儲存位置,從而重定位這些節。

b.  動態鏈結

動態鏈結方式下,函式的定義在動態鏈結庫或共享物件的目標檔案中。在編譯的鏈結階段,動態鏈結庫只提供符號表和其他少量資訊用於保證所有符號引用都有定義,保證編譯順利通過。動態鏈結器鏈結程式在執行過程中根據記錄的共享物件的符號定義來動態載入共享庫,然後完成重定位。在此可執行檔案被執行時,動態鏈結庫的全部內容將被對映到執行時相應程序的虛位址空間。動態鏈結程式將根據可執行程式中記錄的資訊找到相應的函式**。  

目標檔案有三種形式:

1> 可重定位的目標檔案:

包含二進位制**和資料,其形式可以再編譯時與其他可定位目標檔案合併起來,建立乙個可執行目標檔案。

2> 可執行目標檔案:

包含二進位制**和資料,其形式可以被直接拷貝到儲存器並執行。

3> 共享目標檔案:

一種特殊的可重定位目標檔案,可以再載入或執行時,被動態地夾在到儲存器並執行。編譯器和彙編器生成可重定位目標檔案(包括共享目標檔案),鏈結器生成可執行目標檔案。

gcc優化的方式:

1.  -o0:無優化(預設)。

2.  -o1:使用能減少目標檔案大小以及執行時間並且不會使編譯時間明顯增加的優化.在編譯大型程式的時候會顯著增加編譯時記憶體的使用。

3.  -o2: 包含-o1的優化並增加了不需要在目標檔案大小和執行速度上進行折衷的優化.編譯器不執行迴圈展開以及函式內聯.此選項將增加編譯時間和目標檔案的執行效能。(一般優化到-o2就可以了)

4.  -os:專門優化目標檔案大小,執行所有的不增加目標檔案大小的-o2優化選項.並且執行專門減小目標檔案大小的優化選項。

5.  -o3: 開啟所有-o2的優化選項並且增加 -finline-functions, -funswitch-loops,-fpredictive-commoning, -fgcse-after-reload and -ftree-vectorize優化選項。

2019.07.17

對於執行過程中的檔案資訊讀取,可以使用file 檔名、binutils的objdump -h 檔名 檢視檔案,對於elf檔案還可以用readelf -a 檔名 檢視。

程式中執行其他可執行檔案

例如 system del c jk.txt system 函式中可以直接執行dos命令,執行相應操作。ex winexec notepad.exe c autoexec.bat sw show 執行 notepad.exe 開啟目錄下批處理檔案,並正常顯示 ex winexec notepad.e...

程式從原始碼到可執行檔案

cmake和make ide編輯器 是用於編寫源程式的軟體,通過編輯器來編寫源程式檔案。原始檔有特定的格式,由檔案的字尾名來區分,字尾取決於使用的程式語言,如c語言編寫的是c程式檔案,其原始檔以.c為字尾 c 語言編寫的程式原始檔則以.cpp為字尾。更多時候,編輯器是面向程式設計師的,程式編輯器和普...

C原始檔到可執行檔案的過程

一 c原始檔到可執行檔案共經歷了4個過程。在使用gcc編譯程式時,編譯過程可以被細分為四個階段,包括預處理 編譯 彙編 鏈結。1 預處理 在預處理階段,編譯器主要作載入標頭檔案 巨集替換 條件編譯的作用。一般處理帶 的語句。我們可以通過gcc 的 e 選項進行檢視,如下所示 root localho...