Cortex M 的 ARM 汇编帮助

ARM asembly help for CortexM

我需要制作一个 ASM 函数。 我完成了大部分工作,但我没能让它按预期工作。 我想做一个运行到无穷大的循环,直到某个寄存器(SysTick-> CTRL Flag)中的某个位被设置。 我用的是尖沙咀 r5,#Val。 val 是 1<<16 写成十六进制 然后我做一个 BNE 来循环标签。 它只是退出循环。 r5 来自 力量 r5,[r0,#0] 其中 r0 具有 SysTick CTRL 地址。 有没有人有一些完整的 ASM 函数示例。 我使用了 .global funcname 我使用了 .segment 文本 我用过.thumb_func 还有其他需要担心的事情吗?

首先,汇编语言是特定于汇编器的。

对于 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: 等标签,1b 或 1f 将引用最近的 1: 向前或向后。并生成相同的代码:

   6:   d1fe        bne.n   0 <my_fun_inner>

这是一个相对跳转,所以即使我已经反汇编了对象,当你link 反汇编 linked 二进制文件时,那将是相同的机器代码:

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 指令,因此您可能希望对 cortex-ms 超级通用(到目前为止,实际的 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 的尖端版本,您 sometimes/often 看到一个 nop 放置在那里以填充 space。所以现在也许该工具正在填充零。

最基本的完成方式是

.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

如果您检查 gcc 的输出,您会看到更接近最大的东西,语法更多。因此,根据您的个人喜好,瞄准介于两者之间的某个地方。我通常不使用 .cpu 除非我需要,因为它过去默认为 armv4t,这几乎是“所有拇指变体”但现在显然没有,所以我将不得不改变我的习惯.在这里,请再次检查您的 asm 代码输出,尤其是在这个 arm arm/thumb 多个 thumb2 扩展,多个指令集使用相同的工具。