armv7-m裸机ldr / str符号存储器

问题描述 投票:2回答:1

所以我知道关于arm的ldr / str问题不胜枚举。也许这是另一种转折(不太可能),或者我只是缺少了一些东西(更可能。)

所以这是裸机,我想在内存中加载/存储一些变量。而且因为我坚持要给它起个名字。我可以天真地写:

.section .bss
var: .word 0

.section .text
str r0, var 

((具有一个自定义链接脚本,该脚本将.bss放在ram中,并将.text放在flash中)

原因这是行不通的,因为指令是32位的,并且只占一些较小的立即数。我正在谈论的指令实时存储在0x8000000 + x的Flash中,变量将存储在0x20000000 + y的内存中。

手动,我知道很多解决方法:

  • 将变量地址存储为常数(varaddr: .word 0x2001234; ldr r1, [pc,#varaddr]; str r0, [r1]
  • 将ram-base加载到寄存器中并对其进行相对寻址(ldr r1, #0x20000000; str r0, [r1,#varoffset]
  • 通过算术(mov r1, #0x2000000; add r1, #offset / orr / movw / movt something)构造地址
  • 当然还有更多

所有这些变体都可以使用,但是这些变体中的任何一个都不能让我使用我真正想使用的标签。

所以我在这里想念什么。我对链接描述文件和标签的看法是否虚假?我有没有看到的一些汇编器功能?完全不同吗?

assembly arm armv7
1个回答
0
投票

可以在静态存储中为变量使用符号名的一种方法是为变量定义结构。这使您可以将结构的基地址加载到寄存器中,然后使用相对于基地址的符号名称访问结构成员。例如,您可以这样做:

        .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

这几乎是您在静态存储中最接近变量的符号名称的位置。如果变量在堆栈上,则可以使用类似的方法,将帧指针(或堆栈指针)用作基地址。 .struct的操作数是该结构的基地址,您可以为其选择任意值。

关于movwmovt。与不需要ldr ..., =...的某些微体系结构相比,它们在性能上有微小的优势,因为它们不需要将数据提取到文本部分。据我所知,这对armv7-m目标没有影响;同样,与movwmovt操作数相比,ldr=消耗两个额外的字节。因此,我建议您坚持使用ldr=操作数。 movwmovt的用法如下:

        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

这两个必须按此特定顺序发出,因为movw会清除高16位。前缀:lower16::upper16:选择适当的重定位类型,仅参考符号地址的低16位和高16位。您可以创建一个宏以使其更易于键入:

        .macro addr reg, sym
        movw \reg, :lower16:\sym
        movt \reg, :upper16:\sym
        .endm

这可以让您写

        addr r0, foo

以生成前述的movwmovt对。

© www.soinside.com 2019 - 2024. All rights reserved.