Один из способов использовать имена символов c для переменных в хранилище c - это определить структуру для ваших переменных. Это позволяет вам загружать базовый адрес вашей структуры в регистр, а затем обращаться к членам структуры, используя имена символов c относительно базового адреса. Например, вы можете сделать:
.struct 0 @ start a new structure
foo: .skip 4 @ length of foo
bar: .skip 4 @ length of bar
baz: .skip 4 @ length of baz
len: @ total length of the structure
.section .bss @ switch to the BSS (uninitialised data) section
.balign 4 @ align to 4 bytes
variables:
.space len @ reserve space for your variables
.section .text @ switch to the text (code) section
...
ldr r0, =variables @ load r0 with the base address of your variables
ldr r1, [r0+#foo] @ access foo
str r2, [r0+#bar] @ access bar
ldr r3, [r0+#baz] @ access baz
Это в значительной степени ближе всего к символическим c именам переменных в хранилище stati c. Если переменные находятся в стеке, вы можете использовать аналогичный подход, используя указатель кадра (или указатель стека) в качестве базового адреса. Операнд к .struct
является базовым адресом структуры, для которой вы можете выбрать любое значение, которое вам нравится.
Что касается movw
и movt
. Они дают небольшое преимущество в производительности для некоторых микроархитектур по сравнению с ldr ..., =...
, поскольку они не требуют выборки данных в текстовый раздел. Насколько я знаю, это не имеет значения для целей armv7-m; также movw
и movt
потребляют два дополнительных байта против ldr
с операндом =
. Поэтому я рекомендую вам придерживаться ldr
и =
операнда. Использование movw
и movt
выглядит следующим образом:
movw r0, :lower16:foo @ load lower 16 bit of foo's address into r0
movt r0, :upper16:foo @ or higher 16 bit of foo's address into r0
Эти два должны быть выполнены в указанном порядке c, поскольку movw
очищает старшие 16 бит. Префиксы :lower16:
и :upper16:
выбирают соответствующие типы перемещения, ссылаясь только на младший и верхний 16-битный адрес символа. Вы можете сделать макрос, чтобы было проще набирать:
.macro addr reg, sym
movw \reg, :lower16:\sym
movt \reg, :upper16:\sym
.endm
Это позволяет писать
addr r0, foo
для генерации вышеупомянутой пары movw
и movt
.