本節書摘來自華章出版社《編譯與反編譯技術實戰 》一書中的第2章,第2.1節,龐建民 主編 ,劉曉楠 陶紅偉 嶽 峰 戴超 編著,更多章節内容可以通路雲栖社群“華章計算機”公衆号檢視。
人與計算機之間的交流也是通過語言進行的,但人類能了解的語言與機器可以了解的語言是不同的,中間需要翻譯,是以,相應的編譯器誕生了。編譯技術所讨論的問題就是如何把符合人類思維方式的意願(即源程式)翻譯成計算機能夠了解和執行的形式(即目标程式),而實作從源程式到目标程式轉換的程式被稱為編譯程式或編譯器。最早的編譯器是20世紀50年代後期的fortran編譯器,該編譯器也為後續進階語言和編譯器的湧現奠定了基礎。與編譯技術相反,反編譯技術所讨論的問題就是如何把計算機能夠了解和執行的形式(目标程式)翻譯成符合人類便于了解的形式(源程式或流程圖),實作從目标程式到便于人類了解的系列文檔的轉換程式被稱為反編譯程式或反編譯器。反編譯技術起源于20世紀60年代,雖然在時間上隻比編譯技術晚10年左右,但反編譯技術的成熟度卻遠不如編譯技術。半個世紀以來,也湧現了不少實驗性的反編譯器,如dcc、boomerang和ida的反編譯插件hex_rays等。但這些反編譯器都有這樣或那樣的缺陷,還不能像編譯器那樣強健。
本章僅對編譯器實踐方面的知識進行簡要闡述,反編譯實踐方面的概要介紹将在後續章節給出。
就目前計算機的硬體發展水準而言,硬體隻能識别由0、1字元串組成的機器指令序列,即機器指令程式或目标程式。在計算機發明的早期,計算機隻能按照輸入的機器指令程式進行簡單的計算。但是,機器指令程式不易被人類了解,用它編寫程式不僅困難而且還容易出錯。于是後來就引入了代替0、1字元串的由助記符号表示的指令,即彙編指令,彙編指令的集合被稱為彙編語言,彙編指令序列被稱為彙編語言程式。彙程式設計式實際上與機器語言程式是一一對應的,都要求程式員按照指令工作的方式來思考和解決相關問題,也就是說,兩者之間并無本質差別。是以,它們都被稱為面向機器的語言或低級語言,以此與更進階的語言相差別,當然,早期并不知道進階别的語言是否能設計和實作。
計算機的發展和普及超乎人們的想象,應用需求的大量增長導緻程式員的需求也大幅增長,但是,能夠用機器語言或彙編語言程式設計的人員數量卻不多,滿足不了這種需求;同時,許多不同領域的科技工作者也想自己動手編寫程式來直接解決問題。是以,抽象度更高、功能更強的語言來作為程式設計語言就成為必然,于是就産生了面向各類應用的便于人類了解與運用的程式設計語言,即進階語言。盡管人類可以借助進階語言來編寫程式,但計算機硬體真正能夠識别和了解的語言還是0、1組成的機器語言,這就需要在進階語言與機器語言之間建立轉換系統,使得進階語言能夠自動轉換為機器語言。也就是說需要若幹“翻譯”,把各類進階語言翻譯成機器語言。程式設計語言通常被分成三個層次:進階語言、彙編語言、機器語言。進階語言可以翻譯成機器語言,也可以翻譯成彙編語言,這兩種翻譯都被稱為編譯。彙編語言到機器語言的翻譯稱為彙編。編譯和彙編屬于正向工程,有時還需要将機器語言翻譯成彙編語言或進階語言,這通常被稱為反彙編或反編譯,屬于逆向工程範疇。
進階語言的工作方式有兩種,一種是編譯器工作方式,另一種是解釋器工作方式。
在編譯器工作方式下,源程式的翻譯和翻譯後程式的運作處于兩個互相獨立的階段。使用者輸入源程式,編譯器對該源程式進行編譯,生成目标程式,這個階段稱為編譯階段。目标程式在适當的輸入下執行,最終得到運作結果的過程稱為運作階段。
解釋器是另一種形式的翻譯器。它把翻譯和運作結合在一起進行,邊翻譯源程式,邊執行翻譯結果,而這種工作方式被稱為解釋器工作方式。
形象地說,編譯器的工作相當于翻譯一本原著,原著與源程式對應,譯著與目标程式對應,計算機的運作相當于閱讀一本譯著,這時,原著和翻譯人員并不需要在場,譯著是主角。解釋器的工作相當于在進行現場翻譯,外賓和翻譯都要在場,翻譯一邊聽外賓講話,一邊翻譯給聽衆,翻譯是聽衆關注的主角。解釋器與編譯器的最本質差別是:運作目标程式時的控制權在解釋器而不是目标程式,也就是說,運作的是解釋器,目标程式是解釋器的輸入。