MIPS汇编代码计算姓名ASCII最值时最小值错误的修复咨询
问题:MIPS汇编代码计算ASCII最小值错误修复
我写了一段MIPS汇编代码,用来读取输入的姓名(忽略姓名中间的空格),计算所有字符的ASCII最大值和最小值。运行时最大值结果正确,但最小值出错:输入Isaac Newton后,输出最小值为10,预期应该是73。相关代码、实际输出和预期输出如下,怎么修复?
.data prompt: .asciiz "Enter your first and last name: " max_msg: .asciiz "\nMaximum ASCII value: " min_msg: .asciiz "\nMinimum ASCII value: " newline: .asciiz "\n" .text globl main main: # Prompt for input li $v0, 4 # system call for print string la $a0, prompt # load address of prompt syscall # Read input li $v0, 8 # system call for read string la $a0, buffer # load address of buffer li $a1, 255 # set maximum length of input syscall # Find maximum and minimum ASCII values la $t0, buffer # load address of buffer into $t0 li $t1, 0x20 # initialize $t1 to the ASCII value of space li $t2, 0x7F # initialize $t2 to the largest possible ASCII value li $t3, 0x00 # initialize $t3 to the smallest possible ASCII value li $t4, 0 # initialize $t4 to 0 loop: lb $t5, ($t0) # load byte from current position beq $t5, 0, done # if byte is null terminator, we're done # if byte is a space, skip it beq $t5, $t1, next # if this is the first non-space character, initialize $t4 beq $t4, 0, init # find maximum ASCII value bgt $t5, $t3, is_max j is_min is_max: move $t3, $t5 # set $t3 to current byte j next # find minimum ASCII value is_min: blt $t5, $t2, set_min j next set_min: move $t2, $t5 # set $t2 to current byte j next init: # initialize $t4 to the first non-space character move $t4, $t5 j next next: addi $t0, $t0, 1 # move to next byte j loop # jump to loop done: # Print results li $v0, 4 # system call for print string la $a0, max_msg # load address of max message syscall li $v0, 1 # system call for print integer move $a0, $t3 # load maximum ASCII value syscall li $v0, 4 # system call for print string la $a0, min_msg # load address of min message syscall li $v0, 1 # system call for print integer move $a0, $t2 # load minimum ASCII value syscall li $v0, 4 # system call for print string la $a0, newline # load address of newline syscall # Exit program li $v0, 10 # set system call number to 10 for exit syscall # perform system call to exit .data buffer: .space 256 # allocate space for input buffer
实际输出:
Enter your first and last name: Isaac Newton
Maximum ASCII value: 119
Minimum ASCII value: 10
预期输出:
Enter your first and last name: Isaac Newton
Maximum ASCII value: 119
Minimum ASCII value: 73
问题原因
- 初始值未正确初始化:第一个非空格字符仅存入
$t4,未同步设置为$t2(最小值)和$t3(最大值),导致最小值的初始基准还是0x7F(127),后续会被输入末尾的换行符(ASCII 10)覆盖。 - 未过滤换行符:MIPS的字符串读取调用会把用户输入的换行符(ASCII 10)存入缓冲区,代码仅跳过空格,未处理换行符,导致其参与最小值比较。
修复步骤
- 用第一个有效字符初始化最大/最小值:修改
init标签,将第一个非空格、非换行字符同时赋值给$t2和$t3,确立正确的比较基准。 - 过滤换行符:在跳过空格的判断后,新增对换行符(
0x0A)的检测,跳过该字符。
修复后的代码
.data prompt: .asciiz "Enter your first and last name: " max_msg: .asciiz "\nMaximum ASCII value: " min_msg: .asciiz "\nMinimum ASCII value: " newline: .asciiz "\n" .text globl main main: # Prompt for input li $v0, 4 # system call for print string la $a0, prompt # load address of prompt syscall # Read input li $v0, 8 # system call for read string la $a0, buffer # load address of buffer li $a1, 255 # set maximum length of input syscall # Find maximum and minimum ASCII values la $t0, buffer # load address of buffer into $t0 li $t1, 0x20 # initialize $t1 to the ASCII value of space li $t2, 0x7F # initialize $t2 to the largest possible ASCII value li $t3, 0x00 # initialize $t3 to the smallest possible ASCII value li $t4, 0 # initialize $t4 to 0 (flag for first valid char) loop: lb $t5, ($t0) # load byte from current position beq $t5, 0, done # if byte is null terminator, we're done # Skip space and newline characters beq $t5, $t1, next li $t6, 0x0A # ASCII value of newline beq $t5, $t6, next # Initialize max and min with first valid character beq $t4, 0, init # Update maximum ASCII value bgt $t5, $t3, update_max # Update minimum ASCII value blt $t5, $t2, update_min j next update_max: move $t3, $t5 j next update_min: move $t2, $t5 j next init: # Set first valid char as both initial max and min move $t3, $t5 move $t2, $t5 li $t4, 1 # Mark first char as processed j next next: addi $t0, $t0, 1 # move to next byte j loop # jump to loop done: # Print results li $v0, 4 # system call for print string la $a0, max_msg # load address of max message syscall li $v0, 1 # system call for print integer move $a0, $t3 # load maximum ASCII value syscall li $v0, 4 # system call for print string la $a0, min_msg # load address of min message syscall li $v0, 1 # system call for print integer move $a0, $t2 # load minimum ASCII value syscall li $v0, 4 # system call for print string la $a0, newline # load address of newline syscall # Exit program li $v0, 10 # set system call number to 10 for exit syscall # perform system call to exit .data buffer: .space 256 # allocate space for input buffer
修复说明
- 新增换行符过滤逻辑,避免无效字符干扰计算;
- 第一个有效字符同时作为最大值和最小值的初始值,确保后续比较基准正确;
- 优化分支逻辑,让最大/最小值的更新流程更清晰。
内容的提问来源于stack exchange,提问作者Sayma Sultana
相关产品推荐
相关产品推荐

