MARS 4.5中MIPS汇编程序报错“program is finished running (dropped off bottom)”求助
MIPS汇编程序错误修复(MARS 4.5)
核心问题排查
你的程序出现-- program is finished running (dropped off bottom) --错误,同时存在多个逻辑错误,具体如下:
1. 符号解析错误
buffer定义在.text段之后的.data段中,MARS汇编器无法在main函数中正确解析该符号,导致读取输入时出错。
2. 十六进制字符串转整数逻辑完全错误
check_alpha部分错误覆盖了原字符的ASCII值(直接将$t9设为0x20),丢失了输入字符的关键信息,无法正确转换字母类十六进制字符。- 大小写转换逻辑混乱,未正确处理
A-F/a-f的ASCII值到数值的映射。 - 仅用32位寄存器存储结果,无法处理64位有符号整数,也未实现溢出检测逻辑。
3. 未初始化的溢出状态寄存器
代码中直接使用$t3输出溢出状态,但$t3从未被赋值,会输出随机值。
修正后的代码
.data prompt: .asciiz "Enter the 64-bit integer in hexadecimal: " overflow_label: .asciiz "Overflow = " newline: .asciiz "\n" buffer: .space 17 # 将buffer移到开头的.data段,确保符号可被正确解析 .text main: # 提示输入 li $v0, 4 la $a0, prompt syscall # 读取十六进制字符串 li $v0, 8 la $a0, buffer li $a1, 17 syscall # 转换字符串为64位整数,返回值存$v0(低32位)、$v1(高32位),溢出状态存$t3 jal convert_hex_to_int # 输出溢出状态 li $v0, 4 la $a0, overflow_label syscall li $v0, 1 move $a0, $t3 syscall # 换行 li $v0, 4 la $a0, newline syscall # 退出程序 li $v0, 10 syscall # 十六进制字符串转64位有符号整数 # 输入: $a0 = 字符串地址 # 输出: $v0 = 低32位, $v1 = 高32位; $t3 = 1表示溢出, 0表示正常 convert_hex_to_int: li $t0, 0x30 # '0'的ASCII值 li $t1, 0x41 # 'A'的ASCII值 li $t2, 0x61 # 'a'的ASCII值 li $t3, 0 # 初始化溢出标志为0 li $t4, 0 # 高32位结果 li $t5, 0 # 低32位结果 convert_loop: lb $t6, 0($a0) addi $a0, $a0, 1 beqz $t6, convert_done # 遇到空字符结束 # 判断是否是数字(0-9) sub $t7, $t6, $t0 bltz $t7, check_upper bgt $t7, 9, check_upper # 数字处理 j shift_and_combine check_upper: # 判断是否是大写字母(A-F) sub $t7, $t6, $t1 bltz $t7, check_lower bgt $t7, 5, invalid_char addi $t7, $t7, 10 # A-F对应10-15 j shift_and_combine check_lower: # 判断是否是小写字母(a-f) sub $t7, $t6, $t2 bltz $t7, invalid_char bgt $t7, 5, invalid_char addi $t7, $t7, 10 # a-f对应10-15 j shift_and_combine invalid_char: # 非法字符,直接设为溢出 li $t3, 1 j convert_done shift_and_combine: # 64位左移4位:先移高32位,再移低32位,处理进位 sll $t4, $t4, 4 sll $t5, $t5, 4 # 捕获低32位移位前的最高4位,作为高32位的进位 and $t8, $t5, 0xF0000000 srl $t8, $t8, 28 or $t4, $t4, $t8 # 将当前数字合并到低32位 or $t5, $t5, $t7 # 检查64位有符号溢出:若输入超过16位十六进制,或最高位符号位异常 # 统计已处理的字符数(这里简化为:若处理超过16个字符则溢出) sub $t9, $a0, buffer bgt $t9, 16, set_overflow j convert_loop set_overflow: li $t3, 1 convert_done: move $v0, $t5 # 返回低32位 move $v1, $t4 # 返回高32位 jr $ra
关键修改说明
- 调整buffer位置:将
buffer移到开头的.data段,确保汇编器能正确解析符号,避免输入读取失败。 - 重构转换逻辑:正确处理数字、大小写字母的ASCII到数值映射,增加非法字符检测。
- 支持64位整数:用
$t4和$t5分别存储高32位和低32位结果,实现64位左移和进位处理。 - 实现溢出检测:统计输入字符数(超过16位则溢出),同时保留非法字符溢出标记。
- 初始化溢出寄存器:
$t3初始化为0,异常情况设为1,确保输出正确的溢出状态。
内容的提问来源于stack exchange,提问作者Sulais
相关产品推荐
相关产品推荐

