iT邦幫忙

2023 iThome 鐵人賽

DAY 1
0

踏上冒險之旅的第一步,我個人的習慣是:先打開地圖看一看。

記得小時候在系統程式課上拿到的 C/C++ 編譯地圖大概長這樣:
https://ithelp.ithome.com.tw/upload/images/20230918/20161947UnbKb6U7hE.jpg

從源代碼(Source Code) 到可執行檔 (Executable File) 或庫文件 (Library) 中間的路上,首先會遇到編譯器 (Compiler) 將源代碼編譯成組合語言 (Assembler Language),再由組譯器 (Assembler) 組譯成目標檔案 (Object File),接著由連結器 (Linker) 將多個目標檔案 (Object File) 連結 (Link) 成可執行檔 (Executable File) 或庫文件 (Library)。

雖然目前的編譯器大部分都可以直接將源代碼編譯成目的檔,將中間編譯成組合語言的步驟隱藏起來不讓使用者察覺,但這邊還是將整條路徑攤開來看。

接著來介紹一下這一路上會遇到的叔叔阿姨伯伯三叔公們:

  • 源代碼 (Source Code)

    就是你寫的C/C++程式檔案,包含標頭文件 (Header File, .h, .hpp) 與 源碼文件 (Source File, .c, .cpp)。

    • Header File 通常包含了函數 (Function)、類別 (Class) 的聲明、常量 (Constant)定義和結構 (Structure) 的聲明等。它們定義了程式介面 (API, Application Programming Interface) 和結構,允許其他 Source File 訪問這些 API,並在其程式碼中使用相關的函數和數值。
    • Source File 包含了實際的 C/C++ 程式碼實作,它們實現了標頭文件中聲明的函數、類別的成員函數等。Source File 通常包含了程式的主要邏輯。
    • Source File 包含實際的程式碼實現,而Header File 包含 API 聲明,這樣在不同的源文件中可以重複使用和共享這些API。當要編譯 C/C++ 程式時,通常需要將多個Source File(.c, .cpp)一起編譯,並將它們與相應的Header File (.h, .hpp) 一起連接 (Link) 以生成最終的可執行文件 (Executable File)。
  • 編譯器 (Compiler)

    就是用於將 C/C++ 程式語言編譯成組合語言或目的檔的工具。

    • 它的主要功能包括語法檢查、程式碼優化和轉譯,將人類可讀的程式碼轉換為計算機能理解的形式。
  • 組合語言 (Assembler Language)

    組合語言 (Assembler Language, .asm) 是一種低階程式語言,夾在高階語言 (例如: C/C++) 和機器語言之間的角色。

    • 其語法更貼近對硬體的直接操作,並且會因為不同的目標平台的硬體架構而略有不同,像是有些 CPU 使用的指令集為 前置式表示法 ,也就是目標在前的指令撰寫方式 ,其對於這行指令 ADD R1, R2, R3 的解讀就是 將暫存器2的數值與暫存器3的數值相加並把結果放到暫存器1 ,若為 後置式表示法 ,也就是目標在後的指令撰寫方式,其對於那行指令的解讀就是 將暫存器1的數值與暫存器2的數值相加並把結果放到暫存器3
    • 組合語言使用可讀的助記符(mnemonics)和符號,代表特定的機器指令和操作碼,讓工程師更容易理解和編寫與硬體直接交互的程式碼,如驅動程序和嵌入式系統軟體。
    • 它提供了更高級別的抽象,同時允許直接訪問計算機的內部結構和資源,因此通常用於系統編程和性能關鍵的應用,以實現更精細的控制和效能優化。
  • 組譯器 (Assembler)

    就是負責對組合語言做組譯的工具,其主要的功能,是將組合語言轉換為目的檔 (就是機器碼,是二進制碼組成的,a.k.a 一堆由0101 組成的東西) 的工具。

    • 組譯這個步驟負責將可讀的組合語言程式碼轉譯成計算機能理解的形式。
    • 執行語法檢查、符號解析和指令生成,以確保輸出的機器代碼與原始組合語言代碼等效。
  • 目的檔 (Object File)

    就是編譯過程中生成的中間檔案,是二進制文件,包含了源代碼編譯後的機器代碼、符號表、段信息等資訊。

    • 它還包含了未解析的符號引用,這些引用在連接(Linking)階段將被解析為最終的可執行文件或庫文件。
  • 連結器 (Linker)

    就是用來連接目的檔與靜態庫的工具。

    • 它可以將許多目的檔連結成一個可執行檔,或是像庫文件這樣的半成品。
    • 連結器會解析符號引用,解決跨文件的函數和變數引用,並生成可執行文件。
  • 可執行檔 (Executable File)

    就是最終可以直接執行的程式檔案。

    • 是一種二進制文件,包含了電腦上運行的程式的機器碼表示形式。
  • 庫文件 (Library)

    就是包含已經編譯過的、可重用的程式碼和資源的二進制文件集合,用於軟體開發中的模組化和代碼重用。

    • 庫文件可以包括函數、類、數據結構、常量等,開發者可以在不同的項目中引用它們,以節省時間和資源。
    • 庫文件有兩種主要類型:動態庫 (Dynamic Library, a.k.a 共享庫 shared library) 和靜態庫 (Static Library)。
    • 動態庫在運行時加載,可以共享給多個應用程序,而靜態庫在編譯時連接到應用程序,使其成為可執行文件的一部分。

以上就是編譯的路上會遇到的角色介紹,下篇會以 Linux 與 Windows 系統為例,進一步指出上述的角色們的在此兩種系統中實際上是哪些東西,揭開他們的真面目!


上一篇
[Day01] 旅途前的準備:一個人上路太危險了,帶上這個吧!
系列文
駕馭編譯舞台:C/C++程式編譯、Makefile與CMake大冒險!2
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言