简体   繁体   中英

Assembly MIPS: decimal to 32-bit binary with pseudo-rotating

I recently found out that MIPS does not rotate bits, but only shifts them, so I kept digging this hole to make a rotate-like function for MIPS that works as far as I tested it (function named "shifting" at the code below). Basically it stores the 4 MSB's of a given number, turns it to LSB's, shifts the number 4 bits to the left and then joints the former-MSB's-turned-LSB's with the shifted number.

Aaaannnd alakazam! The number is "rotated" 4 bits to the left.

So I've been thinking of putting this to work as far as printing a number in full binary, by checking the last 4 bits for each rotation.

Let's say the given number looks like below:

aaaa bbbb cccc dddd eeee ffff gggg hhhh iiii

by rotating to the left for 4 bits, we check the value of aaaa :

bbbb cccc dddd eeee ffff gggg hhhh iiii aaaa

and keep on rotating, checking and printing the value of bbbb :

cccc dddd eeee ffff gggg hhhh iiii aaaa bbbb

until we finally get to the same number we started and check the last 4 bits, iiii :

. . .

aaaa bbbb cccc dddd eeee ffff gggg hhhh iiii

But I've been having a problem with my code that keeps on adding 0's untill the compiler crashes.

.text
main:
li  $v0, 5          #v0 = the given integer
syscall

move $t1, $v0           moving the integer to t1

add $s1, $zero, $zero   #s1 = counter

shifting:
    andi    $t2, $t1, 0xF0000000    #t2 = the 4 MSB's that get pushed to the left
    srl     $t3, $t2, 28        #turning them to LSB's

    sll     $t4, $t1, 4         #shifting the integer

    or      $t5, $t3, $t4       #$t5 = the pseudo-rotated number


loop:
    andi    $t6, $t5, 0xF       #isolating the 4 new LSB's
    beq $t6, 0xF, one           #print 1's where is necessary 

    li  $v0, 1         #else print 0's
    la  $a0, 0
    syscall
j shifting  

next:
    addi    $s1, $s1, 1
    beq     $s1, 32, exit    #stop printing at 32 numbers

one:                #printing the aces
    li  $v0, 1
    la  $a0, 1
    syscall
j shifting  

exit:
li  $v0, 10
syscall

It seems that I've toasted my brain overthinking about this thing, and I can't really keep up with the loops.

What is wrong with my code?

So I've lost a bit of focus for a moment but I got it working:

.text
main:
li  $v0, 5          #v0 = the given integer
syscall

move    $t1, $v0        #moving integer to t1

add $s2, $zero, $zero   #counter for all the 4bits

shifting:

    andi    $t2, $t1, 0xF0000000    #t2 = the 4 MSB's that get pushed to the left
    srl $t3, $t2, 28         #turning them to LSB's

    sll     $t4, $t1, 4          #shifting the integer

    or  $t5, $t3, $t4       #$t5 = the pseudo-rotated number  

    andi    $t6, $t5, 0xF       #isolating the 4 LSB's

check:  

    beq     $s2, 8, exit        #32 bits = 8x 4bits
    addi    $s2, $s2, 1     #adding the counter for the 4bits

    li  $v0, 11         #spaces between 4bits
    li  $a0, ' '
    syscall

    add $s1, $zero, $zero   #counter for each bit in a 4bit

bts:
    andi    $a0, $t6, 8         #4bit AND 8
    beq     $a0, 8, one     #if a0 = 8 print 1

    li  $v0, 1          #else print 0
    li  $a0, 0
    syscall

next:
    sll     $t6, $t6, 1     #shift the bit to the left

    addi    $s1, $s1, 1     #adding the counter for one 4bit

    move    $t1, $t5        #shift the pseudo-rotated number next time

    beq $s1, 4, shifting    #make sure the 4bit will have 4 bits

one:            #function that prints 1's
    li  $v0, 1
    li  $a0, 1
    syscall
j next  

exit:
li  $v0, 10
syscall

I'll try to make it work for float numbers, when I have the time.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM