MIPSY中十进制转二进制无输出问题排查求助
MIPS二进制转换程序无输出问题排查与修复
问题描述
我正在开发一个MIPS汇编程序,支持用户输入十进制数,通过位运算符转换为二进制、八进制或十六进制。目前仅调试二进制转换功能,但程序无输出结果,无法定位问题。此前将initBin中的计数器设为1时,仅输出正确的首个二进制位;尝试调整binMem缓冲区大小会触发初始化错误,恳请协助排查问题。
原代码
.data binMem: # Allocate 33 bytes for buffer and null terminate the buffer .space 33 .asciiz "" firstMenuLine: .asciiz "Select an output format: \n" secondMenuLine: .asciiz "1. Binary \n" thirdMenuLine: .asciiz "2. Octal \n" fourthMenuLine: .asciiz "3. Hexadecimal \n" fifthMenuLine: .asciiz "4. Exit \n" firstPrompt: .asciiz "Enter your choice: " secondPrompt: .asciiz "Enter a decimal number: " binResult: .asciiz "Binary: " octResult: .asciiz "Octal: " hexResult: .asciiz "Hexadecimal: " exit: .asciiz "Goodbye" .text main: # Ouput the first line li $v0, 4 la $a0, firstMenuLine syscall # Output the second line li $v0, 4 la $a0, secondMenuLine syscall # Output the third line li $v0, 4 la $a0, thirdMenuLine syscall # Output the fourth line li $v0, 4 la $a0, fourthMenuLine syscall # Output the fifth line li $v0, 4 la $a0, fifthMenuLine syscall # Output the first Prompt li $v0, 4 la $a0, firstPrompt syscall # Input a menu select character and move it to $t0 or quit li $v0, 12 syscall move $t0, $v0 beq $t0, '4', end # Output the second Prompt li $v0, 4 la $a0, secondPrompt syscall # Input a decimal number for conversion, assign to $t1 li $v0, 5 syscall move $t1, $v0 convertLoop: # If $t0 is 1, jump to convertBin beq $t0, '1', initBin # If $t0 is 2, jump to convertOct beq $t0, '2', convertOct # If $t0 is 3, jump to convertHex beq $t0, '3', convertHex initBin: #Clear the buffer, and set counter to number of bits la $t3, binMem li $t2, 32 j convertBin convertBin: # Check if decimal number is not zero (all bits processed) beqz $t2, convertBin # Decrement counter addi $t2, $t2, -1 # Extract the least significant binOutput andi $t4, $t1, 1 # Store bit in the buffer sb $t4, ($t3) # Shift right by 1 (divide by 2) srl $t1, $t1, 1 # Move to the next buffer position addi $t3, $t3, 1 j binOutput convertOct: convertHex: binOutput: # Output the result li $v0, 4 # printf("Result: "); la $a0, binResult syscall # Output the number in $t2 la $a0, binMem li $v0, 4 # printf("%s", binMem); syscall # Output newline char li $v0, 11 li $a0, '\n' syscall j main end: # Exit the Program and return 0 li $v0, 10 syscall
问题分析与修复步骤
1. 循环终止逻辑错误
原代码中convertBin的beqz $t2, convertBin会在计数器$t2为0时无限跳回自身,形成死循环。应改为跳转到添加终止符的逻辑,结束转换:
beqz $t2, addNullTerminator # 计数器为0时,添加终止符后输出
2. 二进制位转ASCII字符错误
提取的位是数值0/1,直接存储为字节是不可打印的控制字符,需加上0x30(ASCII中'0'的编码)转换成可打印字符:
andi $t4, $t1, 1 addi $t4, $t4, 0x30 # 转换为ASCII '0'或'1' sb $t4, ($t3)
3. 缺少字符串终止符
转换完成后必须在缓冲区末尾添加'\0',否则syscall 4输出字符串时会读取到内存中的垃圾数据:
addNullTerminator: sb $zero, ($t3) # 添加字符串终止符 j binOutput
4. 循环未重复执行
原代码处理完一位后直接跳转到binOutput,只执行一次转换。应修改跳转逻辑,让循环继续处理所有32位:
addi $t3, $t3, 1 j convertBin # 跳回循环继续处理下一位
修复后的完整代码
.data binMem: # Allocate 33 bytes for buffer and null terminate the buffer .space 33 .asciiz "" firstMenuLine: .asciiz "Select an output format: \n" secondMenuLine: .asciiz "1. Binary \n" thirdMenuLine: .asciiz "2. Octal \n" fourthMenuLine: .asciiz "3. Hexadecimal \n" fifthMenuLine: .asciiz "4. Exit \n" firstPrompt: .asciiz "Enter your choice: " secondPrompt: .asciiz "Enter a decimal number: " binResult: .asciiz "Binary: " octResult: .asciiz "Octal: " hexResult: .asciiz "Hexadecimal: " exit: .asciiz "Goodbye" .text main: # Ouput the first line li $v0, 4 la $a0, firstMenuLine syscall # Output the second line li $v0, 4 la $a0, secondMenuLine syscall # Output the third line li $v0, 4 la $a0, thirdMenuLine syscall # Output the fourth line li $v0, 4 la $a0, fourthMenuLine syscall # Output the fifth line li $v0, 4 la $a0, fifthMenuLine syscall # Output the first Prompt li $v0, 4 la $a0, firstPrompt syscall # Input a menu select character and move it to $t0 or quit li $v0, 12 syscall move $t0, $v0 beq $t0, '4', end # Output the second Prompt li $v0, 4 la $a0, secondPrompt syscall # Input a decimal number for conversion, assign to $t1 li $v0, 5 syscall move $t1, $v0 convertLoop: # If $t0 is 1, jump to convertBin beq $t0, '1', initBin # If $t0 is 2, jump to convertOct beq $t0, '2', convertOct # If $t0 is 3, jump to convertHex beq $t0, '3', convertHex initBin: #Clear the buffer, and set counter to number of bits la $t3, binMem li $t2, 32 j convertBin convertBin: # Check if all bits processed beqz $t2, addNullTerminator # Decrement counter addi $t2, $t2, -1 # Extract the least significant bit andi $t4, $t1, 1 # Convert to ASCII character '0' or '1' addi $t4, $t4, 0x30 # Store bit in the buffer sb $t4, ($t3) # Shift right by 1 (divide by 2) srl $t1, $t1, 1 # Move to the next buffer position addi $t3, $t3, 1 # Continue loop j convertBin addNullTerminator: # Add null terminator to the end of the string sb $zero, ($t3) j binOutput convertOct: # Add octal conversion logic later j main convertHex: # Add hexadecimal conversion logic later j main binOutput: # Output the result label li $v0, 4 la $a0, binResult syscall # Output the binary string la $a0, binMem li $v0, 4 syscall # Output newline char li $v0, 11 li $a0, '\n' syscall j main end: # Exit the Program li $v0, 10 syscall
内容的提问来源于stack exchange,提问作者LNex86
相关产品推荐
相关产品推荐

