См .: Получение метки в регистре
Существует четыре способа получить метку в традиционном ARM:
target:
.long 0xfeadbeef, 0xdeadfeed, 0xbaddad00
adr r0,target
adrl r0,target
ldr r0,=target
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 является четным .