编译器是将代码编译为汇编语言,还是直接输出二进制机器代码更好呢?
我能想到的汇编语言优点:避免需要学习目标文件格式,易于调试后端。
二进制的优点:编译速度更快。这有多重要呢?假设使用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文件。
汇编器是否会隐藏各种操作系统之间的目标文件格式差异?
是的,即使在同一操作系统上,您也可以有多种目标文件格式。(例如,MASM可以生成OMF或COFF目标格式,以供不同的链接器使用。)
有关不同目标文件格式的更多信息,请参阅this document中的相应部分。
你可以尝试一下生成代码汇编需要多长时间:
gcc -O2 -S -c foo.c