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

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
Reply to
Mike Warren
Loading thread data ...

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

Reply to
Mike Silva

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).

Reply to
Mike Silva

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
Reply to
Mike Warren

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

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

Thanks.

--
-Mike
Reply to
Mike Warren

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
Reply to
Mike Silva

All very clear now. Thank you.

--
-Mike
Reply to
Mike Warren

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.