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

MIPS中input_buffer无输出问题:十进制转二进制后无法打印缓冲区

十进制转二进制无输出问题修复

我尝试将输入的十进制数转换为二进制,存入input_buffer后输出缓冲区内容,但执行时没有任何输出,就像缓冲区是空的一样。以下是我的代码:

.data
ask_input: .asciiz "Enter a number (0-255): "
binary: .asciiz "\nThe number in base 2 is: "
input_buffer: .space 10

.text
globl main

main:
    # Ask for input
    li $v0, 4
    la $a0, ask_input
    syscall

    # Assign input
    li $v0, 5
    syscall
    move $s0, $v0 # Integer is stored in $s0

    # Setup
    li $t0, 2    # For dividing by 2
    li $t1, 0    # For holding binary
    li $t2, 8    # Assume 8-bit binary response

    # Initialize the input_buffer with null bytes
    li $t3, 0      # Null byte
    li $t4, 10     # Number of bytes to initialize
    la $t5, input_buffer  # Address of input_buffer

    initialize_buffer:
        sb $t3, ($t5)   # Store a null byte
        addi $t5, $t5, 1  # Move to the next byte
        addi $t4, $t4, -1  # Decrement the byte count
        bnez $t4, initialize_buffer  # Continue until all bytes are null

convert_loop:
    # Continue the loop until $s0 is not equal to 0
    bnez $s0, continue_conversion

    # If $s0 is 0, jump to printing the binary
    j print_bin

continue_conversion:
    # Use 'and' with 1 for the least significant digit
    andi $t3, $s0, 1

    # Convert the least significant digit to '0' or '1'
    addi $t3, $t3, '0'

    # Store the ASCII character in input_buffer
    sb $t3, input_buffer($t2)

    # Right shift for division by 2
    srl $s0, $s0, 1

    # Decrement the counter
    addi $t2, $t2, -1

    # Continue the loop
    j convert_loop

print_bin:
    # Print the output message
    li $v0, 4
    la $a0, binary
    syscall

    # Print the binary representation stored in input_buffer
    li $v0, 4
    la $a0, input_buffer
    syscall

    # Exit
    li $v0, 10
    syscall

问题根源

  1. 缓冲区起始为空:初始化时把整个input_buffer都填成了空字节(\0),转换时又从偏移8的位置开始存二进制字符,而MIPS的字符串打印系统调用(syscall 4)会从缓冲区起始位置读取,遇到第一个空字节就停止,所以直接输出空内容。
  2. 输入0无处理:当输入为0时,转换循环根本不会执行,缓冲区里没有任何有效字符,同样导致无输出。
  3. 冗余变量:t0和t1定义后完全没用到,属于无效代码。

修复后的代码

.data
ask_input: .asciiz "Enter a number (0-255): "
binary: .asciiz "\nThe number in base 2 is: "
input_buffer: .space 10

.text
.globl main

main:
    # 提示输入
    li $v0, 4
    la $a0, ask_input
    syscall

    # 读取输入整数
    li $v0, 5
    syscall
    move $s0, $v0 # 整数存入$s0

    # 初始化变量:从8位二进制的最高位偏移(7)开始填充
    li $t2, 7    
    la $t5, input_buffer  # 缓冲区起始地址

    # 处理输入为0的特殊情况
    beqz $s0, handle_zero

convert_loop:
    # 数值为0时退出循环
    beqz $s0, print_bin

    # 获取当前最低位
    andi $t3, $s0, 1
    # 转换为ASCII字符'0'或'1'
    addi $t3, $t3, '0'
    # 存入缓冲区对应位置
    sb $t3, input_buffer($t2)
    # 右移一位等价于除以2
    srl $s0, $s0, 1
    # 偏移减1,处理下一位
    addi $t2, $t2, -1

    j convert_loop

handle_zero:
    # 输入为0时,手动写入一个'0'到缓冲区
    li $t3, '0'
    sb $t3, input_buffer(7)
    j print_bin

print_bin:
    # 打印提示信息
    li $v0, 4
    la $a0, binary
    syscall

    # 从第一个有效字符的位置开始打印
    addi $a0, $t5, $t2
    addi $a0, $a0, 1
    li $v0, 4
    syscall

    # 退出程序
    li $v0, 10
    syscall

修复说明

  • 调整存储位置:从8位二进制的最高位偏移(7)开始填充,有效字符会集中在缓冲区的后半段,避免起始位置为空的问题。
  • 处理输入0:单独分支处理输入0的情况,确保缓冲区有有效字符。
  • 精准打印起始位:计算有效字符的起始地址(input_buffer + t2 + 1),让打印系统调用从第一个非空字符开始输出。
  • 清理冗余代码:删除未使用的变量,简化逻辑。

内容的提问来源于stack exchange,提问作者Udalizzer 33

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 15:46:27