一、关于段的基本知识
段(section)是指连续占有存储空间的数据或者代码块。在编写汇编语言源程序时,程序按段组织,每行汇编代码都属于某个段,并由段汇编伪指令指明该指令的属性。段是目标文件中可以重新定位的最小单元。COFF
目标文件中至少包含三个默认的段:
.text段 (文本段) 通常包含可执行代码
.data段 (数据段) 通常包含初始化的数据
.bss段 (保留空间段) 通常为没有初始化的变量保留空间
此外,还可以使用自定义段,这些段属于一下两个基本类型:
(1)、初始化段:包括.text段、.data段和由汇编伪指令.sect产生的自定义段。
(2)、未初始化段:为没有初始化的数据保留空间,包括.bss段和由汇编伪指令.usect产生的自定义段。
二、汇编器对段的处理
汇编器可以区分属于某个段的汇编语言程序部分。汇编器有6个伪指令支持该功能:
.bss
.usect
.text
.data
.sect
.asect
(1)、未初始化段
未初始化段通常分配到RAM中,一个程序可以实时使用这些空间创建和保存变量。未初始化段由汇编伪指令.bss和.usect创建,格式分别如下:
.bss symbol,size in words ,[blocking flags]
symbol .usect "section name",size in words, [blocking flags]
.symbol指向.bss或.usect伪指令保留的第一个字。
.sect、.data、.text和.asect指令告诉汇编器停止汇编进入当前的段,而开始汇编进入指定的段,但是.bss和.usect指令不停止当前段的汇编,它只是临时的离开当前的段。.bss和.usect指令可以出现在初始化段中的任何地方而不会影响他们的内容。
(2)、初始化段
初始化段包括可执行代码或者初始化数据。这些段的内容存储在目标文件中并在程序载入时存储在存储器中。4个段伪指令可以告诉汇编器将代码或者数据放在哪个段中,格式如下:
.text
.data
.sect "section name"
.asect "section name", address
段通过一个迭代的过程建立。例如当汇编器第一次遇到一个.data伪指令时,.data段是空的。跟在第一个.data伪指令后的指令被汇编进.data段,直到遇到.text、.sect或者.asect伪指令。如果汇编器在后面还遇到.data伪指令,则将跟在这个.data伪指令后的指令汇编进已经存在的.data段当中。这样就实现了将.data段分配到单个可连续分配的空间。
(3)、自定义段
可以使用三个伪指令来产生自定义段:
.usect产生类似.bss的段,这些段被分配到RAM中。
.sect和.asect指令产生类似.text和.data的段,可以包含代码或者数据。.sect产生地址可以重新定位的段,.asect指令产生具有绝对地址的段。
这三个伪指令的使用方法如下:
symbol .usect "section name", size in words, [blocking flags]
.sect "section name"
.asect "section name", address
三、链接器对段的处理
链接器的主要功能是将汇编器产生的COFF格式的obj文件中的段作为构成块,用这些块作为输入块,产生可执行的COFF输出模块,并为这些输出模块选择存储器地址。链接器有两条指令支持所述的功能:
(1)MEMORY伪指令
用来定义目标系统的存储空间。MEMORY指令可以定义存储空间,并定义存储空间的起始地址和长度。
(2)SECTION伪指令
该指令告诉链接器如何将输入段结合成输出段,并告诉链接器将输出段放在存储器的什么位置。
四、COFF文件中的符号
(1)外部符号
所谓外部符号,是在一个模块中定义而在另一个模块中引用的符号。可以用.def、.ref和.global命令来指出某些符号为外部符号:
.def 在当前模块中定义,而在别的模块中可以引用的符号
.ref 在别的模块中定义,而可以在当前模块中引用的符号
.global 可以是上边的随便一种情况
阅读(3283) | 评论(0) | 转发(1) |