源文件,目标文件与可执行文件

本文介绍C编程中的编译和链接过程,包括源代码如何转换为目标代码,以及链接器如何将目标代码、启动代码和库代码组合成可执行文件。

C编程的基本策略是使用程序将源代码转换为可执行文件,此文件包含可运行的机器语言代码。C分两步完成这一工作:编译和链接。编译器将源代码转换为中间代码,连接器将此中间代码与其他代码相结合来生成可执行文件。C使用被划分为两部分的这一方法使程序便于模块化,你可以分别编译各个模块,然后使用连接器将编译过的模块结合起来。这样,如何需要改变一个模块,则不必重新编译所有其他模块。同时,链接器将您的程序与编译的库代码结合起来。

 

    中间文件的形式有多种选择。最一般的选择,同时也是我们这里讲述的实现方式所采取的选择,是将源代码转换为机器代码。将结果放置在一个目标代码文件(或简称目标文件)中(这里假定您的源代码由单个文件组成)。虽然目标文件包含机器语言代码,但该文件还不能运行。目标文件包含源代码的转换结果,但它还不是一个完整的程序。

 

    目标代码文件中所缺少的第一个元素是一种叫做启动代码(Start-up code)的东西,此代码相当于您的程序和操作系统之间的接口。例如你可以在dos 或Linux下运行一个 IBM PC 兼容机,在两种情况中硬件是相同的,所以都会使用同样的目标代码,但是 DOS与Linux要使用不用的启动代码,因为这两种系统处理程序的方式不同的。

 

所缺少的第二个元素是库例程的代码。几乎所有C程序都利用标准库中所包含的例程(称为函数)。例如,前面的concrete.c使用了函数printf()。目标代码文件不包含这一函数的指令。实际代码存储在另一个称为“库”的文件中,库文件中包含许多函数的目标代码。

 

    链接器的作用是将这3个元素(目标代码、系统的标准启动代码和库代码)结合在一起,并将他们存放在单个文件,即可执行文件中。对库代码来说,链接器只从库中提取您所使用的函数所需的代码(见图1.4所示)

 

 

简而言之,目标文件和可执行文件都是由机器语言指令组成的。但目标文件只包含您所编写的代码转换成的机器语言,而可执行文件还包含您所使用的库例程以及启动代码。

源文件生成可执行文件的过程涉及多个阶段,主要包括预处理、编译、汇编链接四个步骤。这些阶段依次对源代码进行处理,最终生成可在操作系统上直接运行的可执行文件。 ### 预处理阶段 预处理阶段的主要任务是处理源代码中的预处理指令,例如`#include`、`#define`条件编译指令(如`#if`、`#ifdef`等)。预编译器会将头文件的内容插入到源文件中,并展开宏定义。最终生成一个扩展名为`.i`的中间文件,该文件包含了所有预处理后的代码。例如,使用`gcc -E hello.c -o hello.i`可以生成预处理后的文件[^2]。 ### 编译阶段 在编译阶段,编译器将预处理后的代码转换为汇编语言代码。编译器会对代码进行语法分析、语义分析,并生成抽象语法树(AST)。随后,编译器会生成中间代码表示(如LLVM IR或三地址代码),并对其进行优化。最终,生成一个扩展名为`.s`的汇编文件。例如,使用`gcc -S hello.i -o hello.s`可以生成汇编代码文件[^4]。 ### 汇编阶段 汇编阶段的任务是将汇编语言代码转换为目标机器的机器代码。汇编器会将`.s`文件转换为二进制格式的目标文件,扩展名为`.o`。目标文件包含机器指令,但尚未解析外部符号(如函数调用或全局变量)的地址。例如,使用`gcc -c hello.s -o hello.o`可以生成目标文件[^2]。 ### 链接阶段 链接阶段是最后一步,其主要任务是将多个目标文件(`.o`文件文件(静态库或动态库)组合成一个完整的可执行文件。链接器会解析目标文件中的外部符号,并为它们分配运行时地址。最终生成的可执行文件通常命名为`a.out`,也可以通过编译器选项自定义名称。例如,使用`gcc hello.o -o hello`可以生成可执行文件[^1]。 ### 示例代码 以下是一个简单的C语言程序示例,展示了如何通过命令行工具生成可执行文件: ```bash # 预处理 gcc -E hello.c -o hello.i # 编译 gcc -S hello.i -o hello.s # 汇编 gcc -c hello.s -o hello.o # 链接 gcc hello.o -o hello ``` 运行上述命令后,即可生成名为`hello`的可执行文件,通过`./hello`可以直接运行该程序。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值