可以立即将程序计数器移动到遥远的内存地址吗?
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 将允许您从数组中加载值。
我正在尝试调整一个程序,该程序计算文件中 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 将允许您从数组中加载值。