代碼到可執行文件中間經歷的過程

大致過程可分爲以下4個步驟:

預處理->編譯->彙編->鏈接

一、預處理

處理源代碼文件以“#”開始的預編譯指令。

1)展開宏定義

2)處理所有條件編譯指令

3)處理#include預編譯指令,遞歸地將被包含的文件插入進來

4)刪除註釋

5)添加行號和文件名標識,這樣編譯器產生錯誤和警告時才能顯示行號

6)保留#pragma編譯器指令

最終生成.i文件(c語言),或者.ii文件(C++語言)。

二、編譯

1)掃描,將源代碼輸入到掃描器。

1)詞法分析,將源代碼的字符序列分割成一個個記號:關鍵字、標識符、字面量、特殊符號,如“(”是一個記號,變量i是一個記號。詞法掃描工具:lex

2)語法分析,生成一棵結點爲表達式的語法樹,同時檢查表達式是否合法,如括號不匹配、缺少操作符在這步可以檢查出來。語法分析工具:yacc

3)語義分析,檢查表達式是否有意義,如類型匹配、除0。爲語法樹中的所有結點標上類型。

4)源代碼優化,如2 * 5,在這個期間就可以被確定,直接用10替換該表達式。在該步會將語法樹生成中間代碼(不包含數據的大小、變量地址、寄存器名字)。

5)目標代碼生成,將中間代碼生成目標機器代碼。中間代碼跟機器無關,目標機器代碼跟機器有關,會標出字長、寄存器名字等。

6)目標代碼優化,用位移代替乘法、刪除多餘的指令等。

最終會生成彙編代碼文件。

三、彙編

將匯率代碼轉變爲機器可以執行的指令。僅簡單根據彙編指令和機器指令的對照表一一翻譯,不做指令優化。

彙編器工具:as

四、鏈接

鏈接主要是處理各個模塊相互引用的部分,使得它們能正確銜接。比如A模塊引用了B模塊的某個函數、C模塊的某個全局變量等。

1)地址和空間分配

2)符號決議(也叫地址綁定)

3)重定位。有些全局變量或函數定義在其它庫中,重定位找到它們的地址。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章