我正在尝试编写一个LC-3程序,该程序将计算用户在硬编码字符串中输入的char出现次数。我遇到麻烦的部分是测试两个字符是否相等,而且我也无法移动字符串中的下一个字符来测试它。 ;程序计算字符串中char的出现次数
.ORIG x3000
LD R3, POSASC ;Loads R3 with #48
LD R4, NEGASC
LD R1, word ;R1 = word
ADD R6, R6, #5 ;Length of word
GETC ;Gets the char
OUT ;Prints the char
ADD R2, R2, R0 ;Stores the char in R2
;ADD R2, R2, R4 ;To ascii
AND R0, R0, #0 ;set R0 back to 0
LOOP
AND R5, R2, R1 ;check if char is equal
ADD R1, R1, #1 ;increment to next char in word
ADD R6, R6, #-1
BRnp LOOP
ADD R0, R0, R5 ;Set R0 to # of occurrences
OUT ;Print # of occurrences
HALT
POSASC .FILL x0030 ;#48
word .STRINGZ "hello" ;word to count occurrences of a char
NEGASC .FILL xFFD0 ;#-48
.END
答案 0 :(得分:0)
这基本上是如何使用字符串和数组的问题。一开始,当你
LD R1, word
你要去“word”代表并获取一个字节的内存地址。所以在这一点上R1 ='h'。
但是,稍后您尝试使用
遍历字符串ADD R1, R1, #1
现在,R1 ='h'+ 1 ='i',这不是你想要的。你所做的就是增加你从内存地址获得的数据,而不是递增地址本身。因此,不是从LD(从内存标签加载数据)开始,而是从LEA开始,LEA加载内存标签的有效地址。还有一个加载指令也会派上用场,它就是LDR。这将从位于寄存器中的地址加载数据。所以:
LD R1,word ; "h"
LEA R2,word ; memory address of word
LDR R3,R2,#0 ; "h"
word: .STRINGZ "hello"
现在,如果您认为R2 = R2 +#1不会增加数据本身,而是增加地址,您可以看到以下内容:
LD R1,word ; "h"
ADD R1,R1,#1 ; "h"+1="i"
LEA R2,word ; memory address of word
ADD R2,R2,#1 ; (memory address of word) +1
LDR R3,R2,#0 ; "e"
word: .STRINGZ "hello"
希望这可以解决您的问题。
P.S。您还假设寄存器初始化为零。模拟器上有一个命令可以在启动之前使内存随机化 - 这将对您的代码造成严重破坏,并且可能在真实硬件中发生。在阅读之前初始化内存。
答案 1 :(得分:0)
我解决了它:
.ORIG x3000
LEA R1, word ;load address of word
LD R4, ascii
GETc ;get char
OUT ;display char
ADD R6, R6, #5 ;# of chars in word
ADD R2, R0, R2 ;put char in R2
NOT R2, R2
ADD R2, R2, #1 ;R2 now has 2's complement of char
next AND R0, R0, #0 ;clear R0
LDR R0, R1, #0 ;get char of word
ADD R0, R0, R2 ;add 2's complement to char of word
BRz equals
BRnp unEqual
equals ADD R5, R5, #1 ;add 1 to counter if equal
unEqual ADD R1, R1, #1 ;move to next letter
ADD R6, R6, #-1 ;decrement # of letters in word
AND R0, R0, #0 ;clear R0
ADD R0, R6, R0 ;test if done
BRp next
ADD R0, R5, R0 ;put counter in R0
ADD R0, R4, R0 ;convert to ascii
OUT
HALT
word .STRINGz "hello"
ascii .FILL #48
.END