C语言编译的四个步骤

编译一个C语言程序是一个多阶段的过程。从总体上看,这个过程可以分成四个独立的阶段。预处理、编译、汇编和连接。

在这篇文章中,我将逐一介绍编译下列C程序的四个阶段。

/*

* "Hello, World!": A classic.

*/





#include 

int main(void)

{

    puts("Hello, World!");

    return 0;

}

预处理

编译的第一个阶段称为预处理。在这个阶段,以#字符开头的行被预处理器解释为预处理器命令。这些命令形成一种简单的宏语言,有自己的语法和语义。这种语言通过提供内联文件、定义宏和有条件地省略代码的功能,来减少源代码的重复性。

在解释命令之前,预处理器会做一些初始处理。这包括连接续行(以 \ 结尾的行)和剥离注释。

要打印预处理阶段的结果,请向gcc传递-E选项。

gcc -E hello_world.c

考虑到上面的 "Hello, World!"的例子,预处理器将产生stdio.h头文件的内容和hello_world.c文件的内容,并将其前面的注释剥离出来。

编译

编译的第二个阶段被称为编译,令人困惑。在这个阶段,预处理过的代码被翻译成目标处理器架构特有的汇编指令。这些形成了一种中间的人类可读语言。

这一步骤的存在允许C代码包含内联汇编指令,并允许使用不同的汇编器。

一些编译器也支持使用集成汇编器,在这种情况下,编译阶段直接生成机器代码,避免了生成中间汇编指令和调用汇编器的开销。

要保存编译阶段的结果,可以向gcc传递-S选项。

gcc -S hello_world.c

这将创建一个名为hello_world.s的文件,包含生成的汇编指令。

汇编

在这个阶段,汇编器被用来将汇编指令翻译成目标代码。输出包括目标处理器要运行的实际指令。

要保存汇编阶段的结果,请向gcc传递-c选项。

gcc -c hello_world.c

运行上述命令将创建一个名为hello_world.o的文件,包含程序的目标代码。这个文件的内容是二进制格式,可以用运行命令hexdump或od来检查。

hexdump hello_world.o

od -c hello_world.o

Linux中的od(octal dump)命令用于转换输入内容为八进制。

Hexdump是一个命令行工具,用于以各种方式显示文件的原始内容,包括十六进制,可用于Linux、FreeBDS、OS X和其他平台。Hexdump不是传统Unix系统或GNU命令的一部分。

链接

汇编阶段产生的目标代码是由处理器能够理解的机器指令组成的,但程序的某些部分是不符合顺序的或缺失的。为了产生一个可执行的程序,现有的部分必须被重新排列,并把缺失的部分补上。这个过程被称为链接。

链接器将安排目标代码的各个部分,使某些部分的功能能够成功地调用其他部分的功能。它还将添加包含程序所使用的库函数指令的片段。在 "Hello,world!"程序的例子中,链接器将添加puts函数的对象代码。

这一阶段的结果是最终的可执行程序。当不使用选项运行时,gcc 将把这个文件命名为 a.out。如果要给文件命名,请向 gcc 传递 -o 选项。

gcc -o hello_world hello_world.c

参考:

The Four Stages of Compiling a C Program icon-default.png?t=LA23https://www.calleluks.com/the-four-stages-of-compiling-a-c-program/

https://en.wikibooks.org/wiki/Hexdumpicon-default.png?t=LA23https://en.wikibooks.org/wiki/Hexdump

你可能感兴趣的:(编程参考,c语言,开发语言)