汇编代码与二进制输出的区别

3

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

我能想到的汇编语言优点:避免需要学习目标文件格式,易于调试后端。

二进制的优点:编译速度更快。这有多重要呢?假设使用Gnu汇编程序(除了其他因素外,它是可以合理地假设在大多数计算机上都可用的),组装一百万行代码需要多长时间?

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

双方是否有其他优势我没有考虑到的?


2
GNU汇编器一次通过即可工作。它在生成的二进制文件大小方面是线性的。除非您的编译器非常基础,根本不执行任何复杂的优化,否则GNU汇编器所需的时间可以在总编译时间中忽略不计。 - Pascal Cuoq
6个回答

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文件。


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

2
如果您生成汇编代码,那么最终会有以下两个步骤:
- 将该代码写入磁盘,然后汇编器将读取它; - 调用汇编器,即启动一个新进程。
汇编器本身运行速度很快,但文件I/O需要一两秒钟时间。一百万行?可能需要5秒钟。启动汇编器需要100到1000毫秒。这没什么大不了的。
我认为更容易调试和无需调整对象格式的优点将轻松弥补稍长的编译时间。

1
生成二进制代码的主要优点是可以直接将代码注入内存,刷新指令高速缓存,然后跳转到它。这意味着您可以使用本地代码编译器创建一个漂亮的交互式循环。这是一个非常好的功能,并且在新泽西标准ML编译器中已经使用了20多年。

1

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

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

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


0

你可以尝试一下生成代码汇编需要多长时间:

gcc -O2 -S -c foo.c

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接