0

我试图在 MIPS 中编写一个程序,该程序接受一个字符串并打印一个仅包含字符的结果(假设字符串是字母数字)。它适用于大小 < 4 的字符串,但是当出现第 4 个字符时,它会进入无限循环。

.data
    string: .word 10
.data
    result: .word 10
.data
    message1: .asciiz "number\n"
.data
    message2: .asciiz "letter "
.data
    message3: .asciiz "finished loop\n"


.text
    main:
        li $v0 8    # take input as string
        la $a0 string   # store it in "string"
        la $a1 10   # size of "string" is at most 10
        syscall
        la $s0 string   # save address of "string" to s0
        la $s1 result   # save address of "result" to s1


        Loop:
            li $t0 10   # set t0 as '/n'
            lb $t1 ($s0)    # load character that we are currently checking
            beq $t0 $t1 Exit    # check if we are at the end of the string


            li $t0 64   # set t0 to 64 to check if it is a letter (character that we are now checking must be greater than 64)
            slt $t2 $t0 $t1 # t2 will store the result of comparison ($t1 - character)
            li $t0 0    # set t0 to 0 to check the result of comparison
            beq $t2 $t0 Increment # if 64 > ch, then we must just proceed
            li $v0 4
            la $a0 message2 # print message that it is a character
            syscall
            sb $t1 ($s1)    # copy this character into our "result"
            addi $s1 $s1 1  # increment the address of "result"

        Increment:
            li $v0 4
            la $a0 message1 # print message that it is a number
            syscall
            addi $s0 $s0 1  # increment the address of "string" to proceed in loop
            j Loop

        Exit:
            li $t0 10
            sb $t0 ($s1)    # add endline character to "result"
            addi $s1 $s1 1
            li $t0 0
            sb $t0 ($s1)    # add null character to "result"
            li $v0 4
            la $a0 message3 # print message that the loop has finished
            syscall
            li $v0 4
            la $a0 result   # print result
            syscall
            jr $ra

提前致谢。

4

1 回答 1

1

不通过我自己很难说,但这里有一个想法:使用“i”的力量,即立即模式。这样,您就不必担心寄存器值是否与您预期的不太一样。另外,使用特殊$zero寄存器而不是用零加载寄存器。所以改变这个:

        li $t0 64   # set t0 to 64 to check if it is a letter (character that we are now checking must be greater than 64)
        slt $t2 $t0 $t1 # t2 will store the result of comparison ($t1 - character)
        li $t0 0    # set t0 to 0 to check the result of comparison
        beq $t2 $t0 Increment # if 64 > ch, then we must just proceed

对此:

        slti $t2, $t1, 'A' # A little different: set $t2 if $t1 < 65 ('A')
        bne $t2, $zero Increment # branch if $t1 < 'A'

也许通过消除有利于立即数的寄存器,您可以找到导致您进入循环的故障。

此外,还有一些其他可能的故障来源:

  • 您正在寻找'\n'终止字符串,但我不确定如果输入是完整的 10 个字符,您可以保证系统调用将添加 \n。也许您还应该/而不是检查零终止符字节值。

  • 您已将stringand定义result为 10 个单词,但实际上是在其中存储字节。这不应该是一个问题 - 您分配了 40 个字节而不是 10 个。但是如果您返回并将它们更改为byte,请确保允许该尾随\0(和\n)。

抱歉,我不能更具体,但希望能指出你正确的方向。

于 2013-11-07T17:04:34.450 回答