如何在MIPS中用循环实现整数转无符号二进制?兼问hi值存数组及回显
MIPS整数转无符号二进制及数组存储问题解答
原代码存在的问题
- 循环触发逻辑错误:初始
div后直接判断hi是否为0就结束,会遗漏最后一位二进制位,且未处理输入为0的场景 - 数组存储错误:
mfhi $s0是将余数直接覆盖数组的地址寄存器,正确做法是用sw指令把余数存入数组地址指向的内存 - 二进制位顺序错误:当前打印的是余数(低位到高位),输出的二进制是逆序的
- 循环内的
div执行时机错误,导致余数获取不对应
修正后的代码
.data msg1: .asciiz "Please enter value: " A: .space 128 # 最多存储32个整数(每个4字节),对应32位无符号数 newline: .asciiz "\n" .text main: # 提示输入 li $v0, 4 la $a0, msg1 syscall # 获取用户输入 li $v0, 5 syscall move $t1, $v0 # $t1存储输入的无符号整数 # 打印输入的数 li $v0, 1 move $a0, $t1 syscall # 打印换行 li $v0, 4 la $a0, newline syscall la $s0, A # $s0指向数组A的起始地址 li $t5, 2 # 除数2 li $t2, 0 # 计数器,记录存储的二进制位个数 # 处理输入为0的特殊情况 beq $t1, $zero, handle_zero loop: divu $t1, $t5 # 无符号除法,$t1 / 2,余数存hi,商存lo mfhi $s1 # 取出余数(当前二进制位) sw $s1, ($s0) # 将余数存入数组当前位置 addi $s0, $s0, 4 # 数组地址后移4字节(下一个整数位置) addi $t2, $t2, 1 # 计数器加1 mflo $t1 # 将商赋值给$t1,作为下一次循环的被除数 bne $t1, $zero, loop # 商不为0则继续循环 # 从数组末尾往前打印二进制位(因为存储的是低位到高位) print_loop: addi $s0, $s0, -4 # 地址回退到上一个存储位置 lw $a0, ($s0) # 取出存储的二进制位 li $v0, 1 syscall addi $t2, $t2, -1 # 计数器减1 bne $t2, $zero, print_loop j end handle_zero: # 输入为0时直接打印0 li $v0, 1 li $a0, 0 syscall end: # 打印换行 li $v0, 4 la $a0, newline syscall li $v0, 10 syscall
关键知识点解释
- 无符号除法:使用
divu指令而非div,确保处理无符号整数的除法逻辑正确 - 余数存储到数组:通过
sw $s1, ($s0)将余数存入当前数组地址指向的内存,之后用addi $s0, $s0, 4移动到下一个存储单元(MIPS中整数占4字节) - 二进制位顺序处理:因为每次取余得到的是二进制的低位,所以存储时是低位到高位,打印时需要从最后一个存储的位置往前读取,才能得到正确的高位到低位的二进制表示
- 特殊情况处理:单独处理输入为0的场景,避免循环不执行导致无输出
内容的提问来源于stack exchange,提问作者Huncho Ric
相关产品推荐
相关产品推荐

