You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 11:25:14