編譯程式的工作過程
編譯程式的結構
編譯器的自舉和移植
高階語言轉換為可執行語言的過程(以gcc編譯器為例).原始檔為hello.c
步驟一:預處理。將原始檔hello.c預處理成hello.i。該步是將#include中包含的標頭檔案匯入到原始檔中。命令是gcc -e hello.c
步驟二:編譯。將預處理後的hello.i檔案編譯成hello.s檔案。該步是將高階語言轉換為組合語言。命令是gcc -s hello.i步驟二為編譯原理的過程
步驟三:彙編。將編譯後的hello.s檔案會變成hello.o檔案。該步是將組合語言轉換成二進位制檔案。命令是gcc -c hello.s
步驟四:鏈結。將彙編後的hello.c檔案鏈結為hello.exe檔案,該步是將二進位制檔案裝入動態庫如編譯器自帶的print函式等。命令是gcc hello.o
而編譯程式是等價地將高階語言程式轉換為低階語言程式(如組合語言或機器語言程式)的程式。即對應上述的步驟二編譯過程
編譯程式分為診斷編譯程式,優化編譯程式,交叉編譯程式,可變目標編譯程式四類
1.診斷編譯程式:其作用是發現程式的錯誤,進行除錯解釋程式是將源程式作為輸入,邊解釋邊執行,不會產生完整的目標程式。而編譯程式會先進行編譯,產生乙個目標程式,然後執行該目標程式從而得到結果。2.優化編譯程式:其作用是提高目標**的程式效率
3.交叉編譯程式:編譯程式產生不同於宿主機(執行源程式的機器)的機器目標**(目標機),則稱為交叉編譯程式
4.可變目標編譯程式:僅編譯和目標機器有關的部分的程式
解釋程式的過程示意圖:
優點:可移植性較好,只要有解釋環境,可在不同的作業系統上執行。
缺點:執行需要解釋環境,執行起來比編譯慢,占用資源也要多一些,**效率低,**修改後就可執行,不需要編譯過程。
編譯程式的過程示意圖:
優點:執行速度快,**效率高,編譯後的程式不可修改,保密性較好。
缺點:**需要經過編譯才能執行,可移植性差,只能在相容的作業系統上執行。
程式編譯共經過5個階段
第一階段:詞法分析
根據構詞規則,對輸入程式的字串進行掃瞄和分解,識別出單詞字元。利用有限自動機法描述
第二階段:語法分析
在詞法分析的基礎上,根據語法規則將單詞符號串分解成各類語法單位、用上下文無關文法描述
第三階段:中間**產生
對各類語法單詞按照語義進行翻譯。該階段需要進行靜態語義檢查,用屬性文法描述。不會產生目標**
第四階段:優化
根據程式的等價變換規則對中間**進行加工變換,以便在最後階段產生更高效的目標**
第五階段:目標**產生
依賴於硬體系統和機器指令的含義把中間**變換成特定機器上的目標**,目標**分為3類
彙編指令**:需要彙編器將彙編**(move,add等語言)翻譯成機器指令(01字串)才能執行編譯程式的結構與編譯程式的5個過程相對應,絕對指令**:是機器語言程式,可以直接執行,指令的位址是絕對位址
可重定位指令**:位址是相對位址,能從記憶體的任何位置進行裝載。支援模組化的軟體開發。需要通過鏈結程式進行裝配,將相對位址替換成絕對位址,從而變成可執行檔案才能執行
1.詞法分析器
2.語法分析器
3.語義分析於中間**生成器
4.優化段
5.目標**生成器
6.符號表管理和出錯處理,此結構與每個階段都有聯絡
出錯處理:即使用的編譯器能夠發現源程式中的錯誤,將其傳送給程式設計師,包括兩類錯誤,語法錯誤和語義錯誤:
1.語法錯誤:源程式中不符合語法(或詞法)規則的錯誤,如非法字元,括號不匹配等
2.語義錯誤:源程式中不符合語義規則的錯誤,如變數宣告錯誤,作用域錯誤,型別不一致等
其結構圖如下:
由於詞法分析,語法分析與中間**產生與目標機器無關,因此可以以中間**為例,將編譯過程分解為編譯前端和編譯後端(能夠使程式更加清晰,優化更加充分,提高程式的可移植性):
編譯前端的工作是源程式通過詞法編譯器、語法編譯器、中間**產生以及與機器無關優化的處理,實現從源語言到中間語言的轉換編譯過程可用表示t-diagram圖表示,通過i**將s語言轉換成能夠在t機器上執行的檔案:編譯後端則是與機器有關的優化以及目標**的產生,實現中間語言到目標**的轉換
方式一:通過已有的高階語言去編寫新的高階語言的程式
在a機器上有乙個能夠將l語言翻譯成a機器的機器**的p1**,那麼可以用l語言去編寫乙個程式pa(該程式的目的是實現p語言到a機器的編譯),從而使得高階語言p可以在a機器上執行。
編譯示意圖過程如下:
用h編譯器實現i語言到k語言的轉換,在此基礎上,用i語言編寫乙個編譯器i,實現從s語言到t語言的轉換,借助h編譯器,可以將i編譯器先轉換為基於k語言的編譯器,實現s到t語言基於k編譯器的轉換,類似於cpython編譯器的原理
方式二:通過自編譯方式,通過不斷的對編譯器進行功能的增加,從而達到乙個符合所有條件的最終編譯器
自舉就是用該機器a的低階語言去編寫乙個簡單的微型編譯器a1,然後在該微型編譯器的基礎上增加更多功能,形成具有更多功能的編譯器a2,用a2去進行編譯得到最終需要的編譯器,這便是編譯器的自舉
還是需要用m語言寫乙個具有很小功能的s編譯器,然後用其去編譯加入了更多功能的編譯器,然後用編譯出來的更多功能的編譯器去編譯,這樣就得到了最終需要的編譯器,這便是自舉。過程示意圖如下:
編譯程式的移植,其目的是解決高階語言的跨平台性,使同一種語言能夠在不同的機器上執行:
移植的關鍵在於產生交叉編譯器
已知有乙個m編譯器,可以在m機器上編譯s語言,因此,可用s語言去編寫乙個編譯器s,在k機器上能夠對s語言進行編譯,又因為s語言可用m語言編譯,因此將s編譯器用m編譯器進行編譯得到m程式,實現s語言在k機器上的編譯過程,此時m便是交叉編譯器,得到交叉編譯器之後,便可以編譯在k機器上的s編譯器了,將編譯器s編譯成k語言的編譯器k,便可以得到在k機器上執行的k編譯器了,如圖所示:
編譯原理概述
一 編譯過程分析 編譯軟體讀取源程式 字元流 對之進行詞法和語法的分析,將高階語言指令轉換為功能等效的彙編 再由匯程式設計序轉換為機器語言,並按照作業系統對可執行檔案格式的要求鏈結生成可執行程式.二 編譯流程表 c源程式 c檔案 編輯器 預處理過程 c檔案 編譯 優化過程 s或.asm檔案 編譯器 ...
編譯原理概述
計算機不能直接理解 高階語言 只能直接理解 機器語言 所以必須要把高階語言 翻譯 成機器語言,計算機才能執行高階語言編寫的程式。我們可以粗略地把程式語言分為兩類 編譯型語言 和解釋型語言 常用的c c pascal和最近流行的go語言都是編譯型語言,而python ruby等則是解釋型語言,解釋型語...
編譯原理 編譯過程概述
編譯程式即是將高階語言書寫的源程式翻譯成與之等價的目標程式 組合語言或機器語言 其工作可分為六個階段,見下圖 對於編譯的各個階段,邏輯上可以劃分為前端和後端兩部分。前端包括詞法分析到中間 生成中各個階段的工作,後端則是優化及目標 生成的階段。以中間 為分水嶺的原因是把編譯過程分解為與機器有關和無關兩...