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

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

人物介紹 | | 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


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

-Advertisement-
Play Games
更多相關文章
  • 首先保證路徑正確,引入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 ...
一周排行
    -Advertisement-
    Play Games
  • Dapr Outbox 是1.12中的功能。 本文只介紹Dapr Outbox 執行流程,Dapr Outbox基本用法請閱讀官方文檔 。本文中appID=order-processor,topic=orders 本文前提知識:熟悉Dapr狀態管理、Dapr發佈訂閱和Outbox 模式。 Outbo ...
  • 引言 在前幾章我們深度講解了單元測試和集成測試的基礎知識,這一章我們來講解一下代碼覆蓋率,代碼覆蓋率是單元測試運行的度量值,覆蓋率通常以百分比表示,用於衡量代碼被測試覆蓋的程度,幫助開發人員評估測試用例的質量和代碼的健壯性。常見的覆蓋率包括語句覆蓋率(Line Coverage)、分支覆蓋率(Bra ...
  • 前言 本文介紹瞭如何使用S7.NET庫實現對西門子PLC DB塊數據的讀寫,記錄了使用電腦模擬,模擬PLC,自至完成測試的詳細流程,並重點介紹了在這個過程中的易錯點,供參考。 用到的軟體: 1.Windows環境下鏈路層網路訪問的行業標準工具(WinPcap_4_1_3.exe)下載鏈接:http ...
  • 從依賴倒置原則(Dependency Inversion Principle, DIP)到控制反轉(Inversion of Control, IoC)再到依賴註入(Dependency Injection, DI)的演進過程,我們可以理解為一種逐步抽象和解耦的設計思想。這種思想在C#等面向對象的編 ...
  • 關於Python中的私有屬性和私有方法 Python對於類的成員沒有嚴格的訪問控制限制,這與其他面相對對象語言有區別。關於私有屬性和私有方法,有如下要點: 1、通常我們約定,兩個下劃線開頭的屬性是私有的(private)。其他為公共的(public); 2、類內部可以訪問私有屬性(方法); 3、類外 ...
  • C++ 訪問說明符 訪問說明符是 C++ 中控制類成員(屬性和方法)可訪問性的關鍵字。它們用於封裝類數據並保護其免受意外修改或濫用。 三種訪問說明符: public:允許從類外部的任何地方訪問成員。 private:僅允許在類內部訪問成員。 protected:允許在類內部及其派生類中訪問成員。 示 ...
  • 寫這個隨筆說一下C++的static_cast和dynamic_cast用在子類與父類的指針轉換時的一些事宜。首先,【static_cast,dynamic_cast】【父類指針,子類指針】,兩兩一組,共有4種組合:用 static_cast 父類轉子類、用 static_cast 子類轉父類、使用 ...
  • /******************************************************************************************************** * * * 設計雙向鏈表的介面 * * * * Copyright (c) 2023-2 ...
  • 相信接觸過spring做開發的小伙伴們一定使用過@ComponentScan註解 @ComponentScan("com.wangm.lifecycle") public class AppConfig { } @ComponentScan指定basePackage,將包下的類按照一定規則註冊成Be ...
  • 操作系統 :CentOS 7.6_x64 opensips版本: 2.4.9 python版本:2.7.5 python作為腳本語言,使用起來很方便,查了下opensips的文檔,支持使用python腳本寫邏輯代碼。今天整理下CentOS7環境下opensips2.4.9的python模塊筆記及使用 ...