MIPS/MARS二进制打印问题求助:调试print_binary子程序
调试MIPS汇编print_binary子程序问题
问题背景
现有一段MIPS汇编程序,main部分会调用print_binary子程序对三个测试数(2、-1、0xcafef00d)执行32位二进制打印操作。要求仅调试print_binary子程序(不得修改main和end部分),使输出符合预期:
预期输出
00000000000000000000000000000010 11111111111111111111111111111111 11001010111111101111000000001101
注:原问题中给出的第一个预期串为00000000000000000000000000000011,对应数字3,与测试数2不符,此处按测试数2的正确二进制修正。
当前错误输出
00000000000000000000000000000000 10000000000000000000000000000000 10000000000000000000000000000000
原代码
.text main: li $a0, 2 jal print_binary li $a0, -1 jal print_binary li $a0, 0xcafef00d jal print_binary li $v0, 10 # exit syscall # On entry, a0 = number to print in binary print_binary: li $t1, 32 # Initialize a counter for the bit position (32 bits for unsigned) loop: beqz $t1, end # Exit the loop if all bits have been processed srl $t2, $a0, 31 # Get the most significant bit of the number andi $t2, $t2, 1 # Mask the least significant bit addi $t2, $t2, 48 # Convert the bit value to ASCII ('0' or '1') li $v0, 11 # syscall to print one char move $a0, $t2 # Load the bit value into $a0 syscall sll $a0, $a0, 1 # Shift the original number to the left by 1 bit addiu $t1, $t1, -1 # Decrement the counter j loop end: li $v0, 11 # syscall to print one char li $a0, 10 # Load newline character into $a0 ('\n') syscall jr $ra
错误原因分析
- 原始数字被覆盖:执行打印字符的系统调用时,代码将
$a0的值替换为ASCII字符,导致后续移位操作针对的是ASCII值而非原始输入数字,完全偏离预期逻辑。 - 移位对象错误:移位操作本应针对输入的原始数字,但由于
$a0被打印操作覆盖,实际操作的是已修改的ASCII值,导致后续所有位的提取全部错误。
修正后的print_binary子程序
仅修改print_binary部分,核心是用临时寄存器$t0保存原始输入数字,避免$a0被打印操作破坏:
# On entry, a0 = number to print in binary print_binary: li $t1, 32 # 初始化32位计数器 move $t0, $a0 # 将原始数字保存到$t0,避免$a0被打印操作覆盖 loop: beqz $t1, end # 计数器为0则退出循环 srl $t2, $t0, 31 # 逻辑右移31位,将最高位移到最低位 andi $t2, $t2, 1 # 提取最低位,得到0或1 addi $t2, $t2, 48 # 转换为ASCII的'0'或'1' li $v0, 11 # 打印单个字符的系统调用 move $a0, $t2 # 将ASCII字符传入$a0用于打印 syscall sll $t0, $t0, 1 # 对原始数字左移一位,准备下一位的打印 addiu $t1, $t1, -1 # 计数器减1 j loop
修正说明
- 新增
move $t0, $a0:将输入的原始数字保存到临时寄存器$t0,确保后续位提取和移位操作始终基于原始数字。 - 所有位操作改为针对
$t0:彻底避免$a0被打印操作覆盖后导致的逻辑错误。 - 保留逻辑右移
srl:对于32位无符号打印需求,逻辑右移能正确提取最高位(包括负数的符号位),结合andi可得到正确的0/1值。
内容的提问来源于stack exchange,提问作者Dayruiner
相关产品推荐
相关产品推荐

