Ldi R31, high(arr) ; загрузка в R31 старшего байта адреса arr
;...
ldd R10, Z + 0 ; загрузка первого элемента массива arr в R10
ldd R11, Z + 1 ; загрузка второго элемента массива arr в R11
4. При косвенной адресации оперативной памяти данных с предекрементом (лат. decrementum – уменьшение, убыль) перед выполнением команды содержимое указанного в команде регистра X, Y или Z декрементируется (уменьшается на единицу); декрементированное содержимое регистра X, Y или Z является адресом операнда в оперативной памяти данных (рис. 15). Косвенная адресация с предекрементом используется в команде LD косвенной загрузки из ОЗУ и команде ST косвенной загрузки в ОЗУ. Например:
; косвенная адресация с предекрементом
ld R10, -Z ; Z <- Z – 1, R10 <- (Z)
5. При косвенной адресации оперативной памяти данных с постинкрементом (лат. incrementum – увеличение, рост) адресом операнда в оперативной памяти данных является содержимое регистра X, Y или Z, указанного в команде; после выполнения команды содержимое регистра X, Y или Z инкрементируется, т. е. увеличивается на единицу (рис. 16). Косвенная адресация с постинкрементом используется в команде LD косвенной загрузки из ОЗУ и команде ST косвенной загрузки в ОЗУ. Например:
; косвенная адресация с постинкрементом
ld R10, Z+ ; R10 <- (Z), Z <- Z + 1
Для адресации памяти программ используется непосредственная адресация, косвенная адресация, относительная адресация, адресация константы и адресация константы с постинкрементом*.
При непосредственной адресации памяти программ выполнение программы продолжается с адреса, указанного в команде (рис. 17; FLASHEND – символическое имя адреса последней ячейки памяти программ). Непосредственная адресация памяти программ используется в командах JMP и CALL.
При косвенной адресации памяти программ выполнение программы продолжается с адреса, содержащегося в регистре Z, т. е. в программный счётчик загружается содержимое регистра Z (рис. 18). Косвенная адресация памяти программ используется в командах IJMP и ICALL.
При относительной адресации памяти программ выполнение программы продолжается с адреса (PC + k + 1), где PC – содержимое программного счётчика; k – указанный в команде относительный адрес, который может принимать значения от –2048 до 2047 (рис. 19). Относительная адресация памяти программ используется в командах RJMP и RCALL.
При адресации константы адрес байта константы содержится в регистре Z (рис. 20): старшие 15 разрядов занимает адрес ячейки памяти программ (от 0 до 32 К); состояние младшего разряда (LSB) определяет выбор младшего
(LSB = 0) или старшего (LSB = 1) байта адресуемой ячейки памяти. Адресация константы в памяти программ используется в командах LPM (Load Program Memory), которая загружает адресованный регистром Z байт в указанный в команде регистр. Если регистр-приёмник не указан (команда используется без операндов), байт загружается в регистр R0. Команда ELPM (Extended Load Program Memory) служит для загрузки константы из памяти программ объёмом более 64 Кслов. При этом для расширения регистра-указателя Z используется регистр RAMPZ, связанный с регистром Z.
Задать данные в память программ позволяет директива .db (define bytes). Для того чтобы на заданные ячейки памяти можно было ссылаться, директиве должна предшествовать метка. Параметры директивы – последовательность выражений, разделённых запятыми; каждое выражение должно быть числом в диапазоне –128…255 или в результате вычисления давать результат в этом же диапазоне, в противном случае число усекается до байта. Директива .db размещается в программном сегменте и может использоваться совместно с директивой .org. Задавать положение данных в памяти программ следует таким образом, чтобы была исключена возможность непреднамеренного перехода к выполнению их как команд микроконтроллера.
Пример использования адресации константы в памяти программ:
ldi R31, high(var<<1) ; старший байт регистра Z
ldi R30, low(var<<1) ; младший байт регистра Z
LPM R16, Z ; загрузка числа $50 в R16
;...
.org $0025 ; по адресу $0025
var: .db $50, 137 ; константы $50 и 137
В приведённом примере использован оператор <<, выполняющий сдвиг операнда влево на указанное число разрядов.
При адресации константы в памяти программ с постинкрементом адрес байта константы содержится в регистре Z и формируется так же, как и при адресации константы (рис. 21). Адресованный регистром Z байт загружается в указанный регистр; после выполнения команды содержимое регистра Z инкрементируется. Адресация константы в памяти программ с постинкрементом используется в командах LPM и ELPM. Например:
ldi R31, high(var<<1) ; старший байт регистра Z
ldi R30, low(var<<1) ; младший байт регистра Z
lpm R16, Z+ ; загрузка числа $50 в R16, инкремент Z