Gcc 编译器是否总是生成汇编代码? 从C++中的“强”思维到第1卷< /强>:

Gcc 编译器是否总是生成汇编代码? 从C++中的“强”思维到第1卷< /强>:,gcc,assembly,compiler-construction,Gcc,Assembly,Compiler Construction,在第二步中,代码生成器遍历解析树 并为系统生成汇编语言代码或机器代码 树的节点 至少在GCC中,如果我们给出生成汇编代码的选项,编译器就会通过创建包含汇编代码的文件来遵守但是,当我们只运行命令gcc而没有任何选项时,它不会在内部生成汇编代码吗? 如果是,那么为什么它需要首先生成汇编代码,然后将其翻译成机器语言?这是一个编译器实现的问题。汇编代码是高级语言(正在编译的语言)和生成的二进制输出之间的中间步骤。一般来说,首先转换为汇编代码,然后再转换为二进制代码比直接创建二进制代码更容易。汇编阶段有两

在第二步中,代码生成器遍历解析树 并为系统生成汇编语言代码或机器代码 树的节点

至少在GCC中,如果我们给出生成汇编代码的选项,编译器就会通过创建包含汇编代码的文件来遵守但是,当我们只运行命令
gcc
而没有任何选项时,它不会在内部生成汇编代码吗?


如果是,那么为什么它需要首先生成汇编代码,然后将其翻译成机器语言?

这是一个编译器实现的问题。汇编代码是高级语言(正在编译的语言)和生成的二进制输出之间的中间步骤。一般来说,首先转换为汇编代码,然后再转换为二进制代码比直接创建二进制代码更容易。

汇编阶段有两个理由:

  • 它允许c/c++代码被翻译成一个独立于机器的抽象汇编程序,从这个抽象汇编程序可以很容易地转换成多种不同的指令集体系结构
  • 当可以利用现有软件[组件]时,它消除了验证CISC体系结构的正确操作码、前缀、r/m等指令编码的负担

第一版的书是2000版的,但也可以说是90年初,当时C++本身被翻译成C,而GNU/自由软件思想(包括编译器的源代码)还不知道。


EDIT:GCC使用的几种无意义的方法之一是RTL-。

GCC会将汇编代码创建为临时文件,调用汇编程序,也可能调用链接程序,具体取决于您在命令行上添加或不添加的内容。这将生成一个对象,然后如果启用二进制文件,则所有临时文件都将被清除。使用-save temp查看实际情况(有许多临时文件)

在没有任何选项的情况下运行gcc绝对会创建一个asm文件


没有“必要”这样做,这只是他们碰巧设计它的方式。我假设,出于多种原因,在开始使用编译器之前,您已经需要一个汇编程序和链接器(先车后马,先处理器后asm)。“unix方式”是不重新发明工具或库,而只是在上面添加一点,这样就意味着使用asm,然后让汇编器和链接器完成其余的工作。您不必以这种方式重新发明那么多汇编程序工作(多次传递、解析标签等)。开发人员调试ascii asm比调试bits更容易。几代编译器都是这样做的。即时编译器是这个习惯的主要例外,根据定义,他们必须能够进入机器代码,所以他们可以这样做。直到最近,llvm才为命令行工具(llc)提供了一种直接进入对象的方式,而不必在asm上停留(或者至少在用户看来是这样)。

TL:DR不同的对象文件格式/更易于移植到新的Unix平台(历史上)我认为,GCC将汇编程序与编译器分开是一个主要原因。 GCC外部,主流的x86 C和C++编译器(CLAN/LLVM,MSVC,ICC)直接进入机器代码,带有.< LLVM和MSVC都有完整的工具链,而不仅仅是编译器。(还附带汇编程序和链接器)。LLVM已经将对象文件处理作为一个库函数,因此它可以使用该函数,而不是将asm文本写入单独的程序

较小的项目通常选择将对象文件格式的详细信息留给汇编程序。e、 g.,但除此之外,仅适用于asm。有很多说法(,)说几乎所有的编译器都要通过asm文本,但对于许多使用最广泛的编译器(除了GCC)来说,情况并非如此,这些编译器有很多开发人员在使用它们

C编译器倾向于只针对单个平台(如供应商针对微控制器的编译器),并作为“该平台的a/C实现”编写,或者是非常大的项目,如LLVM,其中包括机器代码生成并不是编译器自身代码大小的一大部分。不太广泛使用的语言的编译器通常更易于移植,但不需要编写自己的机器代码/对象文件处理。(现在很多编译器都是LLVM的前端,所以可以免费获得
.o
输出,就像
rustc
,但较旧的编译器没有这个选项。)

在所有编译器中,大多数都使用asm。但是,如果您根据每天使用每一个文件的频率进行加权,那么直接转到可重新定位的对象文件(
.o
/
.obj
)在全球任何给定的一天完成的总构建中都是相当大的一部分。i、 如果你正在阅读这篇文章,你关心的编译器可能会这样工作

同样,像
javac
这样的编译器,目标是一种可移植的字节码格式,使用asm的理由更少;相同的输出文件和字节码格式可以在每个平台上运行

相关的:

  • 关于逆向计算,还有一些关于将
    作为
    分开的优点的答案
  • -即使直接进入机器代码的编译器也不会直接生成链接的可执行文件,它们会生成可重新定位的对象文件(
    .o
    .obj
    )。除,用于单文件C程序的动态使用
  • 半相关:asm对于人类查看机器代码很有用,而不是作为C->机器代码的必要部分

GCC为什么要这么做 是的,
as
是一个独立的程序,
gcc
前端实际上与
cc1
分开运行(产生tex的C预处理器+编译器