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=]”相同,所有这些都在您的有效列表中。删除该行应该可以修复您的程序(尽管我没有检查所有其余代码是否有错误)。
.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=]”相同,所有这些都在您的有效列表中。删除该行应该可以修复您的程序(尽管我没有检查所有其余代码是否有错误)。