连接器需要确定输出段分配在存储器的具体位置,为了达到这一目的,必须有一个完成该目标的存储器模型,MEMORY伪指令就是用来完成此目标存储器的模型。可以定义各种形式的村吃起,以及它们所占的地址范围。
使用MEMORY定义一个存储器模型以后,再用SECTIONS伪指令将各输出段定位带锁定义的存储器。
每一个存储器范围内包含以下几个属性:
NAME
Starting address
Length
Optional set attributes
*可选的设置属性
OPtional fill specification
*可选填的标准
MEMORY
{
name1(attr) : origin = 0xiiii iiiih, length = 0xiiiiiiiih, fill = 0xiiiiiiiih
name2(attr) :
... ... 后面格式相同
}
name: 存储区命名
64个字符以内 不能有数字
attr: attributes
4个属性 R可读,W可写,X包含可执行代码,I可以被初始化
origin, or, o : 32位常量 除了二进制都可以 存储区起始地址
length, len, l: 存储区长度 22位常量 除了二进制都可以
fill, f
:可选,16位常量,填充分配段的存储器范围
MEMORY
{
RFILE (RW) : 0 = 0x0020h, l = 0x1000, f = 0xffffffffh
}
MEMORY
{
PMEM: o = 00000000h l = 00010000h
BMEM: o = 00010000h l = 00030000h
}
SECTION伪指令
1,输入段组合到输出段
2,在可执行程序中定义输出段
3,规定存储器如何存放输出段
4,可以重新命名输出段
格式:
SECTIONS
{
}
加载位置(3种表示):
load = allocation
allocation
> allocation
运行位置(2种):
run = allocation
run > allocation
显式指定组成输出段的输入段。
SECIONS
{
.text :
{
f1.obj(.text)
f2.obj(.sec1)
f3.obj
f4.obj(.text, sec2)
}
}
SECTIONGS
{
.text: {*(.text) }
将所有输入文件中没有被分配的.text段统一链接,放入输出的.text
}
向多个存储器区域输出:
SECTIONS
{
.text : {} > P_MEM1 | P_MEM2 | P_MEM3
}
分裂输出:
SECTIONS
{
.text : {*(.text)} >>
P_MEM1 | P_MEM2 | P_MEM3
}
>> 操作符,表明一段输出在必要的时间可被分裂到指定的存储区域内。
把文档库的一个特成员分配到输出段
boot > BOOT1
{
-lrtsXX.lib<boot.obj> (.text)
-lrtsXX.lib<exit.obj> (.text)
}
指定加载地址和运行地址
可能有关键的代码加载到外部慢速存储器里,但是该部分代码比较常用,需要经常调用到,这是可以使用SECTIONS伪指令连接器给
一个段定位两次,一次设置它的加载地址,另一次设置其运行地址
.fir: load = SLOW_MEM, run = FAST_MEM
.data: load = SLOW_MEM, align = 32 , run = FAST_MEM
或者对齐仅对加载地址:
.data: load = (SLOW_MEM align 32), run = FAST_MEM
load 加载地址
run 运行地址 align
让指令按照XX字节对齐,虽然浪费内存空间,但是可以让cpu更快寻址,更快执行指令