assemblymipsbit-shiftpcspim

Displaying number in Binary by shifting


I made a program in which I try to display the binary form of a number input by user. But the program isn't doing the masking correctly. What should I do to solve it?

user input in $s0

Loop:

and $t0,$s0,2147483648  // anding it with this number because only its MSB is 1 all other bits are zero

sll $s0,$s0,1

move $a0,$t0

li $v0,1
syscall

beq $t1,31,Exit

addi $t1,$t1,1
j Loop

UPDATE: I modified this code as suggested by dbrank0, but now it displays only one bit instead of 32 bits

Loop:

and $t0,$s0,2147483648

sll $s0,$s0,1

beq $t1,31,Exit

move $a0,$t0

addi $t1,$t1,1

bgtu $t0,0,Check

li $t0,0
j Loop

Disp:
li $v0,1
syscall

j Loop

Check:
li $t0,1

j Disp

It will be a great deal if someone can help me solve this problem.

Regards


Solution

  • Here's a problem:

    bgtu  $t0, 0, Check
    li    $t0, 0
    j     Loop
    

    If it's a zero, it doesn't get displayed because you're jumping to Loop instead of Disp. Oh look, Disp is written immediately after this instruction anyhow! Solution: get rid of the jump altogether.

    Here's another problem, as dbrank0 described:

    Disp:
    li $v0,1
    syscall
    

    This will display the contents of $a0 as an integer. But if the bit was a 1, the value of $a0 will be 0x80000000, not 1! When you try to print 0x80000000, it'll treat it as a signed integer and print -2147483648 instead.

    Here's another problem:

    beq $t1,31,Exit
    

    Firstly, this instruction is in an awkward place. Why are you checking for an exit condition after the and and shift? You should check for it either at the start or the end, not in the middle. Furthermore, you need to check against 32 because there are 32 bits and you check before printing each bit. Currently the last bit will get chopped off as a result.


    There's a clever way to make your program do less work than it needs to. Take advantage of the fact that you're displaying from left to right (ie, the most significant bit is being displayed first). When the MSB is set, it can be treated as a negative number in two's complement!

    li     $t0, 32
    li     $v0, 1
    
    Loop:
    bltz   $s0, Bit1
    li     $a0, 0
    j      Disp
    
    Bit1:
    li     $a0, 1
    
    Disp:
    syscall
    
    Tail:
    subi   $t0, $t0, 1
    beqz   $t0, Exit
    sll    $s0, $s0, 1
    j      Loop
    
    Exit: