购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

2.1.3 汇编阶段

汇编阶段负责将编译阶段生成的汇编代码文件翻译成对应的目标文件,有时也称为模块。通常,每个源代码文件都对应一个汇编代码文件,每个汇编代码文件都对应一个目标文件。如果只生成目标文件,需要将“-c”选项传递给gcc,即:

目标文件可以彼此独立编译,因此编译器在汇编目标文件时无法知道其他目标文件的内存地址,这就是为什么需要可重定位的目标文件。目标文件可以以任何顺序链接在一起,形成一个完整的二进制可执行目标文件。

我们可以使用汇编器as或者编译器gcc,根据Prog.s生成可重定位的目标文件Prog.o。

目标文件Prog.o是对应源程序Prog.c的二进制形式,如下所示:

汇编器会给每个变量和命令指定一个内存位置,这个位置一般用符号或者偏移量来表示。可以使用命令nm来查看符号,即:

目标文件通常有三种类型:

(1)可重定位的目标文件。可重定位的目标文件的典型格式如图2.2所示,这种类型的目标文件包含了可以和其他可重定位目标文件结合的二进制代码和数据,在链接时可形成一个可执行的目标文件。

图2.2 可重定位的目标文件的典型格式

在链接阶段之前引用了其他目标文件或外部库中函数或变量的目标文件,其引用的代码和数据被放置的地址还不确定,因此这种类型的目标文件在编译时会包含重新定位信息。这些重定位信息会告知链接器所引用的外部函数或变量最终应如何被解析。

(2)共享目标文件。这是一种特殊的可重定位的目标文件,是由编译器和汇编器生成的,在装载时或者运行时可被加载到内存并进行动态链接。

(3)可执行的目标文件。可执行的目标文件是由链接器生成的,其典型格式如图2.3所示。这种类型的目标文件包含了可以直接装载到内存并执行的二进制代码和数据。

其中的.text、.rodata和.data等节(Section)和可重定位的目标文件类似,不同之处在于这些节已经重定位到其运行时的内存地址。.init节定义了_init()函数,由程序的初始化代码调用。由于可执行的目标文件已经进行链接并重定位,因此,这里 没有与.rel相关的节 。在命令行运行可执行的目标文件时,加载程序会首先将可执行的目标文件的代码和数据复制到主内存中,然后跳转到程序入口点(即位于_start符号的地址)运行程序。

图2.3 可执行的目标文件的典型格式 ElWLD613cf5K5+Jl07vHGxMPkGV8nRSOH+9G6jFyhid9Wy7IAZUCgkE4Rup93gCb

点击中间区域
呼出菜单
上一章
目录
下一章
×