可以立即将程序计数器移动到遥远的内存地址吗?

Possible to move Program Counter to a far-off memory address immediately?

我正在尝试调整一个程序,该程序计算文件中 char 的出现次数,以存储在遥远的内存位置发生匹配的十六进制地址列表。代码:

011 0000 0000 0000 ;Codes x3000 as Load-address of program
0101 010 010 1 00000 ;R2 <- 0
0010 011 000010000 ;R3 <- M[x3012]
1111 0000 0010 0011 ;TRAP x23 (Loads INPUT into R0)
0110 001 011 000000 ;R1 <- M[R3]
;LOOP BEGINS HERE
0001 100 001 1 11100 ;R4 <- R1 - EOT
0000 010 000001000 ;If above = 0, exit loop
1001 001 001 111111 ;R1 <- NOT R1
0001 001 001 1 00001 ;R1 <- R1 + 1
0001 001 001 0 00 000 ;R1 <- R1 + R0
0000 101 000000001 ;If above != 0, do NOT increment counter
0001 010 010 1 00001 ;R2 <- R2 + 1 (increment counter)
0001 011 011 1 00001 ;R3 <- R3 + 1 (increments pointer to next char in file)
0110 001 011 000000 ;R1 <- M[R3] (loads next char into R1)
0000 111 111110110 ;BRnzp x3004 (unconditionally RETURN to loop start)
;LOOP ENDS HERE
0010 000 000000100 ;R0 <- M[x3013]
0001 000 000 0 00 010 ;R0 <- R0 + R2
1111 0000 0010 0001 ;TRAP x21 (OUTPUT)
1111 0000 0010 0101 ;TRAP x25 (HALT)
0011 0001 0000 0000 ;Codes x3100 for the starting address of the file
0000 000 000110000 ;ASCII template

所以我的程序从内存地址 x3000 开始。我想开始处理 x300B 列表的指令集(在 "increment R2" 指令下方)。问题是,我想从 x3500 开始列表,但我不知道 "efficient" 到达那里的方法。

我原来的计划是使用间接加载(LDI)指令,但由于符号扩展,9位偏移量最多只允许偏移量x00FF = 0000 0000 1111 1111,这只需要我从x300C(程序计数器递增的 x300B)到 x310B。

我想出的唯一真正的 "workaround" 是使用加载有效地址 (LEA) 指令将地址 x310B 存储在寄存器(比如 R5)中,然后将值 x00FF 存储在 R6 中,并重复将 R6 添加到 R5 直到我到达 x3408(这将需要 3 个 ADD 指令),此时我将值 x0092 存储在 R6 中,将其添加到 R5,并且我最终在 R5 中有 x3500。

到那时,剩下的就很简单了(将 R3 存储在(R5 + 计数器)中,这会将当前匹配的地址放入列表中适当的 "spot")

我还没有真正做到这一点,因为我上面描述的进入 x3500 的整个方法看起来真的很麻烦和笨拙。我无法摆脱必须有更好、更快的方法来同时移动那么多内存地址的感觉。

是否可以在一条指令中从 x300C 移动到 x3500?即使是两个也会比我现在拥有的更好。

您可能不想这样做,但更简单的方法是使用 LD(操作码 0010)和 LDR(操作码 0110)来执行此操作。无需让 PC 跳转到 x3500(这将开始执行数组中的数据,这是错误的)

有一个地址包含位 0011 0101 0000 0000 操作码 0010 将允许您将 x3500 拉入寄存器。然后,操作码 0110 将允许您从数组中加载值。