ARM 汇编指令:LDR

ARM 汇编指令:LDR

LDR 在 ARM 汇编中是 Load Register 的缩写,即 "加载数据到寄存器"

你可以把它理解为 C 语言等高级语言中的 "读内存""指针解引用" 操作。

核心功能

从一个内存地址中读取数据(一个或多个字节),并将其放入指定的寄存器中。


基本语法

LDR{条件}{大小} 目标寄存器, 源内存地址

  • 目标寄存器:数据将被加载到哪个寄存器(如 R0, R1)。
  • 源内存地址 :指定从哪里读取数据。它可以是:
    • 一个固定的地址(使用标签,如 LDR R0, =my_var
    • 一个寄存器中存储的地址(指针)
    • 一个带有偏移量的地址

常见用法和示例

1. 从固定地址/变量加载

这是最常见的形式,用于访问全局变量或常量。

assembly 复制代码
.data
my_var:     .word   0x12345678   @ 在内存中定义一个32位字,值为0x12345678

.text
    LDR   R0, =my_var     @ 将 my_var 的地址(一个指针)加载到 R0
    LDR   R1, [R0]        @ 这才是真正的 LDR:读取 R0 指向的内存地址的内容(0x12345678)到 R1

更常见的便捷写法(由汇编器自动处理):

assembly 复制代码
    LDR   R1, =my_var     @ 直接加载 my_var 的地址到 R1(常用于加载地址)
    LDR   R2, my_var      @ 直接读取 my_var 的值到 R2(一些汇编器支持)
2. 从寄存器指定的地址加载(基础寄存器寻址)

将寄存器作为一个指针。

assembly 复制代码
    MOV   R3, #0x20000000 @ 假设 0x20000000 是一个有效的内存地址(如 GPIO 寄存器)
    LDR   R4, [R3]        @ 读取地址 0x20000000 处的32位数据到 R4
3. 带偏移量的加载(前变址)

先计算偏移地址再加载,并更新基址寄存器

assembly 复制代码
    LDR   R5, [R6, #4]!   @ 从地址 [R6+4] 处读取数据到 R5,然后 R6 = R6 + 4
                           @ "!" 表示更新基址寄存器 R6
4. 带偏移量的加载(后变址)

先加载,再更新基址寄存器。

assembly 复制代码
    LDR   R5, [R6], #4    @ 从地址 [R6] 处读取数据到 R5,然后 R6 = R6 + 4
5. 带移位/索引寄存器的加载

偏移量由另一个寄存器给出,并可移位。

assembly 复制代码
    LDR   R7, [R8, R9, LSL #2]  @ 地址 = R8 + (R9 << 2)。常用于数组访问(R9 是索引,每个元素4字节)。

加载不同类型的数据(大小后缀)

默认情况下,LDR 加载一个 32位字(Word, 4字节)。但可以通过后缀加载不同大小的数据:

指令 含义 加载大小 说明
LDR Load Word 32 位 最常用,加载一个字
LDRH Load Halfword 16 位 加载半个字,零扩展到32位
LDRSH Load Signed Halfword 16 位 加载半个字,符号扩展到32位
LDRB Load Byte 8 位 加载一个字节,零扩展到32位
LDRSB Load Signed Byte 8 位 加载一个字节,符号扩展到32位

示例:

assembly 复制代码
    LDRB  R0, [R1]   @ 从地址 [R1] 读取一个字节(如 0xFF),存入 R0 后变为 0x000000FF(零扩展)
    LDRSB R0, [R1]   @ 从地址 [R1] 读取一个字节(如 0xFF),存入 R0 后变为 0xFFFFFFFF(符号扩展,因为0xFF是负数)

伪指令:LDR =

这是初学者最容易混淆的地方。LDR Rd, =... 经常被用作一个 伪指令

  • LDR Rd, =label : 这通常意味着 "将 label 的地址加载到 Rd" 。汇编器会自动处理,可能会生成一条 MOV 指令或从附近的"文字池"中加载一个常量。

    assembly 复制代码
    LDR R0, =0x12345678   @ 将一个32位立即数常量 0x12345678 加载到 R0
  • LDR Rd, [Rn] :这才是 "真正的" LDR 指令 ,从内存地址 [Rn] 加载数据。


与 STR 指令的关系

LDR 的"逆操作"是 STR。它们是配对使用的内存访问指令:

  • LDR R0, [R1] : 读内存。R0 = *R1;
  • STR R0, [R1] : 写内存。*R1 = R0;

总结表格

特性 LDR 指令
名称 Load Register(加载到寄存器)
核心作用 从内存读取数据到寄存器
类比C语言 register = *address; (解引用操作)
常见用途 1. 访问变量 2. 读取外设寄存器 3. 访问数组/结构体
关键变体 LDRB(字节), LDRH(半字), LDRSB(有符号字节)等
配对指令 STR(Store Register,将寄存器数据存入内存)

简单记忆:LDR 就是把数据从内存"搬"到CPU的寄存器里。 它是程序与内存交互、获取数据的最基本方式。

相关推荐
somi71 天前
ARM-驱动-02-Linux 内核开发环境搭建与编译
linux·运维·arm开发
XINVRY-FPGA1 天前
XC7VX690T-2FFG1157I Xilinx AMD Virtex-7 FPGA
arm开发·人工智能·嵌入式硬件·深度学习·fpga开发·硬件工程·fpga
cpp_learners1 天前
Linux ARM架构 使用 linuxdeployqt 打包QT程序
linux·arm开发·qt
森G1 天前
3.1、移植Qt程序到ARM平台----移植Qt程序到ARM平台(扩展)
arm开发·c++·qt
炭烤毛蛋1 天前
rk3588 适配音频解码芯片 es8388
arm开发·音视频·rk3588·es8388
独小乐1 天前
007.GNU C内联汇编杂谈|千篇笔记实现嵌入式全栈/裸机篇
linux·c语言·汇编·单片机·嵌入式硬件·arm·gnu
路溪非溪1 天前
Linux中Netlink简介和使用总结
linux·网络·arm开发·驱动开发
Bohemian—Rhapsody1 天前
麒麟v10-arm架构部署rabbitmq
arm开发·架构·rabbitmq
古译汉书2 天前
【IoT死磕系列】Day 9:架构一台“自动驾驶物流车”,看8种协议如何协同作战
网络·arm开发·单片机·物联网·tcp/ip·架构·自动驾驶
路溪非溪2 天前
Linux中gpio子系统的现代接口
linux·arm开发·驱动开发