GCC/G++ 输出类型

8

我知道这是一个非常基础的问题,但当我使用gcc/g++编译我的c/c++代码时,在汇编器生成机器代码之前,中间输出的类型究竟是什么?它是否类似于X86指令?


2
你指的是什么“中间”输出?g++ 直接生成汇编代码。 - Lol4t0
以下选项可能会有用:-g -Wa,-ahl=main.s。它们会导致GCC/G++发出带有交错高级源代码的汇编。 - Joseph Mansfield
这绝不是一个基础问题。 - cha0site
6个回答

13

GCC的处理流程如下:

  1. 您的源代码

  2. 预处理源代码(展开宏和包含文件,去掉注释)(-E, .ii)

  3. 编译成汇编语言(-S, .s

  4. 汇编成二进制代码(-c, .o

  5. 链接到可执行文件

在每个阶段中,我列出了使该过程停止的相关编译器标志,以及相应的文件后缀。

如果使用-flto编译,则对象文件将被装饰为GIMPLE字节码,这是一种低级中间格式,其目的是延迟实际的最终编译至链接阶段,从而允许进行链接时优化。

“编译”阶段是实际的重要部分。预处理器本质上是一个单独的、独立的工具(尽管它的行为是由C和C++标准规定的),汇编器和链接器实际上是单独的、独立的工具,基本上只是实现硬件的二进制指令格式和操作系统的可加载可执行文件格式。


+1,非常好的回答。您可能需要添加一些关于汇编是什么的说明,因为提问者似乎并不完全清楚。 - cha0site
@cha0site:谢谢...让我们看看;如果OP需要澄清,欢迎提出问题,我很乐意进行扩展。 - Kerrek SB
1
@Cemre:GCC 内部分为语言前端(例如 C、C++、Fortran)和硬件后端(x86、PPC、ARM 等),但所有这些都编译成一个固定的编译器二进制文件。您必须为所需的目标架构构建整个编译器套件,因此源代码的结果程序二进制文件取决于您选择的实际编译器。您需要 ARM 编译器来生成 ARM 二进制文件,需要 x86 编译器来生成 x86 二进制文件,等等。为非本机平台编译称为“交叉编译”。 - Kerrek SB
1
@Cemre:GCC(GNU编译器集合)的内部操作是通过所谓的前端将代码转换为一种与语言和硬件无关的内部表示形式,称为抽象语法树。每种语言都有一个前端。然后将此AST传递给特定于机器的后端,以生成汇编代码。但是,正如Kerrek所说,您不能仅构建前端或后端,只能使用整个编译器(这只是GCC的设计方式,不是绝对限制)。 - cha0site
@cha0site:举个例子,Clang是C语言家族的前端,它执行第一次预处理/编译(生成一个称为LLVM IR的中间表示),然后将生成的IR交给LLVM,LLVM生成汇编并将其交给系统链接器(大多数*nix系统上是ld/gold,Windows上是link.exe,尽管有一个LLVM链接器项目正在进行中)。 - Xeo
显示剩余3条评论

4
因此,在GCC中,可执行文件的编译包括四个部分:
1.) 预处理(gcc -E main.c > main.i; 将*.c转换为*.i) 包括宏展开,处理注释。
2.) 编译(gcc -S main.i; 如果成功将*.i转换为*.s) 将C代码编译为汇编语言(在目标x86架构上是x86汇编语言,在目标x86_64架构上是x64汇编语言,在目标arm架构上是arm汇编语言等)。 大多数警告和错误发生在此阶段(例如错误和警告报告)。
3.) 汇编(as main.s -o main.o; 如果成功将*.i转换为*.o) 将生成的汇编程序组装成机器码。尽管仍然有过程的相对地址等。
4.) 链接(gcc main.o) 用绝对地址替换相对地址。删除无用文本。 在此阶段发生链接错误和警告。 最终(如果成功),我们得到可执行文件。
因此,回答您的问题,您所说的中间输出实际上是所谓的汇编语言-请参见汇编语言wiki

2
这是gcc编译步骤的图形表示,由redhat杂志提供:

gcc compilation steps

与其他答案所暗示的相反,这里没有汇编步骤 - 相反,生成汇编代码替代了目标代码生成;如果您真正想要的是二进制表示,那么将内存中的表示转换为文本表示并没有多大意义。

嗯,是的,如果你最终要生成目标代码,那么生成供人类阅读的助记符确实没有太多意义。但是助记符与目标代码几乎是一对一的关系,而汇编器的代码生成部分已经完成了(计算跳转地址等操作)。 - cha0site

0

必须是汇编代码。您可以在编译时使用-S标志获取它。


0

没有所谓的“中间输出”。你得到的第一个输出就是机器码。(虽然你可以通过使用-E参数仅调用预处理器来获取C/C++的中间输出。)


0

GCC 工具链,将程序从源代码编译成机器码。编译器生成汇编代码,汇编器将其汇编成机器码。此处有一个适合初学者的好教程。


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