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

来源:https://www.cnblogs.com/seafever/archive/2020/03/27/12577337.html

人物介紹 | | HelloWorld | |: |: | | | .cpp | | | D:\ | | | 25106D2879A9EA300BB264F8155A71D7C44DA2E8 | 故事簡介 1. "編寫源文件" 2. "預編譯" 3. "編譯" 4. "彙編" 5. "鏈接" 一、編 ...


人物介紹

姓名 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


您的分享是我們最大的動力!

更多相關文章
  • 首先保證路徑正確,引入ttf字體,沒有生效 使用線上工具把ttf轉為更多常用的字體格式 網址:https://www.fontke.com/tool/convfont/ css里補全格式: 生效了 ...
  • 導讀 轉載自 "冪等性如何實現?深入瞭解一波!!!" 現在這個時代大家可能最關心的就是錢了,那麼有沒有想過你銀行轉賬給你沒有一次是轉多的,要麼失敗,要麼成功,為什麼不能失誤一下多轉一筆呢?醒醒吧年輕人,別做夢了,做銀行的能那麼傻x嗎? 今天我們就來談一談為什麼銀行轉賬不能多給我轉一筆?關乎到錢的問題 ...
  • 功能介紹:黑貓關鍵詞URL採集工具 Pro v1.0 批量關鍵詞自動搜索採集 自動去除垃圾二級泛解析功能變數名稱 可設置是否保存功能變數名稱或者url 聯繫客服QQ:944520563 ...
  • python線性數據結構 [TOC] 1 線性數據結構 本章要介紹的線性結構:list、tuple、string、bytes、bytearray。 線性表:是一種抽象的數學概念,是一組元素的序列的抽象,由有窮個元素組成(0個或任意個)。 線性表又可分為 順序表和鏈接表。 順序表:一組元素在記憶體中有序 ...
  • JAVA學習之ClassLoader 前言 最近被 一句話所觸動—— 種一棵樹最好的時間是十年前,其次是現在。 所以決定要開始記錄自己的學習之路。 什麼是類載入? 我們都知道,每個.java文件可以經過javac指令編譯成.class文件,裡面包含著java虛擬機的機器指令。當我們需要使用一個jav ...
  • 記錄,VBScript 如何打開,含有"空格"的路徑。這個問題和常見,卻總是忘! 直接上代碼了,多說無益。 這就是,解決方法! 就是在 path 兩邊個加上, 3層雙引號! 如果直接運行 ,代碼會報錯,或者根本打不開, 因為,代碼不知為何,打開的是,空格之間的那段路徑, 所以,會顯示找不到路徑! 這 ...
  • 一、多線程 1.基本概念: (1)進程:一個進程對應一個應用程式。例如:在windows中啟動Word就表示啟動了一個進程。在java的開發環境中啟動JVM,就表示啟動了一個進程。現在電腦是支持多進程的,在同一個操作系統中,可以啟動多個進程。 (2)多進程的作用:多進程的作用不是提高執行速度,而是 ...
  • day2 pyCharm的debug模式使用,while迴圈結構,格式化輸出,運算符,編碼初識 pyCharm的debug模式 點擊需要調試(或者有問題的)行左側,出現小紅點,然後shift+f9,進入debug模式,下方有debuger和consloe(控制台)兩個tab,選擇console_ta ...
一周排行
  • 在上篇文章中我們已經知道了多線程是什麼了,那麼它到底可以幹嘛呢?這裡特別聲明一個前面的委托沒看的同學可以到上上上篇博文查看,因為多線程要經常使用到委托。源碼 一、非同步、同步 1.同步(在計算的理解總是要你措不及防,同步當線程做完一件事情之後,才會執行後續動作),同步方法慢,只有一個線程執行,非同步方法 ...
  • 本文主要是講解stopwatch對程式運行時間的準確測量 僅僅介紹裡面的StartNew()方法,Restart()方法和ElapsedMilliseconds { get;}屬性 public void StartNew():作用是對新的 System.Diagnostics.Stopwatch ...
  • 一、引言 RabbitMQ是Rabbit Message Queue的簡寫,但不能僅僅理解其為消息隊列,消息代理更合適。RabbitMQ是一個由 Erlang 語言開發的AMQP(高級消息隊列協議)的開源實現,其內部結構如下: RabbitMQ作為一個消息代理,主要和消息打交道,負責接收並轉發消息。 ...
  • TerminalMACS(Terminal Manager And Check System) 遠程終端管理和檢測系統 本文同步更新地址:https://dotnet9.com/11429.html 一、本系統可監控多種終端資源: 移動端 Android iOS PC端 Windows Linux ...
  • 首先,好消息是Goole將於2020年2月份發佈Chrome 80版本。本次發佈將推進Google的“漸進改良Cookie”策略,打造一個更為安全和保障用戶隱私的網路環境。 壞消息是,本次更新可能導致瀏覽器無法向服務端發送Cookie。如果你有多個不同功能變數名稱的應用,部分用戶很有可能出現會話時常被打斷的 ...
  • 在偶然一次調試某程式時,遇到提示: 無法載入程式集*****.XmlSerializers.dll,文件找不到(Could not load file or assembly ****.XmlSerializers.dll , FileNotFoundException...)。於是嘗試在項目屬性中 ...
  • 在上一篇abp(net core)+easyui+efcore實現倉儲管理系統——入庫管理之五(四十一) 文章中實現了入庫管理的列表頁面,並實現了控制器的代碼。在今天我們學習如何在前端實現新增入庫單信息界面。 ...
  • 面向對象 面向對象是一個抽象的概念,其本質就是對事物以抽象的方式建立對應的模型。 簡單來講,比如我有一隻鋼筆,那麼我就可以通過分析,可以得到 這隻鋼筆的材第是塑料,品牌是個雜牌 ,裡面裝的墨是黑色的,可以用。這時候就能建立一個鋼筆的模型,它在這裡應該有這些屬性: 圖是一個不正確的UML類圖,但是可以 ...
  • 在ASP.NET MVC中有四種過濾器類型 Action 1、在ASP.NET MVC項目中,新建文件夾Filter,然後新建類MyCustormFilter,繼承自ActionFilterAttribute類,我們來看下ActionFilterAttribute類有如下四個方法,從命名我應該就可以 ...
  • 你需要瞭解的 HTTP Status Code Intro 現在前後端分離的開發模式越來越流行,後端負責開發對應的 API,前端只需要 關註前端頁面的數據展示和前端邏輯即可。 對於前後端分離這種開發模式,我個人還是比較喜歡的,因為這樣可以讓更專業的人做更專業的事情,後端專註於做 API 的開發設計, ...
x