Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Assembly Loop Through Each Bit of Register Value

I have a register $t0 that has some integer stored to it. For example, say I store the integer 1100 to it. The binary representation of this value is 0000010001001100. Of course it may extend to 32 bits for 32 bit register but that is easily done.

I am trying to implement a loop in assembly that iterates through each bit of the register value and checks if it is a 1 or 0. How would one do this?

Perhaps I misunderstand the nature of a register. It is my understanding that the register stores a 32 bit number, yes? Does that mean each bit is stored at a specific address?

I have tried using shift for the register and checking the bit but that has failed. I also looked into the lb command but this loads the byte, not the bit. So what would one do?

like image 583
user3794422 Avatar asked Dec 21 '25 16:12

user3794422


1 Answers

some basics:

most(all?) shift instructions shift out the bit into the carry flag

most(all?) CPUs have a branch command, to jump to the location on carry flag set

combining this, you could do the following:

load register1,< the value to be tested >
load register2, 0

Lrepeat:
    compare register1 with 0
    jump if zero Lexit

    shift right register1
    jump no carry Lskip
    increase register2 
Lskip:
    jump Lrepeat

Lexit:                      ; when you end up here, your register2
                            ; holds the count of bit register1 had set

some optimization still can be done:

Lrepeat:
    compare register1 with 0
    jump if zero Lexit
    shift right register1
    jump no carry Lskip       <-- note: here you jump ...
    increase register2 
Lskip:
    jump Lrepeat              <-- ... to jump again!
Lexit:

=====>

Lrepeat:
    compare register1 with 0
    jump if zero Lexit
    shift right register1
    jump no carry Lrepeat     <-- so you can optimize it this way
    increase register2 
Lskip:
    jump Lrepeat             
Lexit:

some CPUs have an "add carry" instuction, e.g. 6502:

ADC register,value      ; register = register + value + Carry flag

this could be used to avoid the branch (conditional jump), by adding 0 ( plus Carry of course) to register2 each loop

    shift right register1
    add with carry register2,0   ; may look weird, but this adds a 
                                 ; 1 if the carry is set, which is
                                 ; exactly what we want here
    jump Lrepeat

note that you don't need to know the register size! you just loop until the register is 1, which can save you a lot of time e.g. if your value is something like 0000 0000 0000 0000 0000 0000 0001 1001

like image 151
Tommylee2k Avatar answered Dec 24 '25 11:12

Tommylee2k



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!