MIPS汇编中验证输入字符串为整数/浮点数的问题排查
MIPS字符串数字验证问题修复
问题背景
我正在完成一项需要整数输入的大学作业,为避免程序崩溃,没有使用syscall 5直接输入整数,而是先读取字符串再验证有效性:
- 先检查是否存在非数字字符
- 再判断是否包含小数点以识别浮点数
- 无上述情况则判定为整数
目前浮点数验证功能正常,但输入整数时会触发错误,调试发现输入整数时程序会进入checkdot标签,并通过blt $t0, $t3, error语句跳转到错误分支。
原代码
inputstr: .asciiz "Number " buffer: .space 20 printinteger: .asciiz "Its an integer" printfloat: .asciiz "Its a float" notanumber: .asciiz "It's not a number" zero: .byte '0' nine: .byte '9' dot: .byte '.' .text .globl main main: lb $t1, zero lb $t2, nine lb $t3, dot #Read the string la $a0, inputstr li $v0, 4 syscall la $a0, buffer li $a1, 20 li $v0, 8 syscall #Begining of validation la $a0, buffer loop: lb $t0, 0($a0) beq $a0, $zero, integer # 错误:判断地址而非当前字符 blt $t0, $t1, checkdot bgt $t0, $t2, error addi $a0, $a0, 1 b loop checkdot: blt $t0, $t3, error bgt, $t0, $t3, error # 错误:多余的逗号 la $a0, printfloat li $v0, 4 syscall b end error: la $a0, notanumber li $v0, 4 syscall b end integer: la $a0, printinteger li $v0, 4 syscall end: li $v0, 10 syscall
问题分析
- 循环终止条件错误:原代码中
beq $a0, $zero, integer是判断字符串地址是否为0,这完全错误。应该判断当前读取的字符$t0是否为字符串结束符\0(ASCII值为0),也就是当遍历到字符串末尾时,直接判定为整数。 - 语法错误:
checkdot分支里的bgt, $t0, $t3, error多了一个逗号,属于语法错误,会导致执行异常。 - 整数逻辑触发错误分支:输入整数时,遍历到末尾的
\0,其ASCII值(0)小于'0'的ASCII值(48),因此进入checkdot分支。而\0的ASCII值又小于小数点.的ASCII值(46),触发blt $t0, $t3, error跳转到错误分支。
修复后的代码
inputstr: .asciiz "Number " buffer: .space 20 printinteger: .asciiz "Its an integer" printfloat: .asciiz "Its a float" notanumber: .asciiz "It's not a number" zero: .byte '0' nine: .byte '9' dot: .byte '.' .text .globl main main: lb $t1, zero lb $t2, nine lb $t3, dot #Read the string la $a0, inputstr li $v0, 4 syscall la $a0, buffer li $a1, 20 li $v0, 8 syscall #Begining of validation la $a0, buffer loop: lb $t0, 0($a0) beq $t0, $zero, integer # 修复:判断当前字符是否为字符串结束符 blt $t0, $t1, checkdot bgt $t0, $t2, error addi $a0, $a0, 1 b loop checkdot: blt $t0, $t3, error bgt $t0, $t3, error # 修复:去掉多余的逗号 la $a0, printfloat li $v0, 4 syscall b end error: la $a0, notanumber li $v0, 4 syscall b end integer: la $a0, printinteger li $v0, 4 syscall end: li $v0, 10 syscall
修复说明
- 修改循环终止条件为
beq $t0, $zero, integer,当遍历到字符串末尾的\0时,直接跳转到整数判定分支,避免进入checkdot。 - 移除
checkdot分支中bgt指令后的多余逗号,修正语法错误。
内容的提问来源于stack exchange,提问作者Tyxe
相关产品推荐
相关产品推荐

