從編譯原理的角度看C語言是如何轉換成彙編語言的?

 

大家都知道計算機只能處理和識別二進制指令,而我們利用各種高級編程語言所編寫的程序,要經過一些列的處理步驟,最終轉變爲彙編指令,再最後轉變爲機器指令。

 

640?wx_fmt=jpeg

 

以上這些轉變是如何發生的就屬於大名鼎鼎的“編譯原理”所研究的範疇,作爲計算機專業學生,它的重要性毫無質疑,自然也是必修課。而我們幾年所要給大家講的是高級編程語言到彙編語言這一轉變的過程,後面就以C語言爲例。

 

640?wx_fmt=jpeg

 

640?wx_fmt=jpeg

640?wx_fmt=jpeg

640?wx_fmt=jpeg

 

怎麼樣,計科專業的學生或者學過編譯原理的看到上面幾本書熟悉嗎?這幾本書差不多是大多數高校編譯原理課程的教材了。言歸正傳,我們今天討論的是C如何轉換成彙編語言,在講之前先給大家簡要介紹下彙編語言:

 

彙編語言(assembly language)是一種用於電子計算機、微處理器、微控制器或其他可編程器件的低級語言,亦稱爲符號語言。在彙編語言中,用助記符(Mnemonics)代替機器指令的操作碼,用地址符號(Symbol)或標號(Label)代替指令或操作數的地址。在不同的設備中,彙編語言對應着不同的機器語言指令集,通過彙編過程轉換成機器指令。普遍地說,特定的彙編語言和特定的機器語言指令集是一一對應的,不同平臺之間不可直接移植。

640?wx_fmt=jpeg

彙編語言的主要特點

(1)彙編語言是直接面向處理器(Processor)的程序設計語言。

(2)彙編語言的另一個特點就是它所操作的對象不是具體的數據,而是寄存器或者存儲器,也就是說它是直接和寄存器和存儲器打交道,這也是爲什麼彙編語言的執行速度要比其它語言快,但同時這也使編程更加複雜,因爲既然數據是存放在寄存器或存儲器中,那麼必然就存在着尋址方式,也就是用什麼方法找到所需要的數據。

(3)再者,彙編語言指令是機器指令的一種符號表示,而不同類型的CPU 有不同的機器指令系統,也就有不同的彙編語言,所以,彙編語言程序與機器有着密切的關係。

 

簡單瞭解了彙編語言,那麼根據編譯原理C語言是怎麼轉換成彙編語言的呢?總共可分以下6個步驟:

1. 預處理 -> 2.詞法分析 -> 3.語法分析 -> 4.語義分析 -> 5.優化 -> 6.鏈接

 

1. 預處理:負責執行C語言中的#include, #if, #else 等預處理指令。注意,這裏是去執行這些預處理指令。這些預處理指令的作用是根據你的系統環境配湊出最終版的源代碼。

640?wx_fmt=jpeg

2. 詞法分析:把你定義的函數名、變量名、預留的關鍵字等抽象化,用一個符號來代替,方便編譯程序處理。例如上圖中的main, return, printf等單詞,都被看作一個符號,轉換成M, R, P。在這個過程中,會檢查你的變量名、函數名名稱是否正確。

3. 語法分析:經過詞法分析處理之後,程序代碼已經變成一堆符號了,例如 I S T F ... M I R P(放心,人已經不認識了,但是計算機能認識)。這時的符號是打散的,語法分析負責把這些符號按照一定的結構組織起來,形成一個抽象語法樹(這個結構跟你寫的程序代碼的結構是對應起來的)。

640?wx_fmt=jpeg

4. 語義分析:當構造出這樣一個樹的結構之後,編譯就就會檢查語法是否正確,並且去掃描這棵樹。根據這棵樹的結構,生成中間指令了。這個中間指令已經非常接近彙編。中間指令跟彙編還是有區別的,因爲不同廠家的CPU指令有所不同,所以還要根據不同廠家的CPU指令集,把這個中間指令轉換成彙編。

640?wx_fmt=jpeg

5. 優化:因爲程序員有時代碼寫的不太好,會導致一些多餘的操作,或者效率低的指令。優化過程可以找出這些毛病,自動替換成更好的指令。

6. 鏈接:以上過程只編譯了一個模塊,一個大型程序往往包好多個模塊。最後的鏈接過程負責把所有模塊組裝起來,構造出最後可以執行的程序。

以上大概就是C語言轉換成彙編的過程了,當然可能大家所學編譯原理課程中只列舉了核心的幾個步驟,而且一個步驟就是課程一章的內容,也比較詳細,我們這裏只做簡要介紹,目的是讓大家對這個轉換過程有個大體的瞭解,有興趣想深究的還是建議去系統學習編譯原理,希望以上內容對大家有所幫助,感謝閱讀!

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