編譯器

用手机看条目

出自 MBA智库百科(https://wiki.mbalib.com/)

編譯器(Compiler)

目錄

什麼是編譯器

  編譯器是指從高級語言到低級語言的翻譯器,同樣的技術可用於不同種類語言之間的翻譯。編譯器是一種電腦程式,它會將用某種編程語言寫成的源代碼(原始語言),轉換成另一種編程語言(目標語言)。

  它主要的目的是將便於人編寫,閱讀,維護的高級電腦語言所寫作的源代碼程式,翻譯為電腦能解讀、運行的低階機器語言的程式,也就是可執行文件。編譯器將原始程式(Source program)作為輸入,翻譯產生使用目標語言(Target language)的等價程式。源代碼一般為高階語言 (High-level language), 如 Pascal、C、C++、C# 、Java 等,而目標語言則是彙編語言或目標機器的目標代碼Object code),有時也稱作機器代碼(Machine code)。

  一個現代編譯器的主要工作流程如下: 源代碼 (source code) → 預處理器 (preprocessor) → 編譯器 (compiler) → 彙編程式 (assembler) → 目標代碼 (object code) → 鏈接器 (Linker) → 可執行文件 (executables)

編譯器的分類[1]

  典型的編譯器輸出是由包含人口點的名字和地址以及外部調用的機器代碼所組成的目標文件。一組目標文件,不必是同一編譯器產生,但使用的編譯器必須採用同樣的輸出格式,可以鏈接在一起並生成可以由用戶直接執行的可執行程式。

  在運行過程中,編譯器又可分成只依賴於源語言的編譯器前端和只依賴於目標語言的編譯器後端兩大部分,編譯器前後端結構如圖所示。

  Image:图编译器前后端示意图.jpg

  前端主要負責解析(parse)輸入的源程式,由詞法分析器和語法分析器協同工作。詞法分析器負責把源程式中的“單詞”(Token)找出來,語法分析器把這些分散的單詞按預先定義好的語法組裝成有意義的表達式、語句、函數等。例如“a=b+c”,前端詞法分析器看到的是“'a'='b'+'c'”,語法分析器按定義的語法,先把它們組裝成表達式“b+C”,再組裝成“a=b+c”的語句。前端還負責語義(semantic checking)的檢查,例如檢測參與運算的變數是否是同一類型的,簡單的錯誤處理。最終的結果常常是一個抽象的語法樹AST(Abstract Syntax Tree),這樣後端可以在此基礎上進一步優化處理。編譯器後端主要負責分析、優化中間代碼以及生成機器代碼。一般來說所有的編譯器分析、優化、變型都可以分成兩大類:函數內進行和函數間進行。很明顯,函數間的分析優化更準確,但需要更長的時間來完成。

  一般編譯器可以分為以下兩類:

  ①“本地”編譯器:編譯器可以生成用來在與編譯器本身所在的電腦和操作系統(平臺)相同的環境下運行的目標代碼。

  ②交叉編譯器:編譯器也可以生成用來在其他平臺上運行的目標代碼,交叉編譯器在生成新的硬體平臺時非常有用。

  交叉編譯這個概念的出現和流行是和嵌入式系統的廣泛發展同步的。在進行嵌入式系統的開發時,運行程式的目標平臺通常只有有限的存儲空間和運算能力。例如常見的ARM平臺,其一般的靜態存儲空問為16~32MB,而處理器的主頻為100~500MHz。這種情況下,在ARM平臺上進行本機編譯就不太可能了,這是因為一般的編譯工具需要很大的存儲空間,並需要很強的處理器運算能力。為瞭解決這個問題,交叉編譯工具就應運而生了。通過交叉編譯工具,就可以在CPU能力很強、存儲控制項足夠的主機平臺上(例如通用電腦)編譯出針對其他運行平臺的可執行程式。

  在一種電腦環境中運行的編譯程式,能編譯出在另外一種環境下運行的代碼,這個編譯過程就叫交叉編譯。也就是在主機平臺上開發程式,併在這個平臺上運行交叉編譯器,編譯出程式,這個編譯程式將在目標平臺上運行。這裡需要註意的是所謂平臺,實際上包含兩個概念:體繫結構和操作系統。同一個體繫結構可以運行不同的操作系統;同樣,同一個操作系統也可以在不同的體繫結構上運行。舉例來說,常說的X86Linux平臺實際上是IntelX86體繫結構和LinuxforX86操作系統的統稱;而X86WinNT平臺實際上是IntelX86體繫結構和WindowsNTforX86操作系統的簡稱。

  在交叉編譯技術中有兩種比較典型的實現,一個稱之為Java模式,即Java的位元組碼編譯技術;另一個稱之為GNUGCC模式,即通常所講的CrossGCC技術。Java模式(如圖所示)的最大特點是引入了一個自定義的虛擬機,即Java虛擬機JVM(Java Virtual Machine)。所有Java源程式都會首先被編譯成只在這個虛擬機上才能執行的“目標代碼”:位元組碼(Bytecode)。在實時運行時,可以有兩種運行方式:一種是編譯所獲得的位元組碼由JVM在實際電腦系統上執行;另一種方式是通過Java實時編譯器(Just-In-TimeCompiler)將位元組碼首先轉換成本地機可直接執行的目標代碼,而後交給實際的電腦系統運行。這實際上是一個兩次編譯過程,一次是非實時的,一次是實時的。由於第一次是非實時編譯,Java編譯器生成的是基於JVM的“目標代碼”,可以將它的編譯技術也稱為交叉編譯。

  Image:图Java模式交叉编译.jpg

  GCC模式(如圖所示)通過CrossGCC直接生成目標平臺的目標代碼,從而能夠直接在目標平臺上運行。這裡的關鍵是CrossGCC的生成和選擇問題。需要根據目標平臺的不同,選擇針對這個平臺的CrossGCC。GCC模式和Java模式的最大不同在於GCC直接生成目標平臺的目標代碼,而Java模式首先只是生成位元組碼,只有在有JIT編譯器的參與下才會進一步生成目標平臺的目標代碼。研究表明,Java模式雖然可以通過兩個編譯過程生成目標代碼,但是因為兩次編譯的優化存在相互衝突,最終的目標代碼的執行效率也不是很高。而GCC模式由於直接能夠生成目標代碼,其執行效率一般很高。

  Image:图GCC模式交叉编译.jpg

參考文獻

  1. 李兆麟.嵌入式系統設計與實踐.北京航空航天大學出版社,2010.09.
本條目對我有幫助1
MBA智库APP

扫一扫,下载MBA智库APP

分享到:
  如果您認為本條目還有待完善,需要補充新內容或修改錯誤內容,請編輯條目

本条目由以下用户参与贡献

Yixi,方小莉,寒曦,刘维燎,苏青荇.

評論(共0條)

提示:評論內容為網友針對條目"編譯器"展開的討論,與本站觀點立場無關。

發表評論請文明上網,理性發言並遵守有關規定。

MBA智库
打开APP

以上内容根据网友推荐自动排序生成