1. 程式人生 > >程式的實現過程(編譯、連結、執行)

程式的實現過程(編譯、連結、執行)

在ANSI C的任何一種實現中,存在兩個不同的環境
  • 第1種是翻譯環境,在這個環境中原始碼被轉換為可執行的機器指令。
  • 第2種是執行環境,它用於實際執行程式碼。

標準明確說明:這兩種環境不必位於同一臺機器上。

例如,交叉編譯器就是在同一臺機器上執行,但它所產生的可執行程式碼運行於不同型別的機器上。作業系統也是這樣。

翻譯階段,程式實現過程如下圖:


翻譯階段的兩個步驟:

  1. 組成一個程式的每個原始檔(source code)通過編譯過程分別轉換成目的碼(object code)
  2. 每個目標檔案由
  3. 連結器(linker)捆綁在一起,形成一個單一而完整的可執行程式(executable)

注:連結器同時也會引入標準C函式庫中任何被該程式所用到的函式,並且它可以搜尋程式設計師個人的程式庫,將其需要的函式也連結到程式中。

而編譯本身也分為三個階段組成:

  1. 前處理器(preprocessor)處理--預編譯。在這個階段,前處理器在原始碼上執行一些文字操作。
  1. 原始碼經過解析,判斷它的語句的意思。這個階段產生絕大多數的錯誤和警告。
  2. 形成符號表,產生目的碼
下面截圖表示程式在翻譯階段的具體功能:
注: ①檔案字尾名*.i、*.s、*.o在類unix系統中,可通過gcc相關命令生成對應檔案。
②符號表:在電腦科學中,符號表是一種用於語言翻譯器(例如編譯器和直譯器)中的資料結構。在符號表中,程式原始碼中的每個識別符號都和它的宣告或使用資訊繫結在一起,比如其資料型別、作用域以及記憶體地址。符號表在編譯程式工作的過程中需要不斷收集、記錄和使用源程式中一些語法符號的型別和特徵等相關資訊。這些資訊一般以表格形式儲存於系統中。如常數表、變數名錶、陣列名錶、過程名錶、標號表等等,統稱為符號表。 程式執行的過程:
  1. 程式必須載入記憶體中(由馮曼依諾計算機體系決定)。在有作業系統的環境中:一般這個由作業系統完成。在獨立的環境中,程式的載入必須由手工安排,也可能是通過可執行程式碼置入只讀記憶體來完成。
  2.  程式的執行便開始。接著便呼叫main函式
  3. 開始執行程式程式碼。這個時候程式將使用一個執行時堆疊(stack),儲存函式的區域性變數和返回地址。程式同時也可以使用靜態(static)記憶體,儲存於靜態記憶體中的變數在程式的整個執行過程一直保留他們的值。
  4. 終止程式。正常終止main函式;也有可能是意外終止。
執行時和編譯時的本質:
  • 像標誌符(型別名、變數名、函式名等)、型別定義、const關鍵字、訪問限定符(public/private/protected)、引用(&)等只是存在於原始碼中,他們不會被帶入二進位制可執行程式中,這是“編譯時”的本質。
  • 存在於二進位制可執行程式中的只是指令、地址和資料,沒有別的東西(實際上地址也是資料的一種),這就是“執行時”的本質。
  • C/C++原始碼中的語句、指標和變數都將被轉化成二進位制程式中的指令、地址和資料。因此,通過名字直接引用一個變數、物件即其成員,這樣的程式碼在編譯和連結完成後,實際上都被轉換成了通過變數、物件或成員變數的地址(即記憶體元的地址)進行訪問。