Как загрузить несколько данных непосредственно из метки в регистры - PullRequest
2 голосов
/ 03 октября 2019

Я хотел знать, есть ли способ загрузить, скажем, массив слов, хранящихся в памяти, в массив регистров.

Я знаю, что ldm можно использовать для загрузки сразу нескольких регистров, ноНасколько я понимаю, вам нужно предоставить ему регистр, который уже содержит первый элемент.

Есть ли какая-нибудь псевдоинструкция, которая может помочь? Что-то вроде ldm = array, {r0, r1, r2} (созданный по образцу псевдоинструкции ldr).

Заранее спасибо!

1 Ответ

1 голос
/ 05 октября 2019

См .: Получение метки в регистре

Существует четыре способа получить метку в традиционном ARM:

 target:
     .long 0xfeadbeef, 0xdeadfeed, 0xbaddad00
  1. adr r0,target
  2. adrl r0,target
  3. ldr r0,=target
  4. sub r0,pc,#(.+8-target)

Thumb2 добавляет комбо movw movt,но это не работает для вашего варианта использования.

Пункты 1,2,4 в основном одинаковы. Элемент 3 добавляет адрес как константу к буквальному пулу , и этот адрес загружается в регистр. Что-то вроде 'C', например.

int variable;
const int *p = &variable;
int *reg = p; /* load register from memory */

Есть ли какая-нибудь псевдоинструкция, которая может помочь? Что-то вроде ldm = array, {r0, r1, r2} (созданное после фактической псевдоинструкции ldr).

Для этого нет псевдооперации;Вы должны напрямую кодировать вещи.

Учитывая приведенное выше определение 'target' с тремя значениями, вы можете сделать это с помощью ...

 target:
     .long 0xfeadbeef, 0xdeadfeed, 0xbaddad00
 adr  r0, target
 ldm  r0, {r0-r2}  ; r0 as source/dest should work without write back
                   ; ldm r0, {r1-r3} maybe safer.

Псевдооперации не реализованы, так как это 'редко', а ldm является ограничительным и не поддерживает смещения ПК как источника. Что-то вроде

 ; I just thunk it.
 ldm pc, {r0-r2,pc}  ; pc is always '8' ahead, assuming arm mode.
 nop
 .long arg0, arg1, arg2, routine

возможно, но ограничительно, поскольку данные должны позиционироваться с помощью кода, а поток управления также ограничен. Опять же, это редкий случай использования, и псевдооперация заключается в том, чтобы упростить ввод произвольных констант в регистры, что обычно необходимо. Так что есть только прямое кодирование ldm команд. Возможно, что некоторые ARM CPU / architechure не поддерживают тот же регистр, что и пункт назначения;определенно не поддерживается с обратной записью (rN!). Это зависит от класса целевых процессоров ARM. Использование PC в качестве источника, вероятно, еще более маловероятно для работы с большим классом процессоров ARM. Я бы порекомендовал первый пример (rN! = R15), если вы не исчерпали регистры и не используете известный процессор SOC / конкретного процессора ARM.


Инструкция ldrd - это ограниченная загрузка двойного слова, ноу источника больше гибкости. Вы можете использовать его для загрузки двух значений без отдельного adr. Например,

ldr r0, r1, [pc, #offset]

Но оно ограничено двумя регистрами. Целевой регистр должен быть последовательным, и первым является rN, где N % 2 равно нулю или N является четным .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...