在MIPS中计算字母出现次数并打印单词整数数组

Counting Letter Occurrence and Printing a Word Integer Array in MIPS

提问人:TJream 提问时间:10/31/2023 最后编辑:TJream 更新时间:10/31/2023 访问量:31

问:

我目前正在为一门汇编语言课程做作业,并且遇到了一个问题,为什么它无法正常工作。

我需要将每个字母 (a-z) 的出现次数计算成一个 26 个整数单词数组(array[0] == 出现 a;array[25] == 出现 z)。然后,我需要打印用空格分隔的数组的前 13 个元素,打印一个新行,并打印用空格分隔的数组的最后 13 个元素。

我让打印函数使用一个启动到所有 0 的数组,然后我让它工作,同时只计算 a 的出现。我现在已经修改了程序以计算所有出现次数,这正在工作,但现在整数和新行之间的空格无法打印。

这是我的代码:

    .data
array:  .word   0:26
space:  .asciiz " "
nLine:  .asciiz "\n"
string: .asciiz "abbcccddddeffggghhhhijjkkkllllmnnoooppppqrrsssttttuvvwwwxxxxyzz"
bye:    .ascii  "\n**** Thank you for running my program ****\n"
        .asciiz "\n**************** Goodbye *****************"

    .text
main:
    addi    $t0, $zero, 0       # clear $t0
    
    li  $t3, 10         # 10 is ASCII for new line
    li  $t4, 97         # 97 is ASCII for 'a'
    li  $s0, 0          # counter for number occurence
    li  $t5, 0          # initiate counter for array position
    la  $t1, string     # load address of string into $t1
    
count:  
    sw  $s0, array($t5)     # store letter count in array at position $t5
    
    lb  $t2, ($t1)      # load next character of string
    
    beq $t5, 104, reset     # print once end of array reached
    
    beq $t2, $t3, nArray    # once end of string is reached move to next array element
    
    beq $t2, $t4, inc       # if letter matches, increment count
    
    addi    $t1, $t1, 1     # if letter does not match, move to next character in string
    
    j   count           # loop
    
inc:
    addi    $s0, $s0, 1     # increment count
    
    addi    $t1, $t1, 1     # next character in string

    j   count           # loop
    
nArray:
    addi    $s0, $zero, 0       # clear $s0
    
    la  $t1, string     # load address of string into $t1
    
    addi    $t4, $t4, 1     # move to next ASCII letter
    
    addi    $t5, $t5, 4     # move to next array element
    
    j   count           # loop
    
reset:
    addi    $t0, $zero, 0       # clear $t0
    addi    $t1, $zero, 0       # clear $t1
    addi    $t2, $zero, 0       # clear $t2
    addi    $t3, $zero, 0       # clear $t3
    addi    $t4, $zero, 0       # clear $t4
    addi    $t5, $zero, 0       # clear $t5
    addi    $t6, $zero, 0       # clear $t6
    
printA1:
    beq $t0, 104, done      # once through 26 words, end
    
    beq $t0, 52, printNl    # once through 13 words, print new line
    
printA2:
    lw  $t6, array($t0)     # load next array element
    
    addi    $t0, $t0, 4     # increment array position
    
    li  $v0, 1          # load syscall code for print_int
    move    $a0, $t6        # move array element value into syscall argument
    syscall             # print integer
    
    li  $v0, 4          # load syscall code for print_string
    la  $a0, space      # load space into syscall argument
    syscall             # print space
    
    j   printA1         # loop
    
printNl:
    li  $v0, 4          # load syscall code for print_string
    la  $a0, nLine      # load new line into argument for syscall
    syscall             # print new line
    
    j   printA2         # loop
    
done:
    li  $v0, 4          # system call code for print_string
    la  $a0, bye        # load address of message into $a0
    syscall             # print the string

    li  $v0, 10         # terminate program run and
    syscall             # return control to system

                    # END OF PROGRAM

以下是字符串“abbcccddddeffggghhhhhijjkkkllllmnnoooppppqrrsssttttuvvvwwwxxxxyzz”的输出:

12341234123412341234123412 感谢您运行我的程序****

再见***************** -- 程序已完成运行 --

任何想法是什么导致它跳过空格和新行吗?在它使用所有 0 和 1 个字母后,我没有修改这些行,只是事先添加了寄存器复位。

数组 字符串 循环 整数 、MIP

评论

0赞 ggorlen 10/31/2023
请参阅为什么我不应该上传代码/数据/错误的图像?(包括终端文本输出)。你能显示预期的输出吗?
0赞 Erik Eidt 10/31/2023
你试过调试它吗?使用调试器执行单步操作,并确定它与预期偏差的位置?如果是这样,请分享出错的地方,否则,您需要对调试器进行更多调查和/或与有效的 C 版本进行比较。
0赞 TJream 10/31/2023
对不起,将图像固定在文本上。对于第二条评论:这是我感到困惑的地方。我的字母出现计数似乎有效,我的数组打印似乎有效。到目前为止,我能够弄清楚的最好的方法是,当我添加 nArray 函数时,它停止添加空格和新行,但我无法弄清楚为什么。

答:

0赞 Tim Roberts 10/31/2023 #1

在检查值是否达到 104 之前,将值存储到 U。读取 z 后,$t 5 将为 104,$s 0 将为 0。跳回 ,此时将 0 存储到 ,它从数组的末尾运行,并在 和 中存储零。array($t5)countarray(104)spacenLine

你以错误的方式处理这个问题。您的代码对字符串的外观有着根深蒂固的假设。如果您收到的字符串没有 26 个不同的字母怎么办?如果数组不是按字母顺序排列怎么办?当您到达零终止符时,您的循环应停止,并且您应该使用 计算要递增的 bin 编号,而不是通过递增 。$t2-97$t5

主循环应如下所示:

count:
    lb  $t2, ($t1)      # load next character of string
    beq $t2, 0, print   # if end of string
    sub $t2, $t2, $t4   # convert letter value to ordinal
    sll $t2, $t2, 2     # times 4
    lw  $t0, array($t2) # fetch the counter
    addi $t0, $t0, 1    # bump it
    sw  $t0, array($t2) # store it
    addi    $t1, $t1, 1     # if letter does not match, move to next character in string
    j   count           # loop

评论

0赞 TJream 10/31/2023
第一部分通过移动分支 if 等于存储词之前来修复它。谢谢。这是一个更大程序的一部分,所以在上下文中,它正在按照我的需要工作。我确实承认,不是第一次学习这些东西的学生可能会编写一个更好的解决方案。