I’m trying to move bits from starting register into eight consecutive registers. I’ve just started writing in assembly so I dont really know what to do.
I tried to use rol and lsr instructions. But my loop just reverses the bits. can i change the registry from r18 to r19 mid-loop?
.equ sequen = 0x10001011
ldi r17
ldi r16, 0x8
next: lsr r17
rol r18
;is there a way to move
;to next register, not
; inc its value?
dec r16
brbc 1, next
rjmp pc
CodePudding user response:
As say Peter Cordes it is possible. For example like this
.equ sequen = 0b1000_1011
ldi r17, sequen
ldi r16, 0x8
ldi zl,18 ;Z (ZH:ZL) is used as indirect address register (pointer in C terminology)
ldi zh,0 ;this two instruction set Z to 18 - address for first value. See AVR memmory map for details
clr r0
next:
bst r17,0
bld r0, 0
st z , r0 ;save result to register and increase address (18, 19, ...|
lsr r17
dec r16
brne next
rjmp pc
CodePudding user response:
The pattern I would use in pseudo code is this.
You start with register V holding your 8 bit value, eg 0xe4 1110 0100
Set reg B to the bit pattern 0x01 Results go into R0 to R7
((V & (B << 0)) >> 0) & 0x01 goes into R0 (the bottom bit, ie bit 0) 0x00
((V & (B << 1)) >> 1)& 0x01 goes into R1 (the next bit, ie bit 1) 0x00
((V & (B << 2)) >> 2)& 0x01 goes into R2 0x01
((V & (B << 3)) >> 3)& 0x01 goes into R3 0x00
((V & (B << 4)) >> 4)& 0x01 goes into R4 0x00
((V & (B << 5)) >> 5)& 0x01 goes into R5 0x01
((V & (B << 6)) >> 6)& 0x01 goes into R6 0x01
((V & (B << 7)) >> 7)& 0x01 goes into R7 0x01
It could be loop where you left shift the initial bit pattern and then right shift the result of that by the shift value, then you move the result into memory location offset by the shiftvalue.
At the end of the loop, incr shiftValue and compare (or subtract) against end value jump conditionally to loop start.
loop:
((V & (B << ShiftValue)) >> ShiftValue) goes into Memory Shiftvalue
ShiftValue subtract 0x80
jump when zero loop: