预处理.i,编译器输出.s,汇编器输出.o

·

1 min read

预处理器输出 (.i 文件)

预处理器接受原始的 C 源代码(.c 文件)并进行预处理,这包括处理 #include 指令,替换宏定义 (#define),处理条件编译 (#if#ifdef#ifndef 等)。预处理器的输出是 .i 文件,它是经过预处理后的 C 代码,其中所有的宏和 #include 指令都被替换为其具体的内容。.i 文件可以作为编译器的输入。

编译器输出 (.s 文件)

编译器将预处理器输出的 .i 文件作为输入,并将其转换为汇编语言代码。这个过程包括了很多步骤,例如词法分析Lexical,语法分析Parsing,生成抽象语法树AST,优化,以及生成汇编语言代码。编译器输出的是 .s 文件,也就是汇编语言代码。.s 文件可以作为汇编器的输入。

汇编器输出 (.o 文件)

汇编器将编译器输出的 .s 文件作为输入,并将其转换为二进制的目标代码。汇编器的输出是 .o 文件,也就是目标文件。这些目标文件可以作为链接器的输入,链接器将多个 .o 文件链接为一个可执行文件或文件。

关于重命名和重新编译.i

.i 文件可以重命名为 .c 文件并重新编译。.i 文件本身就是 C 语言代码,只不过它已经进行了预处理,所以可以直接作为编译器的输入。将 .i 文件重命名为 .c 文件并重新编译的情况并不常见,但在某些情况下可能会有用,例如在调试预处理器问题,或者在需要将预处理结果作为源代码的情况下。

重命名 .i 文件为 .c 文件并重新编译的好处是,你可以直接看到预处理的结果,这在调试宏扩展等问题时非常有用。然而,你需要注意,由于 .i 文件已经经过预处理,因此它可能非常大,并且包含大量的代码,这可能会使得代码阅读和理解更加困难。

  1. gcc -save-temps: 这个命令在 GCC 中有特殊的用途。当你在编译源代码时,GCC 会通过几个阶段,包括预处理、编译、汇编链接。每个阶段都会生成中间文件。使用 -save-temps 选项会让 GCC 在每个阶段之后都保存中间文件,而不是像默认情况那样在整个编译过程结束后删除它们。保存的文件包括

    • 预处理器输出(.i文件)

    • 编译器输出(.s文件)

    • 汇编器输出(.o文件)。

  2. gcc -E: 这个命令用于运行 GCC 的预处理阶段,并将预处理后的源代码输出到标准输出(默认情况下)或指定的文件。预处理阶段包括将所有的宏扩展、处理所有的预处理指令(如 #include、#define 等),同时也会处理条件编译指令(如 #if、#ifdef、#else 等)。这个命令可以让你看到预处理阶段后的代码是如何的,特别是对于调试宏扩展的问题特别有用。