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

AArch64 ADRP±4GB寻址范围计算及重定向机制问询

ADRP寻址范围计算与重定向逻辑解答

1. ADRP ±4GB寻址范围的计算逻辑

AArch64架构中ADR和ADRP的寻址逻辑差异核心在页对齐偏移的设计:

  • ADR指令使用21位带符号立即数,直接和PC值相加,偏移范围是-2^20 ~ +2^20-4,也就是你说的±1MB近似范围。
  • ADRP指令同样使用21位带符号立即数,但计算时会先将当前PC值的低12位清零(按4KB页对齐),再将立即数左移12位后相加,计算逻辑为:
    目标页基址 = (当前PC值 & ~0xFFF) + (符号扩展(21位立即数) << 12)
    
    21位带符号立即数左移12位后,可表示的偏移范围为-2^32 ~ +2^32 - 4096,刚好对应±4GB的近似寻址范围。

2. 示例代码的重定向打补丁过程

你贴出的反汇编是未链接的可重定位目标文件(.o文件),其中adrp x0, 0 <main>的立即数是临时占位值,完整重定向流程如下:

  1. 编译阶段,编译器会生成两个重定位条目:
    • 类型为R_AARCH64_ADR_PREL_PG_HI21的条目,绑定全局变量g和adrp指令的立即数字段
    • 类型为R_AARCH64_LDST32_ABS_LO12_NC的条目,绑定全局变量g和后续ldr指令的偏移字段
  2. 链接阶段,链接器会先分配各段的运行时虚拟地址,得到main函数的最终地址addr_main,以及全局变量g的最终地址addr_g
  3. 补丁adrp指令:将addr_main和addr_g都按4KB页对齐,计算两者的页差后右移12位,得到21位带符号立即数,写入adrp指令的对应编码位,此时x0寄存器的值就是g所在页的基址
  4. 补丁ldr指令:取addr_g的低12位(也就是g在所在页内的偏移),写入ldr指令的偏移字段,此时ldr w0, [x0]实际访问的地址就是g的真实地址,可正确读取变量值。

3. 示例中地址偏移是否大于1MB的判定

当前可重定位目标文件阶段无法判断偏移大小:

  • 你看到的adrp x0, 0 <main>是未补丁的占位值,和实际偏移无关
  • 如果是静态链接的小内存模型程序,通常代码段和数据段距离远小于1MB,此时用ADR指令也可完成寻址,编译器选择ADRP是为了兼容大内存模型和位置无关代码的需求
  • 如果是动态链接的PIC程序、或是大内存模型的程序,代码段和数据段的距离可能超过1MB,此时ADR的±1MB范围不足,必须使用ADRP。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 17:39:03