編譯器將代碼編譯爲彙編語言,還是直接輸出二進制機器代碼會更好嗎?彙編與二進制輸出
我能想到的彙編語言的優勢:避免了學習目標文件格式的需要,調試後端的難度。
二進制的優點:編譯速度更快。這有多重要?假設使用Gnu彙編器(除了其他任何東西,它可以合理地假定在大多數機器上都可用),是否需要花費大量的時間來組裝比如說一百萬行代碼?
彙編器隱藏的各種操作系統之間的目標文件格式是否存在差異?
我還沒有想到任何一方都有其他優點嗎?
編譯器將代碼編譯爲彙編語言,還是直接輸出二進制機器代碼會更好嗎?彙編與二進制輸出
我能想到的彙編語言的優勢:避免了學習目標文件格式的需要,調試後端的難度。
二進制的優點:編譯速度更快。這有多重要?假設使用Gnu彙編器(除了其他任何東西,它可以合理地假定在大多數機器上都可用),是否需要花費大量的時間來組裝比如說一百萬行代碼?
彙編器隱藏的各種操作系統之間的目標文件格式是否存在差異?
我還沒有想到任何一方都有其他優點嗎?
裝配更容易輸出,它具有人類可讀性的好處。 至於編譯的時候,這裏是從我的編譯器的一些統計數據:
[~/ecc/ellcc/ecc/Main] main% ../../bin/x86-elf-ecc test/sieve.c -time-actions
===-------------------------------------------------------------------------===
... Ellcc action timing report ...
===-------------------------------------------------------------------------===
Total Execution Time: 2.9006 seconds (2.9857 wall clock)
---User Time--- --System Time-- --User+System-- ---Wall Time--- --- Name ---
2.0397 (71.3%) 0.0250 (65.8%) 2.0647 (71.2%) 2.1174 (70.9%) Bitcode linking
0.7999 (27.9%) 0.0070 (18.4%) 0.8069 (27.8%) 0.8111 (27.2%) Generating
0.0000 ( 0.0%) 0.0010 ( 2.6%) 0.0010 ( 0.0%) 0.0274 ( 0.9%) Assembly
0.0110 ( 0.4%) 0.0030 ( 7.9%) 0.0140 ( 0.5%) 0.0143 ( 0.5%) LLVM generation
0.0070 ( 0.2%) 0.0000 ( 0.0%) 0.0070 ( 0.2%) 0.0066 ( 0.2%) Type checking
0.0000 ( 0.0%) 0.0020 ( 5.3%) 0.0020 ( 0.1%) 0.0041 ( 0.1%) Linking
0.0030 ( 0.1%) 0.0000 ( 0.0%) 0.0030 ( 0.1%) 0.0031 ( 0.1%) Optimization
0.0010 ( 0.0%) 0.0000 ( 0.0%) 0.0010 ( 0.0%) 0.0010 ( 0.0%) Elaboration
0.0010 ( 0.0%) 0.0000 ( 0.0%) 0.0010 ( 0.0%) 0.0004 ( 0.0%) Integrity checking
0.0000 ( 0.0%) 0.0000 ( 0.0%) 0.0000 ( 0.0%) 0.0004 ( 0.0%) Parsing
2.8626 (100.0%) 0.0380 (100.0%) 2.9006 (100.0%) 2.9857 (100.0%) TOTAL
[~/ecc/ellcc/ecc/Main] main%
正如你所看到的裝配時間由聯和代碼生成相形見絀。這個例子編譯並鏈接一個小的main()以及標準庫,全部使用LLVM中間形式。然後爲整個程序生成一個彙編語言文件。該文件使用鏈接器進行鏈接(實際重新定位),該鏈接器創建a.out文件。
程序集的另一個優點:可以使用標籤進行跳轉,循環,分支和函數調用,因此不需要手動計算內存地址。
你可以嘗試一下它需要多長時間來生成彙編爲您的代碼:
gcc -O2 -S -c foo.c
如果生成彙編代碼,那麼你最終會
彙編程序本身運行速度很快,但文件I/O需要一兩分鐘。一百萬行?也許5秒。例如,啓動彙編程序需要100到1000毫秒。那裏沒什麼大不了的。
我認爲調試和解除對象格式操作的輕鬆性很容易彌補稍長的編譯時間。
直接生成二進制文件的主要優點是可以直接將代碼噴入內存,刷新I緩存,然後分支到內存。這意味着您可以使用本地代碼編譯器創建一個良好的交互式循環。一個很好的功能,並在編譯器中部署了超過20年的Standard ML of New Jersey。
彙編器隱藏的各種操作系統之間的目標文件格式是否存在差異?
是的,即使在同一個操作系統上,也可以有多種目標文件格式。(例如,MASM可以生成例如OMF或COFF目標格式,以通過不同的連接體來使用。)
更多關於不同的對象的文件格式可以在相應的部分中 this document找到。
GNU彙編器一次工作。它在生成的二進制文件的大小上是線性的。除非你的編譯器是非常基本的,並且根本沒有任何困難的優化,否則GNU彙編器所花費的時間在整個編譯時間內可以忽略不計。 – 2010-01-04 13:48:22