1. 程式人生 > >[C++]HelloWorld背後的故事!總結一下在我們執行exe可執行檔案前究竟發生了什麼!

[C++]HelloWorld背後的故事!總結一下在我們執行exe可執行檔案前究竟發生了什麼!

人物介紹

姓名 HelloWorld
性別 .cpp
住址 D:\
身份證號(SHA1) 25106D2879A9EA300BB264F8155A71D7C44DA2E8

故事簡介

  1. 編寫原始檔
  2. 預編譯
  3. 編譯
  4. 彙編
  5. 連結

一、編寫原始檔

  原始碼:

#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