# A confusion on flash memory map of an AVR micro-controller

I'm trying to figure out the flash memory map of ATmega328P:

Below is from the datasheet:

Program Memory Map for ATmega328P is given as 32KB: 32Kbytes = 32K * bytes

0x0000 means 16 bit wide (for each line of memory there is 2 bytes)

which is 16K * 16bit

What I understand from this, the flash memory is made up of 16K lines of 16 bit wide registers. So for an instruction on the flash memory the maximum address number is 16K.

Is this 16K 2^16 or 16000?

The last three X Y Z general purpose registers which are used for holding the addresses(pointers) are 16-bit which can store up to 2^16 = 65536 addresses. So I would guess 16K means 65536 here?

But if it is, in the above figure it shows the last memory line as 0x3FFF which corresponds to 16383.

What am I knowing wrong here?

What you are knowing wrong are a couple of things.

Not all AVR devices have the same amount of actual available on-chip program memory. Some may have 8K bytes, 16K bytes, 32K bytes or even 64K bytes. Yours happens to have the advertised 32K bytes.

The X, Y and Z registers are 16-bits wide. These are generically designed to support a data memory map up to 64K bytes. Once again the size of available data memory can vary from device to device type so the whole 64K byte addressability may not be used on all devices.

The X, Y and Z registers are generically indicated right in the data sheet description to be used for accessing data memory. Data memory is not to be confused with program memory. The Z register can be used, in conjunction with certain specific opcodes, to access tables in the program memory (Z still 16-bits to support up to a generic 64K bytes even though the program memory available may be less).

• LPM/ELPM/SPM, which access program memory, are intended to be used with Z. – Ignacio Vazquez-Abrams Dec 10 '16 at 17:26
• I know. I was just going to add that to my answer. – Michael Karas Dec 10 '16 at 17:29
• But data memory is far less than the 16K adress program memory it is only 2KB. X Y Z needed for that 2048 addresses?? – user16307 Dec 10 '16 at 17:31
• Whille it doesn't require 16 bits to address 2KB, it is convenient to have all registers either 8 or 16 bits long - things would get messy if the registers were trimmed to the minimum size required. If the X, Y and Z registers are 16 bits, they can be used for many other things than just addressing RAM. – Peter Bennett Dec 10 '16 at 18:15
• "The X, Y and Z registers are generically indicated right in the data sheet description to be used for accessing data memory." I don't get that: Imagine the processor wants to store the last address number(by pointer) of the flash/program memory which is 16383 to one of its general purpose registers. You say 16 bit X Y Z will only hold data about SRAM. The rest of general purpose CPU registers are 8 bit wide. The max number they can hold is 2^8 which is 256. Where will the number 16383 be stored in CPU registers in that case? – user16307 Dec 10 '16 at 23:09

Is this 16K 2^16 or 16000?

... Neither.

It is 16 * 1024 = 16384.