MIPS 中的字符串输入会省略输入的前四个字符

String input in MIPS omits the first four characters that are inputted

.data
EntryReq:
    .asciiz "Please enter an 8 digit hexadecimal MIPS instruction: \n"
InputLongError:
    .asciiz "\nYour input was too long, make sure it is 8 digits. "
InputShortError:
    .asciiz "\nYour input was too short, make sure it is 8 digits. "
CharInvalidError:
    .asciiz "\nYour input contains an invalid character. "
ValidChars:
    .asciiz "0123456789abcdef\n\b[=10=]"

.align 4
input:
    .space 20

.text

main:
    #Print input request
    la $a0, EntryReq #loads input into arg. reg.
    li $v0, 4 #op code for print string
    syscall

    #take input for input (stored)
    li $v0, 8 #op code for take user input
    la $a0, input #provide address for syscall
        li $a1, 20 # tell syscall the byte space required for the string
    syscall

    #move to input(stored)
    sw $v0, input #move inputted into from $v0 to input(stored)

    #check validity of input
    la $a0, input #load address of input to arg. reg. for method call
    la $a1, ValidChars #load address of string of valid chars
    jal verifyInput #call the verifyInput method which does as expected 

    #test if string length count works
    addi $a0, $v0, 0 #load from $v0 to arg. reg.
    li $v0, 1 #op code for print int
    syscall

terminate:
    li $v0, 10
    syscall

verifyInput:
    li $v0, -1 #start length count at 0
verifyLoop:
    lb $t0, ($a0) #load current 
    li $a2, 0 #loop for char check, loops up to length of validChar string
    la $a1, ValidChars
    j checkChar
charVerified: #ignore this, is entry point back into verifyLoop for checkChar
    addi $a0, $a0, 1 #increment 
    addi $v0, $v0, 1
    bgt $v0, 8, printTooLongError #if result bigger than 8, error
    bne $t0, 10, verifyLoop #10 is string end, so check if string is end
    blt $v0, 8, printTooShortError #if result less than 8, error
    jr $ra #if here string input was confirmed okay

checkChar: # loops through valid chars for each char in $a0                 | Valid Chars: 0123456789abcdef\n |
    lb $t1, ($a1) #loads in byte from char string
    addi $a1, $a1, 1 #increment address, for the next char
    addi $a2, $a2, 1 #increment until length of valid char string is reached
    beq $t0, $t1, charVerified
    bne $a2, 19, checkChar #if length of valid chars changes, change second argument here
    j charNotValidError
charNotValidError:
    la $a0, CharInvalidError #loads input into arg. reg.
    li $v0, 4 #op code for print string
    syscall
    j terminate
printTooLongError:
    la $a0, InputLongError #loads input into arg. reg.
    li $v0, 4 #op code for print string
    syscall
    j terminate
printTooShortError:
    la $a0, InputShortError #loads input into arg. reg.
    li $v0, 4 #op code for print string
    syscall
    j terminate

这段代码的大致意思是让用户输入一个8位的十六进制字符串,然后程序检查它是否是一个有效的十六进制字符串(即只包括0-9和a-f)。但是,每当我 运行 它时,我输入的字符串都缺少前四个字符。因此,如果我在前四位数字中放置无效字符,例如 wwww1abc,那么代码 运行 就可以了,但它不应该这样做。但是如果我执行 1abcwwww,它会输出无效字符错误,这是应该的。我真的很困惑为什么会这样,我也没有看到其他人遇到过这个问题。非常感谢任何帮助。

问题出在这一行:

#move to input(stored)
sw $v0, input #move inputted into from $v0 to input(stored)

read integer 系统调用不同,read string 将结果放入输入缓冲区,在您的例子中是 input。因此,您不需要读出 $v0 中的值并将其存储在 input 中,您将用 $v0 的值覆盖缓冲区的前 4 个字节,即仍然是 0x00000008,这与小端机器的字符串“\b[=22=][=22=][=22=]”相同,所有这些都在您的有效列表中。删除该行应该可以修复您的程序(尽管我没有检查所有其余代码是否有错误)。