初識編譯器
我們通常所說的編譯器是一個廣義的概念,其實編譯器是有幾個子產品組成的,具體如下:
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiI9s2RkBnVHFmb1clWvB3MaVnRtp1XlBXe0xCM581dvRWYoNHLwEzX5xCMx8FesU2cfdGLwATMfRHLGZkRGZkRfJ3bs92YskmNhVTYykVNQJVMRhXVEF1X0hXZ0xiNx8VZ6l2cssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnL2kjM2gDN2QjM2UjN3ITNx8CXwMTNwgTMwIzLcNXZnFWbp9CXvwVbvNmLvR3YxUjL0M3Lc9CX6MHc0RHaiojIsJye.png)
從上圖可知編譯器由4部分組成;
每當我們在內建開發環境下寫完代碼,點選build的時候 編譯器的工作原理如下:
可以看到,編譯代碼的過程其實就是編譯器讓這些子產品協同工作的過程。
第一步:預處理器将.c和.h檔案編譯器.i中間檔案。
第二步:.i中間檔案被編譯器進行文法,語義分析,生成.s彙編檔案。
第三步:.s檔案經過彙編器編譯成.o二進制檔案。
編譯器做了什麼
1.預編譯(文本處理工作)
-處理所有注釋,以空格代替
-将所有的#define删除,并且展開所有的宏定義
-處理條件編譯指令#if,#ifdef,#elif,#else,#endif
-處理#include,展開被包含的檔案
-保留編譯器需要使用的#pragma指令
預處理指令示例:
gcc -E file.c -o file.i
-o:指定生成的輸出檔案;
-E:僅執行編譯預處理;
-S:将C代碼轉換為彙編代碼;
-wall:顯示警告資訊;
源代碼的單步編譯示例:
打開預編譯器處理過後的19-1.i檔案可以看到 裡面的注釋和#define都沒有了,預編譯器将#define的内容進行文本替換,并且19-1.h裡面的内容也被加載進來了
當預編譯器處理完成之後 ,真正意義上的額編譯器就出場了
2.編譯
-對預處理檔案進行詞法分析,文法分析和語義分析
.詞法分析:分析關鍵字,辨別符,立即數等是否合法
.文法分析:分析表達式是否遵循文法規則
.語義分析:在文法分析的基礎上進一步分析表達式是否合法
-分析結束後進行代碼優化生成相應的彙編代碼檔案
編譯指令示例:
gcc -S file.i -o file.s
編譯器将源程式編譯成彙編代碼
彙編
-彙編器将彙編代碼轉變為機器的可執行指令
-每條彙編語句幾乎都對應一條機器指令
彙編指令示例:
gcc -c file.s -o file.o