首页 > 解决方案 > LC-3:BLKW 何指定存储数据的内存位置?

问题描述

在 LC-3 中,当您使用 BLKW 时,如何将内存块初始化为位置 x3102 而不是下一个可用内存位置?

标签: memorystorelc3

解决方案


首先,让我们注意一下,根据内存映射(例如,至少在 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

这个说明性的:虽然这将成功放置在 x3100,但由于 9 位 pc 相对位移有限TESTB,因此无法通过 theLEA或指令到达。LD

(还有另一个实际限制是,随着指令的添加,.BLKW操作数的大小必须缩小,这显然很痛苦——这方面可以通过在其中支持.ORIG指令来消除。)

因此,大块和其他类似的替代方案是诉诸使用零初始化内存,并使用附近的指针变量引用其他内存:使用LD加载地址而不是LEALDI访问值而不是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。与代码到代码/数据引用(即指令引用代码或数据)不同,数据到代码/数据(即数据引用代码或数据)指针具有可用于指向的所有 16 位。

因此,一旦我们使用这种方法,即简单地使用其他内存,我们就放弃了在其他标签之后自动放置标签(对于那些其他区域),并且也放弃了非零初始化。


一些 LC-3 汇编器将允许多个文件,并且每个文件都允许它们自己的.ORIG指令——因此通过使用多个文件,我们可以将代码和数据放置在地址空间中的不同位置。但是,代码到数据的指令偏移编码限制仍然适用,因此,无论如何,您最终可能会手动管理其他此类内存区域,并且也使用数据指针。


请注意,JSR 指令具有 11 位偏移量,因此代码到代码引用可以比代码到数据引用更远。


推荐阅读