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
相关产品推荐
相关产品推荐

