深入理解计算机系统 1.2 程序被其它程序翻译成不同形式

hello程序作为高级C程序开始它的生命,之所以被叫做高级的,是因为它能人类阅读和理解。然而,为了能在系统上运行hello.c,单个的C语句必须被其它程序翻译成一系列低级的机器语言指令。这些指令以被叫做可执行对象程序的形式打包,并且被存储为二进制磁盘文件。对象程序与可执行对象文件关联。

在Unix系统上,从源文件到对象文件的翻译过程被编译器执行:

unix> gcc -o hello hello.c


深入理解计算机系统 1.2 程序被其它程序翻译成不同形式_第1张图片

GCC编译器读取hello.c源文件,然后把它翻译成一个hello可执行对象文件。翻译以Figure 1.3所示的四步被执行。执行这四步(预处理器,编译器,汇编器,链接器)的程序一起被叫做编译系统。


预处理步骤。预处理器(cpp)通过以#开始的指令修改C源程序。例如,hello.c的第一行的#include <stdio.h>命令告诉预处理器去读取系统头文件stdio.h的内容并将其直接插入到程序文本中。这就有了另外一个C程序,典型的带有.i后缀。


编译阶段。编译器(cc1)将hello.i文本文件翻译为hello.s文本文件,hello.s里包含的是一个汇编语言程序。汇编语言程序里的每一条语句以一个标准文本格式精确地描述了一条低级机器语言指令。汇编语言是有用的,因为它为对应不同高级语言的不同编译器提供相同的输出语言。例如,C编译器和Fortran编译器用相同的汇编语言产生输出文件。


汇编阶段。汇编器把hello.s翻译成机器语言指令,以可重定向对象程序的格式打包它们,并把结果存在对象文件hello.o中。hello.o是二进制文件,它用字节编码机器语言指令,而不是用字符。如果我们用一个文本编辑器来看hello.o,看到的将是乱码。


链接阶段。注意,我们的hello程序调用了printf函数,printf函数是C标准库的一部分,每一个编译器都将提供C标准库。printf函数在另一个之前已经编译好的叫做printf.o的对象文件中,printf.o必须与我们的hello.o文件合并。链接器(ld)就是来合并它们的。最终产生hello文件,它是一个能被加载进内存并被系统执行的可执行对象文件。

你可能感兴趣的:(深入理解计算机系统 1.2 程序被其它程序翻译成不同形式)