logical shift and rotate

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

Answers (2)

JimmyB
JimmyB

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

Netch
Netch

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

Related Questions