gcc編譯器為什麼不直接編譯成機器代碼?
是不是經過彙編再從彙編翻譯成機器代碼的總消耗反而比直接從源程序解釋成機器代碼低呢? @vczh 如果是這樣,那應該有很聰明的人直接把這兩部分合二為一啊。我是小白,別打我。
彙編跟機器碼是一一對應的,編譯到不同的平台本身就需要產生不同的彙編。不知道gcc有沒有跟llvm一樣產生屬於自己的中間語言。如果有的話,題主可能看錯了,以為中間語言就是彙編。如果沒有的話,多半只是為了debug方便而做成這樣的。
理論上是可以合二為一的。猜測是一個歷史問題。AS,LD等一堆工具屬於GNU下的Binutils項目,而GCC是另一個項目。當然了,即使合二為一,解析彙編語言的功能還是要保留的
新的編譯器比如LLVM就是這樣,既可以直接生成對象,也可以先產生彙編再調用外部的裝配器。前者應該效率更高些這裡用的是分層思想,假如機器體系改變了,只動彙編層次的代碼即可,高級語言的語法進化了,直接改變編譯器的代碼就行,不用動彙編層次。相關的可以參看tcp/ip的層次模型。
彙編本身就是後端生成的,不存在彙編是中間語言的說法,彙編並沒有任何屏蔽下層的作用,gcc 編譯器的中間語言(編譯器前後端的中間層)好像沒有暴露給外部。
gcc 這麼做多半是為了調試方便一些(不過調試目的也完全可以反彙編,一一對應),事實上彙編到機器碼的消耗是非常小的,因為一一對應,查表就行。
事實上很多生成的語言都能選擇生成文本格式或者二進位格式,文本形式輔助調試,二進位形式真正執行的設定,如 llvm 就有ir和bc兩種模式,你把彙編和機器碼當成這種關係就行。分層是計算機設計的基本思想,為了靈活可擴展。
前後端加個中間層,一方便做優化,二便於移植和升級。
機器語言-&>彙編語言-&>高級語言的發展過程,所以編譯器出現之前彙編器應該已經存在了。高級語言能翻譯到彙編就可以了,純粹個人揣測。
解耦的一種方式。
彙編可讀性好啊。
通過看彙編可以抓到編譯器犯二的時候。
然後反過來改源代碼以圖生成更好更快的代碼。
更多詳情看
https://www.youtube.com/watch?v=GOlurMtkuWQlist=PLD2AE32F507F10481index=7
https://www.youtube.com/watch?v=7a89iFEEpToindex=6list=PLD2AE32F507F10481
暫時想到一點: 編譯單元無法確定要訪問的邏輯地址,也就無法轉為機器碼,必須由鏈接過程分配地址。
至於為什麼要先編譯後鏈接,應該是易於編譯器的實現和擴展並且能夠增加靈活性和多文件項目的編譯效率。推薦閱讀:
※請問國內有哪些關於clang編譯技術的重要會議或者論壇?
※單純學習C,windows下有什麼好的編譯器?
※std::array 是被編譯器特別對待的嗎?
※C語言編譯器為什麼能夠用C語言編寫?
※為什麼總有人追求 one-pass compiler?
TAG:編譯器 |