装配与二进制输出

时间:2010-01-04 13:42:24

标签: compiler-construction assembly code-generation

编译器将代码编译为汇编语言或直接输出二进制机器代码是否更好?

汇编语言的优点让我无法想到:避免学习目标文件格式,轻松调试后端。

二进制的优点:更快的编译速度。这有多重要?假设使用Gnu汇编程序(除了其他任何东西,它可以合理地假设在大多数机器上都可用),是否需要花费大量时间来组装,比如一百万行代码?

汇编程序隐藏的各种操作系统之间的目标文件格式是否存在差异?

我有没有想到的任何一方有任何其他优势?

6 个答案:

答案 0 :(得分:3)

装配更容易输出,并且具有人类可读性的好处。 至于编译时间,这里有我的编译器的一些统计数据:

[~/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文件。

答案 1 :(得分:2)

汇编的另一个优点:能够为跳转,循环,分支和函数调用使用标签,因此您无需手动计算内存地址。

答案 2 :(得分:2)

如果您生成汇编代码,那么您将结束

  • 将该代码写入磁盘,汇编器必须阅读它;
  • 调用汇编程序,即启动新进程。

汇编程序本身运行速度很快,但文件I / O需要一两分钟。一百万行?也许5秒。例如,启动汇编程序将需要100到1000毫秒。那里没什么大不了的。

我认为更容易调试并且不需要使用对象格式,这很容易弥补编译时间稍长的时间。

答案 3 :(得分:1)

直接生成二进制文件的主要优点是可以将代码直接喷入内存,刷新I-cache,然后分支到它。这意味着您可以使用本机代码编译器创建一个很好的交互式循环。这是一个很好的功能,可以在Standard ML of New Jersey编译器中使用和部署超过20年。

答案 4 :(得分:1)

  

汇编程序隐藏的各种操作系统之间的目标文件格式是否存在差异?

是的,即使在同一操作系统上,您也可以使用多种目标文件格式。 (例如,MASM可以生成例如OMF或COFF对象格式以供不同的链接器使用。)

有关不同目标文件格式的更多信息,请参阅相应部分 this document

答案 5 :(得分:0)

您可以尝试为代码生成程序集所需的时间:

gcc -O2 -S -c foo.c