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

如何在MIPS中用syscall打印二进制/十六进制时截断前导零并移除十六进制的'x'

处理MIPS系统调用输出的前导零与格式问题

原始代码与当前输出

我有一段通过syscall将十进制转换为二进制的MIPS代码:

.text 

main:

    li $v0, 35
    li $a0, 3
    syscall

这段代码将3转换为二进制,输出结果为:

00000000000000000000000000000011

若改为十六进制输出(将li $v0, 35替换为li $v0, 34),结果为:

0x00000003

需求:截断二进制和十六进制输出中的前导零,同时移除十六进制中的x。


解决方案

MIPS内置的syscall 34(十六进制)和syscall 35(二进制)没有提供格式调整选项,只能输出固定的32位带前导零格式,因此需要手动实现转换逻辑来满足需求。

1. 二进制输出(截断前导零)

核心思路:从最高位开始检查,跳过所有前导零,遇到第一个1后开始逐位输出,同时处理输入为0的特殊情况。

示例代码:

.text
main:
    li $a0, 3          # 待转换的十进制数
    move $t0, $a0      # 保存原始值
    li $t1, 0x80000000 # 掩码:从31位(最高位)开始检查
    li $t2, 0          # 标记是否已开始输出有效位

binary_loop:
    and $t3, $t0, $t1  # 获取当前位的值
    beqz $t3, check_zero
    li $t2, 1          # 遇到第一个1,标记开始输出
    j print_bit

check_zero:
    bnez $t2, print_bit # 已开始输出则打印当前0
    j shift_mask

print_bit:
    srl $t3, $t3, 31    # 将当前位移到最低位
    addi $a0, $t3, 48   # 转换为ASCII字符(0→48,1→49)
    li $v0, 11          # syscall 11:打印单个字符
    syscall

shift_mask:
    srl $t1, $t1, 1     # 掩码右移一位,检查下一位
    bnez $t1, binary_loop

# 处理输入为0的特殊情况
beqz $t2, print_zero
j exit

print_zero:
    li $a0, '0'
    li $v0, 11
    syscall

exit:
    li $v0, 10          # 程序退出
    syscall

运行效果:输入3输出11,输入0输出0,输入8输出1000。

2. 十六进制输出(截断前导零+移除x)

核心思路:按4位一组从最高位开始检查,跳过前导零组,遇到非零组后将每组转换为对应十六进制字符(0-9、A-F),同时处理输入为0的特殊情况。

示例代码:

.text
main:
    li $a0, 3          # 待转换的十进制数
    move $t0, $a0      # 保存原始值
    li $t1, 0xF0000000 # 掩码:从最高4位(28-31位)开始检查
    li $t2, 0          # 标记是否已开始输出有效位
    li $t3, 28         # 初始右移位数(将最高4位移到最低位)

hex_loop:
    and $t4, $t0, $t1  # 获取当前4位的值
    beqz $t4, check_hex_zero
    li $t2, 1          # 遇到第一个非零组,标记开始输出
    j print_hex_digit

check_hex_zero:
    bnez $t2, print_hex_digit # 已开始输出则打印当前0
    j shift_hex_mask

print_hex_digit:
    srl $t4, $t4, $t3  # 将当前4位移到最低位
    ble $t4, 9, hex_num # 处理0-9的情况
    addi $t4, $t4, 55  # 处理A-F的情况(10→'A'=65,65-10=55)
    j print_hex_char

hex_num:
    addi $t4, $t4, 48  # 0-9转换为ASCII字符(0→48)

print_hex_char:
    move $a0, $t4
    li $v0, 11          # syscall 11:打印单个字符
    syscall

shift_hex_mask:
    srl $t1, $t1, 4     # 掩码右移4位,检查下一组
    subi $t3, $t3, 4    # 右移位数减4
    bgez $t3, hex_loop

# 处理输入为0的特殊情况
beqz $t2, print_hex_zero
j exit

print_hex_zero:
    li $a0, '0'
    li $v0, 11
    syscall

exit:
    li $v0, 10          # 程序退出
    syscall

运行效果:输入3输出3,输入255输出FF,输入0输出0,输入16输出10。


内容的提问来源于stack exchange,提问作者John Sall

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 07:27:40