【C语言】源代码的编译过程
一、引言
我們平常編寫C語言程序都是使用集成開發環境(IDE),這樣的IDE通常是將編譯和鏈接過程合并成一步完成,稱為構建(Build)。這樣對開發者雖然比較友好,但同時由于集成開發環境運行時掩蓋了程序運行機制與機理,導致基礎開發者并不知道從C源代碼到二進制可執行文件生成中間到底經歷哪些過程呢?接下來就來探索一下其中各個過程具體做了哪些工作。
二、C源代碼的編譯過程
c程序的基本編譯過程具體如下圖1和圖2所示:
源代碼.c文件和相關頭文件被預編譯器預編譯成一個.i文件;
對于C++程序而言,一般是.cpp文件和頭文件,預編譯成.ii文件
預處理相當于根據預處理指令組裝新的C/C++程序。經過預處理,會產生一個沒有宏定義,沒有條件編譯指令,沒有特殊符號的輸出文件,這個文件的含義同原本的文件無異,只是內容上有所不同。
//gcc進行預編譯: gcc -E hello.c -o hello.i具體工作:
1.刪除所有“#define”,并展開所有宏定義(進行文本替換)
2.處理“#include”預編譯指令,遞歸展開被包含的文件并插入到該預編譯指令位置
3.處理“#if”、“#ifdef”、“#elif”、“endif”等條件編譯指令
4.刪除所有的注釋(“//”和“/* */”)
5.添加行號和文件名標識,以便編譯時編譯器產生調試用的行號信息及用于編譯時產生編譯錯誤或警告時能夠顯示行號
6.保留所有的“#program”指令,因為編譯器編譯時需要使用它們
- 編譯
將.i文件翻譯成匯編代碼.s文件(在windows中,通常使用.asm便是匯編文件)
具體工作:
1.詞法分析
(對構成源程序的字符串從左到右進行掃描分析,根據語言的詞法規則識別一個一個具有獨立意義的單詞,例如:保留字(begin、end、for、while等)、標識符、常數、運算符、界符等)
2.語法分析
(根據語言的語法規則,把單詞符號串分解成各類語法單位,如短語、子句、句子、程序段等,并檢查各種語法單位在語法結構上的正確性)
3.語義分析
(對每種語法單位進行靜態語義(靜態語義指程序在語義上要遵守的規則)審查,然后分析其含義,并用另一種語言形式來描述這種語義)
4.中間代碼生成及優化
5.生成匯編代碼文件(生成指令)
- 匯編
通過匯編器as將編譯完的匯編代碼文件翻譯成機器指令,并生成可重定位目標程序的.o文件,該文件為二進制文件,字節編碼是機器指令。
- 鏈接
通過鏈接器將一個個目標文件(或許還會有庫文件)鏈接在一起生成一個完整的可執行程序。
具體工作:
1.合并段和符號表
2.符號解析
3.分配地址和空間
4.符號重定義
- 執行
具體工作:
1.創建虛擬內存空間和物理內存(創建PCB)
2.加載指令和數據
3.將入口地址寫入下一條指令寄存器
三、編譯程序、翻譯程序、匯編程序、解釋程序的辨析
-
翻譯程序
將用匯編語言或高級語言編寫的程序轉換成等價的機器語言程序,執行這種轉換功能的程序統稱為翻譯程序 -
匯編程序
源程序為匯編語言,目標程序為機器語言的翻譯程序 -
編譯程序
源程序為高級語言編寫的程序,目標程序為匯編語言或機器語言的翻譯程序 -
解釋程序
接受某個語言的程序并立即運行這個源程序。它的工作模式是一個個的獲取、分析并執行源程序語句,一旦第一個語句分析結束,源程序便開始運行并且產生結果,它特別適合程序員以交互方式工作的情況,即希望在獲取下一個語句之前了解每個語句的執行結果,允許執行時修改程序。
編譯方式和解釋方式實現高級語言的編譯的區別:
在解釋方式下,并不生成目標代碼程序,而是直接執行源程序本身
總結
以上是生活随笔為你收集整理的【C语言】源代码的编译过程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: html 各种字符 换位键,excel替
- 下一篇: 如何自动执行Excel的多次替换--Ex