LC-3 计算字符串中字符出现次数的程序
LC-3 Program to Count occurrences of a char in a string
我正在尝试编写一个 LC-3 程序,该程序将计算用户在硬编码字符串中输入的字符出现的次数。我遇到麻烦的部分是测试这两个字符是否相等,而且我也无法移动字符串中的下一个字符来测试它。
;计算字符串中字符出现次数的程序
.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
这基本上是一个如何处理字符串和数组的问题。一开始,当你
LD R1, word
你要去"word"代表的内存地址并得到一个字节。所以在那个时候 R1='h'.
但是,稍后您尝试使用
遍历字符串
ADD R1, R1, #1
现在,R1='h'+1='i',这不是您想要的。您所做的是递增从内存地址获取的数据,而不是递增地址本身。因此,不是从 LD 开始,它从内存标签加载数据,而是从 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。您还假设寄存器被初始化为零。模拟器上有一个命令可以在启动之前随机化内存——这将对您的代码造成彻底破坏,并且可能发生在真实硬件中。读取之前先初始化内存。
我解决了:
.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
我正在尝试编写一个 LC-3 程序,该程序将计算用户在硬编码字符串中输入的字符出现的次数。我遇到麻烦的部分是测试这两个字符是否相等,而且我也无法移动字符串中的下一个字符来测试它。 ;计算字符串中字符出现次数的程序
.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
这基本上是一个如何处理字符串和数组的问题。一开始,当你
LD R1, word
你要去"word"代表的内存地址并得到一个字节。所以在那个时候 R1='h'.
但是,稍后您尝试使用
遍历字符串ADD R1, R1, #1
现在,R1='h'+1='i',这不是您想要的。您所做的是递增从内存地址获取的数据,而不是递增地址本身。因此,不是从 LD 开始,它从内存标签加载数据,而是从 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。您还假设寄存器被初始化为零。模拟器上有一个命令可以在启动之前随机化内存——这将对您的代码造成彻底破坏,并且可能发生在真实硬件中。读取之前先初始化内存。
我解决了:
.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