[C++]HelloWorld背後的故事!總結一下在我們執行exe可執行檔案前究竟發生了什麼!
阿新 • • 發佈:2020-03-27
人物介紹
姓名 |
HelloWorld |
---|---|
性別 |
.cpp |
住址 |
D:\ |
身份證號(SHA1) |
25106D2879A9EA300BB264F8155A71D7C44DA2E8 |
故事簡介
- 編寫原始檔
- 預編譯
- 編譯
- 彙編
- 連結
一、編寫原始檔
原始碼:
#include <iostream>
using namespace std;
int main()
{
cout << "Hello World!" << endl;
return 0;
}
二、預編譯
預編譯輸入命令g++ -o HelloWorld.i -E HelloWorld.cpp
該命令表示編譯環節的第一步,也就是預編譯!當然,這一步也可以被稱為“編譯預處理”!而這個 HelloWorld.i 即是預編譯過後的檔案!
序號 | 主要行為 |
---|---|
1. | 展開所有的巨集定義,消除“#define” |
2. | 處理所有的預編譯指令,比如#if、#ifdef等 |
3. | 處理#include預編譯指令,將包含檔案插入到該預編譯的位置 |
4. | 刪除所有的註釋“/**/”、"//"等 |
5. | 新增行號和檔名標識,以便於編譯時編譯器產生除錯用的行號資訊以及錯誤提醒 |
6. | 保留所有的#program編譯指令,原因是編譯器要使用它們 |
值得注意:這一步不會做出任何安全性和合法性的檢查!
三、編譯
編譯請輸入命令g++ -o HelloWorld.s -S HelloWorld.i
該命令表示編譯過程,也就是生成相應的彙編檔案 HelloWorld.s 。
主要行為 | 具體描述 |
---|---|
詞法分析 |
將原始碼檔案的字元序列劃分為一系列的記號,一般詞法分析產生的記號有:識別符號、關鍵字、數字、字串、特殊符號(加號、等號);在識別記號的同時也將識別符號放好符號表、將數字、字元放入到文字表等;有一個lex程式可以實現詞法掃描,會按照之前定義好的詞法規則將輸入的字串分割成記號,所以編譯器不需要獨立的詞法掃描器 |
語法分析 |
語法分析器將對產生的記號進行語法分析,產生語法樹----就是以表示式尾節點的樹,一步步判斷如何執行表示式操作;如果存在括號不匹配或者表示式錯誤,編譯器就會報告語法分析階段的錯誤;相同的存在一個yacc程式可以根據使用者輸入的語法規則生成語法樹; |
語義分析 |
由語法階段完成分析的並沒有賦予表示式或者其他實際的意義,比如乘法、加法、減法,必須經過語義階段才能賦予其真正的意義; |
程式碼優化 |
將程式碼進行優化處理 |
符號彙總 |
彙總所有符號 |
補充說明:其中語義分析又可以分為“靜態語義分析”和“動態語義分析”兩種。
語義分析 | 簡單說明 |
---|---|
靜態語義分析 | 通常在編譯器就可以確定的語義,主要包括“宣告”、“型別的匹配”以及“型別的轉換” |
動態語義分析 | 只能在執行期才能確定的語義 |
四、彙編
彙編請輸入命令g++ -o HelloWorld.o -C HelloWorld.s
該命令表示對 HelloWorld.s 檔案進行彙編處理,生成對應的可重定位的二進位制檔案 HelloWorld.o ,也就是我們所熟知的機器語言對應的檔案。
五、連結
連結請輸入命令g++ HelloWorld.cpp -o HelloWorld.exe
通過呼叫連結器ld來連結程式執行需要的一大堆目標檔案,以及所依賴的其它庫檔案,最後生成可執行檔案., 連結的主要內容是把各個模組之間相互引用的部分處理好,使得各個模組之間能夠正確地銜接。
需要指出:連結分為“靜態連結”和“動態連結”。
連結型別 | 具體說明 |
---|---|
靜態連結 | 指在編譯階段直接把靜態庫加入到可執行檔案中去,這樣可執行檔案會比較大 |
動態連結 | 指連結階段僅僅只加入一些描述資訊,而程式執行時再從系統中把相應動態庫載入到記憶體中去 |
需要補充:
庫檔案型別 | 特點 |
---|---|
靜態庫檔案 | 是一個二進位制檔案,存放的功能函式實現,在檔案編譯時要訪問檔案,編譯之後靜態庫檔案可以刪除 |
動態庫檔案 | 是一個二進位制檔案,存放的功能函式實現,在檔案執行時要訪問檔案,編譯時不需要動態庫檔案 |
額外說明:
作業系統 | 動態庫檔案字尾名 |
---|---|
linux | .so |
window | .dll |
相簿
預編譯後的檔案HelloWorld.i
可以看到,程式碼量驚人的大!足足有兩萬多行!可想這個HelloWorld也不簡單啊!
編譯後的檔案HelloWorld.s
很明顯看出,此時程式碼精簡了很多!
彙編後的檔案HelloWorld.o
可以看出,記事本已經顯示亂碼了!
幫忙的朋友
工具 | 作用 | 負責過程 |
---|---|---|
編輯器 | 編寫程式碼的一些視窗 | 編寫原始碼 |
編譯器 | 檢查使用者程式碼的一些語法錯誤,將其編譯成彙編程式碼 | 預編譯、編譯 |
彙編器 | 將編譯出來的彙編檔案編譯成一定功能的目的碼 | 彙編 |
聯結器 | 將目的碼連線成可執行檔案 | 連結 |
原創說明
原文作者:Seaver(海之戀SF)
如要轉載,請務必註明出處!
原文連結:https://www.cnblogs.com/seafever/p/12577337.h