一,預編譯
操作步驟: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個步驟後,我們獲得目标代碼,但是裡面的各個位址還沒有确定,空間還沒有配置設定。
連結過程主要包括:位址和空間的配置設定,符号決議和重定位。