ZHCUAU3J January 2018 – March 2024
MEMORY 指令可识别实际存在于目标系统中并可被程序使用的存储器范围。每个范围都有若干特性:
使用 MEMORY 指令时,请务必确定程序在运行时可以访问的所有存储器范围。MEMORY 指令定义的存储器会被配置;而未使用 MEMORY 指令显式指定的任何存储器则不会被配置。链接器不会将程序的任何部分放入未配置的存储器中。用户可通过不在 MEMORY 指令语句中添加相应的地址范围来表示不存在的存储器空间。
在命令文件中指定 MEMORY 指令的方法是使用 MEMORY(大写)一词后跟用大括号括起来的内存范围规格列表。下面的示例中的 MEMORY 指令定义了一个系统,该系统在地址 0x0000 0000 处具有 4K 字节的快速外部存储器,在地址 0x0000 1000 处具有 2K 字节的慢速外部存储器,在地址 0x1000 0000 处具有 4K 字节的慢速外部存储器。它还演示了存储器范围表达式以及起始/结束/大小地址运算符的使用方式(请参阅节 12.5.4.3)。
/********************************************************/
/* Sample command file with MEMORY directive */
/********************************************************/
file1.c.obj file2.c.obj /* Input files */
--output_file=prog.out /* Options */
#define BUFFER 0
MEMORY
{
FAST_MEM (RX): origin = 0x00000000 length = 0x00001000 + BUFFER
SLOW_MEM (RW): origin = end(FAST_MEM) length = 0x00001800 - size(FAST_MEM)
EXT_MEM (RX): origin = 0x10000000 length = size(FAST_MEM)
MEMORY 指令的一般语法如下: | |
MEMORY | |
{ | |
name 1 [(attr )] : origin = expr , length = expr [, fill = constant] [ LAST(sym )] | |
. | |
. | |
name n [(attr )] : origin = expr , length = expr [, fill = constant] [ LAST(sym )] | |
} |
name | 指定存储器范围的名称。存储器名称可包含 1 到 64 个字符;有效字符包括 A-Z、a-z、$、. 和 _。名称对链接器而言没有特殊意义,它们只用于标识存储器范围。存储器范围名称是链接器的内部名称,不会保留在输出文件或符号表中。所有存储器范围必须具有唯一名称且不得重叠。 | |
attr | 指定与命名的范围关联的一到四个属性。属性是可选的;使用时,必须将它们括在圆括号中。属性可以将输出段的分配限制在特定存储器范围内。如果不使用任何属性,则可以将任何输出段分配到任何范围内,不受限制。任何未指定属性的存储器(包括默认模型中的所有存储器)都具有所有这四个属性。有效属性为: | |
R | 指定可以读取存储器。 | |
W | 指定可以写入存储器。 | |
X | 指定存储器可包含可执行代码。 | |
I | 指定可以初始化存储器。 | |
origin | 指定存储器范围的起始地址;输入形式为 origin、org 或 o。相应的值(以字节为单位指定)是一个 64 位的整数常量表达式,可以采用十进制、八进制或十六进制格式。 | |
length | 指定存储器范围的长度;输入形式为 length、len 或 l。相应的值(以字节为单位指定)是一个 64 位的整数常量表达式,可以采用十进制、八进制或十六进制格式。 | |
fill | 指定存储器范围的填充字符;输入形式为 fill 或 f。填充值是可选的。相应的值是一个 的整数常量,可以采用十进制、八进制或十六进制格式。填充值用于填充未分配给段的存储器范围区域。 | |
LAST | (可选)指定一个符号,可在运行时将其用于查找存储器范围中上次分配字节的地址。请参阅节 12.5.9.8。 |
填充存储器范围:如果为大存储器范围指定填充值,则输出文件将非常大,因为填充存储器范围(即使填充值为 0s)会导致为该范围内所有未分配的存储器块生成原始数据。
以下示例指定了一个具有 R 和 W 属性以及填充常量 0FFFFFFFFh 的存储器范围:
MEMORY
{
RFILE (RW) : o = 0x00000020, l = 0x00001000, f = 0xFFFFFFFF
}
通常将 MEMORY 指令与 SECTIONS 指令结合使用以控制输出段的放置。有关 SECTIONS 指令的更多信息,请参阅节 12.5.5。