MIPS:从一个字符串到另一个错误的选择性复制

时间:2013-11-07 14:45:00

标签: mips

我试图在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

提前致谢。

1 个答案:

答案 0 :(得分: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'

也许通过取消寄存器支持immediates,你可以找到导致你进入循环的故障。

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

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

  • 您已将stringresult定义为10个字,但实际上您在其中存储了字节。这不应该是一个问题 - 你已经分配了40个字节而不是10个字节。但如果你回过头来改变它们byte,请务必允许这个尾随\0(和{{ 1}})。

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