Преиндексная и постиндексная адресация

Последнее обновление: 14.07.2023

Преиндексная адресация

В ходе обычной адресации со смещением значение базового регистра никак не изменяется. Преиндексная адресация применяется, когда также надо обновить значение базового регистра новым адресом с учетом смещения. При подобной адресации в конце выражения указывается восклицательный знак !:

LDR Xt, [Xn, #imm]!   // Xn = Xn + #imm

В качестве смещения может выступать только непосредственный операнд. Например:

.global _start 
_start:
    ldr x1, =nums      // загружаем в X1 адрес nums
    ldrb w0, [x1, #1]!    // х1 = x1 + #1;  X0=12

    mov x8, #93       // устанавливаем функцию Linux для выхода из программы
    svc 0             // Вызываем функцию Linux

.data
    nums: .byte 11, 12, 13, 14, 15, 16, 17, 18

Здесь в регистр Х1, который выступает в качестве базового регистра, помещается адрес массива байтов nums. Допустим, мы хотим получить второй элемент в этом массиве. Поскольку все числа в массиве размером 1 байт, то адрес второго элемента от начала массива будет отличаться на 1 байт. Соответственно используем смещение в 1 байт:

ldrb w0, [x1, #1]!

В данном случае происходит следующая последовательность действий:

  1. Вычисляется новое значение адреса: address = x1 + #1

  2. Считывается 1 байт, который располагается по новому адресу address (x1 + #1)

  3. Считанный байт помещается в регистр W0

  4. В регистр Х1 помещается вычисленный адрес address (x1 + #1)

В результате обновляется значение базового регистра - к нему прибавляется смещение - 1, а в регистр W0 помещается байт по вычисленному адресу.

Постиндексная адресация

При постиндексной адресации сначала идет обращение по адресу в базовом регистре, а затем вычисляется новый адрес на основе смещения и вычисленный адрес помещается в базовый регистр. то есть если при преиндексной адресации обращение идет по новому адресу, то при постиндексной адресации обращение идет по старому адресу.

При постиндексной адресации смещение в виде непосредственного операнда указывается за квадратными скобками

LDR Xt, [Xn], #imm

Изменим предыдущий пример, применив вместо преиндексной постиндексную адресацию:

.global _start 
_start:
    ldr x1, =nums      // загружаем в X1 адрес nums
    ldrb w0, [x1], #1    // X1 = X1 + X2 ; X0=11
    mov x8, #93       // устанавливаем функцию Linux для выхода из программы
    svc 0             // Вызываем функцию Linux

.data
    nums: .byte 11, 12, 13, 14, 15, 16, 17, 18

Здесь также в базовый регистр Х1 помещается адрес массива байтов nums и также используем смещение в 1 байт:

ldrb w0, [x1], #1

В данном случае происходит следующая последовательность действий:

  1. Считывается 1 байт, который располагается по адресу в X1

  2. Считанный байт помещается в регистр W0

  3. Вычисляется новое значение адреса: address = x1 + #1

  4. В регистр Х1 помещается вычисленный адрес address (x1 + #1)

В результате обновляется значение базового регистра - к нему прибавляется смещение - 1, а в регистр W0 помещается байт по старому адресу.

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850