[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 ...
一周排行
  • 背景 習慣使用markdown的人應該都知道Typora這個神器,它非常簡潔高效。雖然博客園的線上markdown編輯器也不錯,但畢竟是網頁版,每次寫東西需要登錄系統-進後臺-找到文章-編輯-保存草稿。。。非常難受。。。 但是使用Typora來寫的話,文章圖片又是個問題,本地寫完粘貼到網站上,圖片全 ...
  • 案例:修改預設線程個數 1.NameValueCollection System.Collections.Specialized.NameValueCollection collection = new System.Collections.Specialized.NameValueCollecti ...
  • // from https://stackoverflow.com/questions/35381238/how-to-use-custom-fonts-in-emgucv string text = "塗聚文(Geovin Du)"; // 下麵定義一個矩形區域 int rectWidth = t ...
  • 場景 ASP.NET中新建Web網站並部署到IIS上(詳細圖文教程): https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/107199747 前面講過將ASP.NET的項目部署到本機的IIS上。 但是如果將其部署到伺服器上Window ...
  • 在不同的區域中使用Convert.ToDouble可能會產生問題。 string str = "20.0"; double val = Convert.ToDouble(str); 比如在某些區域語言中得到的結果是200,如: Thread.CurrentThread.CurrentCulture ...
  • 1、前言 ​ 不知道你是否對.NET裡面的定時器產生過一些疑問,以下是武小棧個人的一些總結。 2、官方介紹 在.NET的框架之內定時器有四種,先看一下微軟官方對他們各自特點介紹: System.Timers.Timer,它將觸發事件,並定期在一個或多個事件接收器中執行代碼。 類旨在用作多線程環境中基 ...
  • 筆試考試系統需求分析 1. 引言 1.1編寫目的 項目需求分析目的是使用戶和軟體開發者雙方對項目開發目標有一個共同的理解,便於對軟體開發各個過程的控制與管理,通過對項目開發目標的描述,使開發人員能夠正確理解用戶需求,明確該系統應具有的功能。性能與界面要求。 需求分析作為項目開放的基礎和依據,其預期讀 ...
  • 使用Topshelf部署.net core windows服務 首先新建一個.net core的模板worker程式 過程 略 打開Program.cs namespace TopshelfDemo { public class Program { public static void Main(s ...
  • xaml裡面使用很簡單 xmlns:i="http://schemas.microsoft.com/xaml/behaviors" <i:Interaction.Behaviors> <i:MouseDragElementBehavior/> </i:Interaction.Behaviors> 後 ...
  • Application Insignhts是微軟開發的一套監控程式。他可以對線上的應用程式進行全方位的監控,比如監控每秒的請求數,失敗的請求,追蹤異常,對每個請求進行監控,從http的耗時,到SQL查詢的耗時,完完整整的被記錄下來。當對程式進行優化跟排錯時非常好使。它原來是visualstudio ...