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