Reputation: 1
i have a problem here understand this part of the code. can anyone explain me how this two orders (lsl and rol)works?
main:
clr r0
clr r22 ;
LDI ZL,LOW(AEMS)
ldi zh,HIGH(AEMS)
lsl zl
rol zh
mov r22,zl
aems contains : AEMS:.db $74,$91 ;7491 .db $76,$28 ;7628
Upvotes: 0
Views: 1651
Reputation: 12610
The two instructions together multiply the (16-bit) value in the Z
pointer register by 2.
But I can't see what that could be good for.
Usually, you take an index value (into an array), multiply that by the size of the array elements (2 for example) and then add the result to the pointer to the first element of the array, like
ldi r24, N ; Nth element of the array (0-based!)
clr r25
lsl r24 ; multiply by 2 for double-byte array elements
rol r25 ; (<- this is really only needed if the array is bigger than 256 bytes, otherwise r25 will always be 0)
ldi zl,LOW(AEMS)
ldi zh,HIGH(AEMS)
add zl, r24 ; add offset to base address
adc zh, r25
; Now Z points to the address of the Nth double-byte element from AEMS.
Upvotes: 0
Reputation: 4562
The pair of LSL and ROL performs one-bit double byte value shifting. LSL shifts lower byte and passes the former most significant bit of this byte to C flag in SREG. Then, ROL shifts the high byte, shifting in the bit from C flag into the least significant bit.
This method of shifting multibyte value is a widely used idiom and should be carefully remembered for both shift directions. Virtually it is supported in most processors with flags register, but details can differ (e.g. x86 names instructions RCL/RCR instead of AVR ROL/ROR). Also, with shifts more than for 1 bit at a time, another approach is more efficient (as x86 SHLD/SHRD).
Upvotes: 1