22

我正在学习剑桥大学的Baking Pi课程,其中在 ARMv6 指令集中构建了一个简单的操作系统,针对 Raspberry Pi。

到目前为止,我们一直在使用两种方式通过ldr指令将数据加载到寄存器中,现在我意识到我正在一起使用它们,我并不完全理解它们的作用。

所以我使用了类似的东西ldr r0,=0x20200000,我实际上将其理解为“将存储在内存位置 0x20200000 的数据读入寄存器 r0。

然后我使用了类似的东西:

ldr r0,[r1,#4]

我将其理解为“将存储在 r1 指向的内存地址处的数据以 4 个字节的偏移量读取到寄存器 r0 中”。

然后我遇到这个:

ldr r0,=pattern
ldr r0,[r0]

pattern这是.int.data部分中的一个(表示 LED 的一系列开/关状态的位图)。读到这里,我意识到我之前的理解=foo一定是错误的,否则上面的两个指令都会做同样的事情。

=x语法基本上更像C中的指针,而语法[x]就好像x实际读取了所指向的内存?

假设ptr在下面的 C 中是 an int*,我对等效程序集(概念上,而不是字面意思)的评论是否有意义?

r0 = ptr;     /* equivalent to: ldr r0,=ptr     */
r0 = *ptr;    /* equivalent to: ldr r0,[ptr]    */
r0 = *(ptr+4) /* equivalent to: ldr r0,[ptr,#4] */
4

2 回答 2

24
ldr r0,=something
...
something:

表示将标签的地址加载到寄存器 r0 中。然后,汇编器在 ldr 指令可及的某处添加一个单词,并用

ldr r0,[pc,#offset]

操作说明

所以这个快捷方式

ldr r0,=0x12345678

表示将 0x12345678 加载到 r0 中。

作为大多数固定长度的指令,您不能在一条指令中将完整的 32 位立即数加载到寄存器中,可能需要多条指令才能完全加载 32 位数的寄存器。很大程度上取决于数量。例如

ldr r0,=0x00010000

将被 gnu 汇编器替换为一条指令 mov r0,#0x00010000 如果它是 ARM 指令,对于 thumb 指令虽然它可能仍然必须是 ldr r0,[pc,#offset]

这些 ldr rd,=things 是快捷方式,伪指令,不是真实的。

ldr rd,[rm,#offset]
ldr rd,[rm,rn]

是真正的指令,意思是从地址 rm+offset 或 rm+rn 的内存中读取,并将读取的值放入寄存器 rd

=something 更像是 C 中的 &something。

unsigned int something;
unsigned int r0;
unsigned int r1;

r0 = &something;
r1 = *(unsigned int *)r0;

并在组装

something:
    .word 0

ldr r0,=something
ldr r1,[r0]
于 2013-06-20T13:38:35.703 回答
0

值得一提的是,对于那些出于某种原因想要避免伪指令/文字池的人来说,存在以下替代方法:

  • adr r0, label(v7 / v8):单条指令,将标签的完整地址存储到r0. 指通过相关 PC 寻址的标签,另请参阅:ARM 汇编中 ADRP 和 ADRL 指令的语义是什么?| 带有断言的示例

    但是,在 ARMv7 中,无法使用 访问不同部分中的标签adr,例如.datafrom .text,显然是因为没有重定位来处理它。ldr =可以做到这一点。如果您尝试,GAS 会失败并显示:

     Error: symbol .data is in a different section
    

    然而,在 ARMv8 中可以进行横截面访问,并生成类型为 的重定位R_AARCH64_ADR_PRE例子

  • movwmovt(v7) + GNU GAS #:lower

    movw r0, #:lower16:myvar
    movt r0, #:upper16:myvar
    

    带有断言的示例

    movk+ 班次 (v8) + GNU GAS

    movz x0, #:abs_g2:label     // bits 32-47, overflow check
    movk x0, #:abs_g1_nc:label  // bits 16-31, no overflow check
    movk x0, #:abs_g0_nc:label  // bits  0-15, no overflow check
    

    带有断言的示例

于 2019-01-04T17:17:47.217 回答