1. 程式人生 > >Linux GCC生成可執行程式的4個步驟——預處理、編譯、彙編、連結

Linux GCC生成可執行程式的4個步驟——預處理、編譯、彙編、連結

一,預編譯

操作步驟:gcc -E hello.c -o hello.i

主要作用:

處理關於 “#” 的指令

【1】刪除#define,展開所有巨集定義。例#define portnumber 3333

【2】處理條件預編譯 #if, #ifdef, #if, #elif,#endif

【3】處理“#include”預編譯指令,將包含的“.h”檔案插入對應位置。這可是遞迴進行的,檔案內可能包含其他“.h”檔案。

【4】刪除所有註釋。/**/,//。

【5】新增行號和檔案識別符號。用於顯示除錯資訊:錯誤或警告的位置。

【6】保留#pragma編譯器指令。(1)設定編譯器狀態,(2)指示編譯器完成一些特定的動作。

二,編譯(編譯器主要做了什麼)

操作步驟:gcc -s hello.c -o hello.s

主要作用:1.掃描(詞法分析),2.語法分析,3.語義分析,4.原始碼優化(中間語言生成),5.程式碼生成,目的碼優化。

【1】將原始碼程式輸入掃描器,將原始碼的字元序列分割成一系列記號。例array[index] =  (index + 4) * (2 + 6);

【2】基於詞法分析得到的一系列記號,生成語法樹。

【3】由語義分析器完成,指示判斷是否合法,並不判斷對錯。又分靜態語義:隱含浮點型到整形的轉換,會報warning,

  動態語義:在執行時才能確定:例1除以3

【4】中間程式碼(語言)使得編譯器分為前端和後端,前端產生與機器(或環境)無關的中間程式碼,編譯器的後端將中間程式碼轉換為目標機器程式碼,目的:一個前端對多個後端,適應不同平臺。

【5】編譯器後端主要包括:程式碼生成器:依賴於目標機器,依賴目標機器的不同字長,暫存器,資料型別等

    目的碼優化器:選擇合適的定址方式,左移右移代替乘除,刪除多餘指令。

三,彙編

操作步驟:gcc -c hello.c -o hello.o

主要作用:彙編器是將彙編程式碼轉變成可以執行的指令,生成 目標檔案。

四,連結

操作步驟:gcc hello.o -o hello

主要作用:通過編譯器的5個步驟後,我們獲得目的碼,但是裡面的各個地址還沒有確定,空間還沒有分配。

連結過程主要包括:地址和空間的分配,符號決議和重定位。

地址和空間:略

符號決議:也可以說地址繫結,分動態連結和靜態連結,

重定位:假設此時又兩個檔案:A,B。A需要B中的某個函式mov的地址,未連結前將地址置為0,當A與B連結後修改目標地址,完成重定位。
--------------------- 
作者:huoyahuoya 
來源:CSDN 
原文:https://blog.csdn.net/huoyahuoya/article/details/53083424