You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ARM架构中ADR指令的用途、适用场景及与PIC的关联咨询

ADR vs LDR:适用场景、用法示例及PIC关联

核心特性回顾

你已经抓准了关键:ADR是PC相对寻址伪指令,它会生成基于当前PC的加减指令来计算标签地址;LDR加载标签地址时默认是绝对寻址(LDR Rn, =label本质是从常量池读取预存的绝对地址)。

何时分别使用

  • 选ADR的情况:
    • 你需要写位置无关代码(PIC):比如裸机中需要从Flash搬到RAM运行的启动代码、或者要在不同地址执行的固件。
    • 标签和当前指令的偏移在ADR的支持范围内(ARM架构中,ADR通常支持±4KB或±1MB的偏移,具体看指令集和编码方式)。
  • 选LDR的情况:
    • 标签地址超出ADR的偏移范围,必须用绝对寻址才能访问。
    • 代码固定在某个地址运行,不需要考虑位置无关性(比如映射地址固定的裸机程序)。

ADR用法示例(ARM裸机汇编)

下面是一个位置无关的跳转示例,不管代码被加载到哪个地址,都能正确跳转到目标标签:

_start:
    ; 用ADR计算loop_label的相对地址,存入R0
    ADR R0, loop_label
    ; 跳转到R0指向的地址
    BLX R0

loop_label:
    MOV R1, #0x1
    ; 无限循环
    B loop_label

对比用LDR的非位置无关版本:

_start:
    ; 加载loop_label的绝对地址到R0(比如编译时固定为0x80000004)
    LDR R0, =loop_label
    BLX R0

loop_label:
    MOV R1, #0x1
    B loop_label

如果把这段LDR代码从0x80000000移到0x90000000运行,R0里的地址还是0x80000004,跳转直接出错;而ADR版本会基于当前PC重新计算偏移,跳转完全正常。

和PIC的关系

没错,ADR是实现PIC的核心指令之一。PIC的核心要求是代码不依赖固定绝对地址,所有地址引用都基于当前执行位置(PC)。ADR通过PC相对寻址天然满足这个要求——只要指令间的相对偏移不变,不管代码被加载到哪个内存地址,ADR计算出的目标地址都能正确指向标签。

内容的提问来源于stack exchange,提问作者wangloo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 02:41:07