AVR Assembler - Data from a table in program memory (ATMega8)

Mar 19, 2008 6 Replies

I have a table in program memory and want to store a byte at a given location into register R16.



(This is just example data for testing)



MyTable: ; 256 bytes .db $00,$01,$02,$03,$04,$05,$06,$07,$08,$09,$0A,$0B,$0C,$0D,$0E,$0F .db $10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$1A,$1B,$1C,$1D,$1E,$1F .db $F0,$F1,$F2,$F3,$F4,$F5,$F6,$F7,$F8,$F9,$FA,$FB,$FC,$FD,$FE,$FF R17 contains a number between $00 and $FF which represents the offset from MyTable.



Can someone please show me a nice way of doing this?


-Mike

You need to use the LPM instruction, which uses the Z register pair (R31:R30). Something like (no guarantees on the syntax)

ldi r31, (high) MyTable ldi r30, (low) MyTable ;load base of table into Z pair add r30,r17 adc r31,#0 ;address of desired value now in Z pair lpm r16,Z ;fetch desired value

OK, looks like "adc r31,#0" isn't allowed. I suppose the alternative is

ldi r16,0 adc r31,r16

AVR assembly programmers, is there a better way here?

BTW, I know avr-gcc sets up a zero register (r1 IIRC). If you set one up in your program it would be useful to use here for the adc instruction (and many other places, presumably).

Thanks for the reply Mike.

Ok, I wasn't sure add(ing) to ZL (R30) would work on all 16 bits of the Z register.

I don't understand this. What's supposed to happen here?

-Mike

I see now. These three together work on the 16 bits.

Sounds like a good idea. I'll keep that in mind.

Thanks.

-Mike

No, it doesn't. We're adding an 8 bit value to the low 8 bits of Z (r30), which may or may not result in a carry out. If there is a carry we need to add it to the high 8 bits of Z (r31).

First of all, I replaced "#0" with "r1", assuming that r1 contains 0. This instruction is then adding the carry bit from the "add r30,r17" to r31.

Two examples, one without carry and one with:

Z =3D MyTable =3D 0x380 (r31 =3D 0x3, r30 =3D 0x80) r17 =3D 0x40 add r30,r17 =3D 0xC0 (no carry) adc r31,r1 =3D 3+0+C(=3D0) =3D 3 (no carry added to r31) r31:r30 =3D 0x3C0

2nd example, same MyTable base address r17 =3D 0xA0 add r30,r17 =3D 0x20 (with carry) adc r31,r1 =3D 3+0+C(=3D1) =3D 4 (adding the carry to r31) r31:r30 =3D 0x420

All very clear now. Thank you.

-Mike

Join the Discussion

Have something to add? Share your thoughts — no account required.

Didn't find your answer?

Ask the community — no account required