Справка по сборке ARM для CortexM - PullRequest
0 голосов
/ 03 августа 2020

Мне нужно создать функцию ASM. Я сделал большую часть этого, но мне не удается заставить его работать должным образом. Я хочу сделать al oop, который работает до бесконечности, пока бит в определенном регистре (SysTick-> CTRL Flag) не будет установлен. Я использовал TST r5, # Val. Значение val равно 1 << 16, записано как шестнадцатеричное. Затем я делаю метку BNE to l oop. Он просто выходит из l oop. r5 берется из STR r5, [r0, # 0], где r0 имеет адрес SysTick CTRL. Есть ли у кого-нибудь полные примеры функций ASM. Я использовал .global funcname. Я использовал текст .segment. Я использовал .thumb_func. Есть ли другие причины для беспокойства? </p>

1 Ответ

0 голосов
/ 03 августа 2020

Прежде всего, ассемблер указан c для ассемблера.

Для gnu

.thumb
.globl myfun
.thumb_func
myfun:
    ldr r0,=0x12345678
myfun_inner:
    ldr r1,[r0]
    cmp r1,#0
    bne my_fun_inner
    bx lr

so.o:     file format elf32-littlearm


Disassembly of section .text:

00000000 <myfun>:
   0:   4802        ldr r0, [pc, #8]    ; (c <myfun_inner+0xa>)

00000002 <myfun_inner>:
   2:   6801        ldr r1, [r0, #0]
   4:   2900        cmp r1, #0
   6:   d1fe        bne.n   0 <my_fun_inner>
   8:   4770        bx  lr
   a:   0000        .short  0x0000
   c:   12345678    .word   0x12345678

gnu имеет интересный странный ярлык ярлыка, который мне не особенно нравится, но некоторые делают :

.thumb
.globl myfun
.thumb_func
myfun:
    ldr r0,=0x12345678
1:
    ldr r1,[r0]
    cmp r1,#0
    bne 1b
    bx lr

думайте о 1b как о 1 назад, вы можете иметь несколько меток 1 :, 2: et c в этом коде, а 1b или 1f будут ссылаться на ближайший 1: вперед или назад. и производит тот же код.

   6:   d1fe        bne.n   0 <my_fun_inner>

Это относительный скачок, поэтому, хотя я дизассемблировал объект, когда вы связываете и дизассемблируете связанный двоичный файл, это будет тот же машинный код.

ldr r0,=0x12345678

Псевдокод, поддерживаемый некоторыми ассемблерами ARM. В частности, Gas попытается найти оптимизированное решение:

.thumb
ldr r0,=0x12345678
ldr r0,=1
ldr r0,=0x20002

00000000 <.text>:
   0:   4802        ldr r0, [pc, #8]    ; (c <.text+0xc>)
   2:   f04f 0001   mov.w   r0, #1
   6:   f04f 1002   mov.w   r0, #131074 ; 0x20002
   a:   0000        .short  0x0000
   c:   12345678    .word   0x12345678

Это было немного опасно, потому что он выбрал инструкцию thumb2, так что вы можете sh быть ultra generi c для cortex- мс (на данный момент это настоящие микросхемы armv8m)

.cpu cortex-m0
.thumb
ldr r0,=0x12345678
ldr r0,=1
ldr r0,=0x20002

00000000 <.text>:
   0:   4801        ldr r0, [pc, #4]    ; (8 <.text+0x8>)
   2:   4802        ldr r0, [pc, #8]    ; (c <.text+0xc>)
   4:   4802        ldr r0, [pc, #8]    ; (10 <.text+0x10>)
   6:   0000        .short  0x0000
   8:   12345678    .word   0x12345678
   c:   00000001    .word   0x00000001
  10:   00020002    .word   0x00020002

.short - это элемент выравнивания, позволяющий выравнивать слова по словам. это передовая версия binutils, вы иногда / часто видите, что там помещается nop, чтобы заполнить пространство. Итак, теперь, возможно, инструмент заполняется нулями.

Минимальное завершение будет соответствовать строкам

.cpu cortex-m0
.thumb
.globl myfun
.thumb_func
myfun:
    ldr r0,=0x12345678
myfun_inner:
    ldr r1,[r0]
    cmp r1,#0
    bne my_fun_inner
    bx lr

И если вы изучите вывод g cc, вы увидите что-то более близкое до максимального, с гораздо большим синтаксисом. Так что стремитесь к чему-то среднему в соответствии с вашими личными предпочтениями. Я часто не использую .cpu, если мне не нужно, так как раньше он по умолчанию был armv4t, что в значительной степени является «всеми вариантами большого пальца», но теперь явно не используется, поэтому мне придется изменить свои привычки. Здесь снова всегда проверяйте вывод asm-кода, особенно в этой руке / большой палец, несколько расширений thumb2, несколько наборов инструкций с одним и тем же инструментом.

...