assembly - 为什么在 ARM 汇编中使用 LDR 而不是 MOV(反之亦然)?

标签 assembly arm immediate-operand

我正在浏览本教程:http://www.cl.cam.ac.uk/freshers/raspberrypi/tutorials/os/ok01.html

第一条组装线是:

ldr r0,=0x20200000

第二个是:

mov r1,#1

我认为ldr用于将值从内存加载到寄存器中。但似乎 = 意味着 0x20200000 是一个值而不是内存地址。这两行似乎都在加载绝对值。

最佳答案

这是一个技巧/捷径。举例来说

ldr r0,=main

会发生的情况是汇编器会在指令附近但在指令路径之外分配一个数据字

ldr r0,main_addr
...
b somewhere
main_addr: .data main

现在将该技巧扩展到常量/立即数,特别是那些无法适合立即移动指令的内容:

top:
add r1,r2,r3
ldr r0,=0x12345678
eor r1,r2,r3
eor r1,r2,r3
b top

组装然后拆卸

00000000 <top>:
   0:   e0821003    add r1, r2, r3
   4:   e59f0008    ldr r0, [pc, #8]    ; 14 <top+0x14>
   8:   e0221003    eor r1, r2, r3
   c:   e0221003    eor r1, r2, r3
  10:   eafffffa    b   0 <top>
  14:   12345678    eorsne  r5, r4, #125829120  ; 0x7800000

你会看到汇编器已经为你添加了数据字,并将 ldr 更改为你的 pc 相对值。

现在,如果您使用适合 mov 指令的立即数,那么可能取决于汇编器,当然还有我正在使用的 gnu,它会将其变成我的 mov

top:
add r1,r2,r3
ldr r0,=0x12345678
ldr r5,=1
mov r6,#1
eor r1,r2,r3
eor r1,r2,r3
b top


00000000 <top>:
   0:   e0821003    add r1, r2, r3
   4:   e59f0010    ldr r0, [pc, #16]   ; 1c <top+0x1c>
   8:   e3a05001    mov r5, #1
   c:   e3a06001    mov r6, #1
  10:   e0221003    eor r1, r2, r3
  14:   e0221003    eor r1, r2, r3
  18:   eafffff8    b   0 <top>
  1c:   12345678    eorsne  r5, r4, #125829120  ; 0x7800000

所以它基本上是一个打字快捷方式,理解你赋予汇编器找到一个地方来保存常量的能力,它通常做得很好,有时会提示,不确定我是否见过它失败安全地进行。有时您需要在代码中使用 .ltorg 或 .pool 来鼓励汇编器找到位置。

关于assembly - 为什么在 ARM 汇编中使用 LDR 而不是 MOV(反之亦然)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14046686/

相关文章:

assembly - 强制 arm64 gcc 使用指令构造 double float ,无 .rodata 部分

assembly - 了解 ATT 程序集(即时)

linux - 使用 x87 float 调用 printf

c - Cortex-M7 的 DS-5 配置

assembly - 如何在裸机 16 位 x86 程序集中休眠?

Android 电视盒在 10 秒内关闭我的应用程序

c++ - fatal error : arm_acle. h:没有那个文件或目录

assembly - RISC-V 立即编码符号到底是如何工作的?

c - 在不知道参数的情况下将函数调用传递给另一个

optimization - 为什么INC和ADD 1有不同的表现?