Vou responder a essa pergunta especificamente para os controladores AVR que você mencionou. O princípio básico também é válido para muitas outras arquiteturas de 8 bits.
AVRs são núcleos de 8 bits. Isso significa que eles têm registradores de 8 bits. No entanto, 8 bits não são suficientes para acessar uma quantidade utilizável de memória. Portanto, o núcleo do AVR pode usar um conjunto específico de registros combinados como registros de ponteiro de 16 bits. Os registros r30 e r31 (também conhecido como ZL e ZH) são um exemplo disso. Juntos, eles formam o ponteiro Z.
Na montagem, a leitura de um byte no endereço 0x1234 ficaria assim:
ldi ZL, 0x34 ; Load r30 (ZL) with low byte of address
ldi ZH, 0x12 ; Load r31 (ZH) with high byte of address
ld r16, Z ; Load byte to r16
A família AVR possui 3 pares de registros que podem ser usados para isso. Eles são projetados especificamente em hardware para permitir essas operações.
Ao programar em uma linguagem de nível superior como C, o compilador lida com essas coisas.
Nota: Alguns AVRs até suportam tamanhos de memória maiores que 64k. Esses controladores possuem um registro de função especial no qual bits adicionais do endereço são gravados antes do acesso. O endereço, portanto, consiste nos seguintes bits (MSB para LSB):
Registro de função especial (geralmente 1 byte), ZH (8 bits), ZL (8 bits).