【发布时间】:2020-03-09 03:43:42
【问题描述】:
在 LC-3 中,当您使用 BLKW 时,如何将内存块初始化为位于 x3102 位置而不是下一个可用内存位置?
【问题讨论】:
在 LC-3 中,当您使用 BLKW 时,如何将内存块初始化为位于 x3102 位置而不是下一个可用内存位置?
【问题讨论】:
首先,让我们注意一下,根据内存映射(例如,至少在 x3000-xFDFF 范围内),16 位地址空间的所有内存都可供您使用,并且它已被初始化归零;可以随意使用。
一般来说,LC-3 汇编器不允许在整个文件中使用多个 .ORIG 指令,相反,它们需要在文件开头使用一个。如果他们确实允许后续的 .ORIG 指令,这将是完成您所询问的内容的一种方式。
但即使他们这样做了,我们也会经常遇到指令偏移编码限制。因此,我将在下面展示另一种解决方案。
但首先,让我们看看指令偏移/立即编码限制。
通常的数据存储器访问指令格式的偏移量非常有限,只有 9 位值(+/- 约 256),并且偏移量是 pc 相关的。因此,例如,以下内容将不起作用:
.ORIG x3000
LEA R0, TESTA
LD R1, TESTA
LEA R2, TESTB ; will get an error due to instruction offset encoding limitation
LD R3, TESTB ; will get an error due to instruction offset encoding limitation
HALT
TESTA
.FILL #1234
.BLKW xFA ; exactly enough padding to relocate TESTB to x3100
TESTB
.FILL #4321 ; which we can initialize with a non-zero value
.END
这说明:虽然这将成功地将 TESTB 放置在 x3100,但由于 9 位 pc 相对位移有限,LEA 或 LD 指令无法到达它。
(还有另一个实际限制是,随着指令的添加,.BLKW 操作数的大小必须缩小,这显然很痛苦——这方面可以通过在其中支持 .ORIG 指令来消除。 )
因此,大块和其他类似的替代方案是使用零初始化内存,并使用附近的指针变量引用其他内存:使用LD 加载地址,而不是LEA,和@ 987654329@ 访问一个值而不是LD。
.ORIG x3000
LEA R0, TESTA
LD R1, TESTA
LD R2, TESTBRef ; will put x3100 into R3
LDI R3, TESTBRef ; will access the memory value at address x3100..
HALT
TESTA
.FILL #1234
TESTBRef ; a nearby data pointer, that points using the full 16-bits
.FILL x3100
.END
在上面的后者中,没有声明在x3100 保留存储,我们也不能使用非零初始化(例如,没有字符串、没有预定义数组)来初始化x3100 的存储。
使用了数据到数据的指针TESTBRef。与代码到代码/数据引用(即 指令 引用代码或数据)不同,数据到代码/数据
(即 data 引用代码或数据)指针具有可用于指向的所有 16 位。
因此,一旦我们使用这种方法,即简单地使用其他内存,我们就会放弃将标签自动放置在其他标签之后(对于那些其他区域),并且也放弃非零初始化。
一些 LC-3 汇编器允许多个文件,每个都允许自己的 .ORIG 指令——因此通过使用多个文件,我们可以将代码和数据放置在地址空间的不同位置。但是,代码到数据的指令偏移编码限制仍然适用,因此,您最终可能最终还是要手动管理其他此类内存区域,并且还要使用数据指针。
请注意,JSR 指令有一个 11 位的偏移量,因此代码到代码的引用可以比代码到数据的引用更远。
【讨论】: