[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.i

  可以看到,代碼量驚人的大!足足有兩萬多行!可想這個HelloWorld也不簡單啊!

編譯后的文件HelloWorld.s

HelloWorld.s

  很明顯看出,此時代碼精簡了很多!

匯編后的文件HelloWorld.o

HelloWorld.o

  可以看出,記事本已經顯示亂碼了!

幫忙的朋友

工具 作用 負責過程
編輯器 編寫代碼的一些窗口 編寫源代碼
編譯器 檢查用戶代碼的一些語法錯誤,將其編譯成匯編代碼 預編譯、編譯
匯編器 將編譯出來的匯編文件編譯成一定功能的目標代碼 匯編
連接器 將目標代碼連接成可執行文件 鏈接

原創說明

原文作者:Seaver(海之戀SF)
如要轉載,請務必注明出處!
原文鏈接:https://www.cnblogs.com/seafever/p/12577337.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM