Загрузка и сохранение двух регистров. LDP и STP

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

В дополнение к инструкциям LDR и STR ассемблер предоставляет дополнительные инструкции, которые позволяют загружать и сохранять сразу два регистра:

  • LDP: загружает значение из памяти в два регистра

  • STP: сохраняет значение в память из двух регистров

Обе инструкции оперируют двумя регистрами:

LDP Xn, Xm, [Xs]
STP Xn, Xm, [Xs]

LDP Wn, Wm, [Xs]
STP Wn, Wm, [Xs]

В качестве первых двух регистров могут выступать либо 64-разрядные X0-X30, либо 32-разрядные W0-W30. В случае с 64-разрядной версией в Xn помещаются младшие 64 разряда, а в Xm старшие 64 разряда. В случае с 32-разрядной версией в Wn помещаются младшие 34 разряда, а в Wm старшие 34 разряда.

В качестве третьего - базового регистра могут выступать либо регистры X0-X30, либо указатель стека SP. Например:

.global _start 
_start:
    ldr x0, =num1      // загружаем адрес метки num1 в Х1
    ldp x1, x2, [x0]   // загружаем данные в Х1 и Х2: Х1=11, X2=12

    add x1, x1, #10     // для теста изменяем значения регистров
    add x2, x2, #10
    
    stp x1, x2, [x0]   // сохраняем данные из Х1 и Х2: num1=21, num2=22

    ldr x0, num1    // для теста проверяем num1: X0=21

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

.data
    num1: .quad 11
    num2: .quad 12

Сначала в Х0 загружается адрес метки num1.

ldr x0, =num1 

Далее в регистры X1 и X2 загружаются данные по адресу из регистра X0

add x1, x1, #10     // для теста изменяем значения регистров
add x2, x2, #10

Затем сохраняем значения регистров Х1 и Х2 обратно в область по адресу из Х0:

stp x1, x2, [x0]

В итоге значение Х1 будет загружаться в первые 64 байта (в то есть в переменную num1), а значение регистра Х2 - в следующие 64 байта.

Таким образом, инструкции LDP и STP упрощают работу, если надо разом загрузить или сохранить два регистра.

Стоит отметить, что для инструкций LDP и STP доступны те же виды адресаций, что и для LDR и STR:

  • Через базовый регистр (как в примере выше)

    LDP Xt1, Xt2, [Xn|SP] 
    LDP Wt1, Wt2, [Xn|SP]
    
    STP Xt1, Xt2, [Xn|SP] 
    STP Wt1, Wt2, [Xn|SP]
    
  • Через базовый регистр плюс смещение

    LDP Xt1, Xt2, [Xn|SP, #imm] 
    LDP Wt1, Wt2, [Xn|SP, #imm]
    
    STP Xt1, Xt2, [Xn|SP, #imm] 
    STP Wt1, Wt2, [Xn|SP, #imm]
    
  • Через базовый регистр (как в примере выше)

    LDP Xt1, Xt2, [Xn|SP] 
    LDP Wt1, Wt2, [Xn|SP]
    
    STP Xt1, Xt2, [Xn|SP] 
    STP Wt1, Wt2, [Xn|SP]
    
  • Преиндексная адресация

    LDP Xt1, Xt2, [Xn|SP, #imm]! 
    LDP Wt1, Wt2, [Xn|SP, #imm]!
    
    STP Xt1, Xt2, [Xn|SP, #imm]! 
    STP Wt1, Wt2, [Xn|SP, #imm]!
    
  • Постиндексная адресация

    LDP Xt1, Xt2, [Xn|SP], #imm 
    LDP Wt1, Wt2, [Xn|SP], #imm
    
    STP Xt1, Xt2, [Xn|SP], #imm 
    STP Wt1, Wt2, [Xn|SP], #imm
    
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850