armv7-m голый металл ldr / str символика c память - PullRequest
2 голосов
/ 11 марта 2020

так что я знаю, что вопросов для ldr / str на руке бесчисленное множество. Возможно, это еще один поворот (не вероятно), или я просто что-то упускаю (более вероятно.)

Так что это голый металл, и я хочу загрузить / сохранить некоторую переменную в памяти. И потому, что я настаиваю, я хочу дать ему имя. Наивно я мог бы написать:

.section .bss
var: .word 0

.section .text
str r0, var 

(имея собственный скрипт компоновщика, который помещает .bss в ram и .text в fla sh)

Конечно, это не работает, потому что инструкции 32-битные и имеют место только для небольшого количества непосредственных. И инструкции, о которых я говорю, живут в fla sh, который равен 0x8000000 + x, и переменная должна храниться в памяти, которая находится где-то в 0x20000000 + y.

Вручную я знаю довольно много способов, чтобы решить эту проблему:

  • хранение адреса переменных в константе (varaddr: .word 0x2001234; ldr r1, [pc,#varaddr]; str r0, [r1])
  • загрузка ram-base в регистр и относимся к нему относительно (ldr r1, #0x20000000; str r0, [r1,#varoffset])
  • , строим адрес по арифметике c (mov r1, #0x2000000; add r1, #offset / orr / movw / movt something)
  • , конечно, еще немного

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

Так что мне здесь не хватает. Является ли моя идея для скрипта компоновщика и фальшивых ярлыков? Есть какая-то особенность ассемблера, которую я не видел? Что-то совершенно другое?

1 Ответ

2 голосов
/ 11 марта 2020

Один из способов использовать имена символов 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.

...