自己动手构造编译系统:编译、汇编与链接2.5.1 地址空间分配

2.5.1  地址空间分配

 

   在汇编器生成的目标文件内,是无法确定数据段和代码段的虚拟地址的,因此将它们的段地址都设置为0。链接器是这些代码和数据加载到内存执行之前的最后一道处理,因此要为它们分配段的基址。

  链接器按照目标文件的输入顺序扫描文件信息,从每个文件的段表中提取出各个文件的代码段和数据段的信息。假设可执行文件段加载后的起始地址是0x080408000,链接器从该地址开始,就像“摆积木”似的将所有文件的同类型段合并,按照代码段、数据段、“.bss”段的顺序依次决定每个段的起始地址,此时需要考虑段间对齐产生的偏移以及特殊的地址计算方式(参考第5章关于程序头表的描述)。

  图2-18展示了链接器将目标文件a.o和b.o链接为可执行文件ab时,地址空间分配的效果。a.o的数据段大小为0x08字节,代码段大小为0x4a字节;b.o的数据段大小为0x04字节,代码段大小为0x21字节。链接后的可执行文件ab的数据段大小为0x0c字节,代码段大小为0x6d字节(对齐b.o的代码段消耗2字节)。代码段的起始地址为0x08048080,结束地址为0x08048080+0x6d=0x080480ed。数据段起始地址为0x080490f0,结束地址为0x080490f0+ 0x0c=0x080490fc。

 

图2-18  地址空间分配

时间: 2024-07-29 13:59:12

自己动手构造编译系统:编译、汇编与链接2.5.1 地址空间分配的相关文章

自己动手构造编译系统:编译、汇编与链接

"自己动手系列" 自己动手构造编译系统 编译.汇编与链接 范志东  张琼声  著 图书在版编目(CIP)数据 自己动手构造编译系统:编译.汇编与链接 / 范志东,张琼声著. -北京:机械工业出版社,2016.7 (自己动手系列) ISBN 978-7-111-54355-8 I. 自- II. ①范- ②张- III. 编译器 IV. TP314 中国版本图书馆CIP数据核字(2016)第163077号 自己动手构造编译系统:编译.汇编与链接 出版发行:机械工业出版社(北京市西城区百万

自己动手构造编译系统:编译、汇编与链接导读

Preface前 言 本书适合谁读 本书是一本描述编译系统实现的书籍.这里使用"编译系统"一词,主要是为了与市面上描述编译器实现的书籍进行区分.本书描述的编译系统不仅包含编译器的实现,还包括汇编器.链接器的实现,以及机器指令与可执行文件格式的知识.因此,本书使用"编译系统"一词作为编译器.汇编器和链接器的统称. 本书的目的是希望读者能通过阅读本书清晰地认识编译系统的工作流程,并能自己尝试构造一个完整的编译系统.为了使读者更容易理解和学习编译系统的构造方法,本书将描述

自己动手构造编译系统:编译、汇编与链接1.3 GCC的工作流程

1.3  GCC的工作流程       在着手构造编译系统之前,需要先介绍编译系统应该做的事情,而最具参考价值的资料就是主流编译器的实现.GNU的GCC编译器是工业化编译器的代表,因此我们先了解GCC都在做什么. 我们写一个最简单的"HelloWorld"程序,代码存储在源文件hello.c中,源文件内容如下: #include<stdio.h> int main() {      printf("Hello World!");      return

自己动手构造编译系统:编译、汇编与链接2.6 本章小结

2.6  本章小结      本章介绍了编译系统的设计,并按照编译.汇编和链接的顺序阐述了它们的内部实现.同时,也介绍了x86指令和ELF文件结构等与操作系统及硬件相关的知识. 通过以上的描述,可以了解高级语言如何被一步步转化为汇编语言,以及词法分析.语法分析.语义分析.符号表和代码生成作为编译器的主要模块,其内部是如何实现的.汇编器在把汇编语言程序转化为二进制机器代码时,做了怎样的工作:汇编器的词法和语法分析与编译器有何不同:汇编器如何生成二进制指令和目标文件的信息.链接器在处理目标文件时是如

自己动手构造编译系统:编译、汇编与链接2.1 编译程序的设计

第2章 编译系统设计 麻雀虽小,五脏俱全. --<围城>    一个完善的工业化编译系统是非常复杂的,为了清晰地描述它的结构,理解编译系统的基本流程,不得不对它进行"大刀阔斧"地删减.这为自 己动手实现一个简单但基本功能完整的编译系统提供了可能.虽然本书设计的是简化后的编译系统,但保留了编译系统的关键流程.正所 谓"麻雀虽小,五脏俱全",本章从全局的角度描述了编译系统的基本结构,并按照编译.汇编和链接的流程来介绍其设计. 2.1  编译程序的设计 编译器

自己动手构造编译系统:编译、汇编与链接1.2 历史渊源

1.2  历史渊源    历史上很多新鲜事物的出现都不是偶然的,计算机学科的技术和知识如此,编译系统也不例外,它的产生来源于编程工作的需求.编程本质上是人与计算机交流,人们使用计算机解决问题,必须把问题转化为计算机所能理解的方式.当问题规模逐渐增大时,编程的劳动量自然会变得繁重.编译系统的出现在一定程度上降低了编程的难度和复杂度. 在计算机刚刚诞生的年代,人们只能通过二进制机器指令指挥计算机工作,计算机程序是依靠人工拨动计算机控制面板上的开关被输入到计算机内部的.后来人们想到使用穿孔卡片来代替原

自己动手构造编译系统:编译、汇编与链接2.5.2 符号解析

2.5.2  符号解析     如果说地址空间分配是为段指定地址的话,那么符号解析就是为段内的符号指定地址.对于一个汇编文件来说,它内部使用的符号分为两类:一类来自自身定义的符号,称为内部符号.内部符号在其段内的偏移是确定的,当段的起始地址指定完毕后,内部符号的地址按照如下方式计算: 符号地址 = 符号所在段基址 + 符号所在段内偏移 另一类来自其他文件定义的符号,本地文件只是使用该符号,这类符号称为外部符号.外部符号地址在本地文件内是无法确定的,但是外部符号总定义在其他文件中.外部符号相对于定

自己动手构造编译系统:编译、汇编与链接2.5.3 重定位 

2.5.3  重定位             重定位从本质上来说就是地址修正.由于目标文件在链接之前不能获取自己所使用符号的虚拟地址信息,因此导致依赖于这些符号的数据定义或者指令信息缺失.汇编器在生成目标文件的时候就记录下所有需要重定位的信息.链接器获取这些重定位信息,并按照重定位信息的含义修改已经生成的代码,使得最终的代码正确.完整. 之所以称重定位是链接器最关键的操作,主要是因为地址空间分配和符号解析都是为重定位做准备的.程序在运行时,段的信息.符号的信息都显得"微不足道",因为C

自己动手构造编译系统:编译、汇编与链接2.5 链接程序的设计

2.5  链接程序的设计        本书欲设计一个简洁的静态链接器,以满足上述汇编器产生的目标文件的链接需求.它的工作内容是把多个可重定位目标文件正确地合并为可执行文件,但链接器不是对文件进行简单的物理合并.除了合并同类的段外,链接器需要为段分配合适的地址空间,还需要分析目标文件符号定义的完整性,同时对符号的地址信息进行解析,最后还有链接器最关键的工作--重定位.本书设计的链接器结构如图2-17所示.   图2-17  链接器结构 段的地址空间分配除了为加载器提供相应的信息外,还可为段内符号