-1

Consider the following code portion in AVR assembly for the ATmega16 micro controller:

LDI ZH, high(DATA << 1)
LDI ZL, low(DATA << 1)
LPM R16, Z

.org $ffff
DATA: .db 7

This should load the value stored at DATA into register R16.

But here's my question. According to the ATmega16 datasheet and appnote, in order to address that byte in question I need to shift the address by one. However when I deposit my data at address $FFFF (at the theoretical very end of flash), I can't shift the address left, otherwise I'd shift out the MSB of the address.

How am I supposed to address anything that is stored after address $7FFF? Or is it just impossible to do so?

In the definition file for the micro controller in question (m16def.inc), there is a FLASHEND declaration set to 0x1FFF, so that would prevent me from putting anything past that, technically. But assuming the flash would go up to word addresses past 0x7FFF, how would I retrieve data from there? Or is it simply impossible and the theoretical highest word address is 0x7FFF?

polemon
  • 4,722
  • 3
  • 37
  • 48
  • 3
    The instruction set reference says about `LPM`: _"this instruction can address the first 64K bytes (32K words) of Program memory."_ Thus you can't use to address `0xffff` (words). For that you should use the `ELPM` instruction which supports 24 bit addressing via the `RAMPZ` register. – Jester Aug 27 '23 at 23:19
  • @jester I'm looking at the instruction set manual right now, `RAMPZ` contains the third byte needed for `Z` byte addressing, it seems. Is that correct? – polemon Aug 28 '23 at 03:04
  • 1
    @polemon That is correct, you would need to execute another rotate instruction in order to transfer the carry bit into the third byte. Do note however, that the ATMEGA16 only has 16k memory, so this is unnecessary ( as you seemingly already know). – dvd280 Aug 28 '23 at 07:15
  • 1
    The last byte of ATmega16 program memory is at byte address `0x3fff`. – emacs drives me nuts Aug 28 '23 at 10:21

0 Answers0