gpt4 book ai didi

assembly - armv7-m 裸机 ldr/str 符号内存

转载 作者:行者123 更新时间:2023-12-04 10:26:11 32 4
gpt4 key购买 nike

所以我知道 ldr/str on arm 的问题数不胜数。也许这是另一个转折(不太可能),或者我只是错过了一些东西(更有可能。)

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

.section .bss
var: .word 0

.section .text
str r0, var

(有一个自定义链接器脚本,将 .bss 放入 ram 并将 .text 放入 flash)

这当然行不通,因为指令是 32 位的,并且只有一些较小的立即数。我正在谈论的闪存中的指令是 0x8000000+x,而变量将存储在内存中,该内存位于 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 )
  • 当然更多

  • 这些变体中的每一个都有效,但这些变体都不允许我使用我真正想要使用的标签。

    那么我在这里错过了什么。我对链接器脚本和标签的想法是假的吗?是否有一些我没有看到的汇编功能?完全不同的东西?

    最佳答案

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

            .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和一个 =操作数。 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

    这两个必须按此特定顺序发布为 movw清除高 16 位。前缀 :lower16::upper16:选择适当的重定位类型,仅引用符号地址的低 16 位和高 16 位。您可以制作一个宏以使其更易于键入:
            .macro addr reg, sym
    movw \reg, :lower16:\sym
    movt \reg, :upper16:\sym
    .endm

    这允许你写
            addr r0, foo

    生成上述 movwmovt一对。

    关于assembly - armv7-m 裸机 ldr/str 符号内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60626117/

    32 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com