- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
第 4 章 存储空间分配
$Revision: 2.3 $
$Date: 1999/06/15 03:30:36 $
链接器或加载器的首要任务是存储分配.一旦分配了存储空间后,链接器就可以继续
进行符号绑定和代码调整.在一个可链接目标文件中定义的多数符号都是相对于文件内的存
储区域定义的,所以只有存储区域确定了才能够进行符号解析.
与链接的其它方面情况相似,存储分配的基本问题是很简单的,但处理计算机体系结
构和编程语言语义特性的细节让问题复杂起来.存储分配的大多数工作都可以通过优雅和相
对架构无关的方法来处理,但总有一些细节需要特定机器的专门技巧来解决.
段和地址
每个目标或可执行文件都会采用目标地址空间的某种模式.通常这里的目标是目标计
算机的应用程序地址空间,但某些情况下(例如共享库)也会是其它东西.在一个重定位链
接器或加载器中的基本问题是要确保程序中的所有段都被定义并具有地址,并且这些地址不
能发生重叠(除非有意这样).
每一个链接器输入文件都包含一系列各种类型的段.不同类型的段以不同的方式来处
理.通常,所有相同类型的段,诸如可执行代码段,会在输出文件中被合并为一个段.有时
候段是在其它段的基础上合并得到的(如 Fortran 的公共块), 以及在越来越多的情况下
(如共享库和 C++专有特性),链接器本身会创建一些段并将其放置在输出中.
存储布局是一个两遍的过程,这是因为每个段的地址在所有其它段的大小未确定
前是无法分配的.
简单的存储布局
在一种简单而不现实的情形下,链接器的输入文件包含一系列的模块,将它们称为 M1,
M2, ... Mn,每一个模块都包含一个单独的段,从位置 0 开始长度依次为 L1, L2, ... Ln,并
且目标地址空间也是从 0 开始.如图 1 所示.
图4-1:单独段的存储空间分配
从位置 0 开始的多个段按照一个跟着另一个的方式重定位
链接器或加载器依次检查各个模块,按顺序分配存储空间.模块 Mi 的起始地址为从 L1
到 Li-1 相加的总和,链接得到的程序长度为从 L1 到 Ln 相加的总和.
多数体系结构要求数据必须对齐于字边界,或至少在对齐时运行速度会更快些.因此
链接器通常会将 Li 扩充到目标体系结构最严格的对齐边界(通常是 4 或 8 个字节)的倍数.
例 1:假定一个称为 main 的主程序要与三个分别称为 calif,mass 和 newyork 的子例程
链接(按照地理位置划分风险投资).每个例程的大小为(16 进制数字):
名称尺寸
ain1017
calif 920
ass 615
newyork1390
假定从 16 进制的地址 1000 处开始分配存储空间,并且要求 4 字节对齐,那么存储分配
的结果可能是:
名称位置
ain1000 - 2016
calif2018 - 2937
ass2938 - 2f4c
newyork2f50 - 42df
由于对齐的原因,2017 处的一个字节和 2f4d 处的三个字节被浪费了,但无须忧虑.
多种段类型
除最简单格式外所有的目标格式,都具有多种段的类型,链接器需要将所有输入模块
中相应的段组合在一起.在具有文本和数据段的 UNIX 系统上,被链接的文件需要将所有的
文本段都集中在一起,然后跟着的是所有的数据,在后面是逻辑上的 BSS(即使 BSS 在输出
文件中不占空间,它仍然需要分配空间来解析 BSS 符号,并指明当输出文件被加载时要分配
的 BSS 空间尺寸).这就需要两级存储分配策略.
现在每一个模块 Mi 具有大小为 Ti 的文本段,大小为 Di 的数据段, 以及大小为 Bi 的 BSS
段,如图 2 所示.
图4-2:多种段的存储分配
按类型将文本,数据和 BSS 段分别归并
在读入每个输入模块时,链接器为每个 Ti,Di,Bi 按照(就像是)每个段都各自从位置
0 处开始的方式分配空间.在读入了所有的输入文件后,链接器就可以知道这三种段各自总
的大小Ttot,Dtot 和 Btot. 由于数据段跟在文本段之后,链接器将 Ttot 加到每一个数据段所分
配的地址上,接着, 由于 BSS 跟在文本和数据段之后,所以链接器会将 Ttot,Dtot 的和加到每
一个 BSS 段分配的地址上.
同样,链接器通常会将分配的大小按照对齐要求扩充补齐.
段与页面的对齐
如果文本和数据被加载到独立的内存页中,这也是通常的情况,文本段的大小必须扩
充为一个整页,相应的数据和 BSS 段的位置也要进行调整.很多 UNIX 系统都使用一种技巧
来节省文件空间, 即在目
文档评论(0)