如何在Apple Silicon(ARM64)平台通过标签加载数据?
苹果平台下用ADRP加载.data段数据的方案
ADRP指令的核心逻辑
ADRP是ARM64架构适配ASLR(地址空间随机化)的专用指令,核心作用是计算目标符号所在4KB内存页的基地址:
- 先将当前PC的低12位清零,得到当前代码所在页的基地址
- 加上指令携带的21位有符号偏移(左移12位,对应4KB页级偏移),最终得到目标符号所在页的基地址
- 汇编器的
@PAGE修饰符提取目标符号地址的页基地址部分,@PAGEOFF提取页内偏移部分
加载mynumber的具体代码实现
针对你提供的.data段数据,用ADRP+ADD组合获取地址再加载数据的代码如下:
.global _start .text _start: // 计算mynumber的完整虚拟地址 ADRP X0, mynumber@PAGE // 将mynumber所在页的基地址存入X0 ADD X0, X0, mynumber@PAGEOFF // 加上页内偏移,得到mynumber的完整地址 // 从内存加载mynumber的值到寄存器 LDR X1, [X0] // 把mynumber的8字节数据加载到X1寄存器 // 程序退出流程 mov X0, #0 // 设置返回码为0 mov X16, #1 // 指定终止程序的系统调用号 svc #0x80 // 调用内核终止程序 .data .align 4 arr1: .FILL 10, 4, 0 mynumber: .quad 0x123456789ABCDEF0 myoctaword: .octa 0x12345678876543211234567887654321
扩展:加载更大的myoctaword数据
如果要加载16字节的myoctaword,可以用LDP指令一次性加载到两个寄存器:
ADRP X0, myoctaword@PAGE ADD X0, X0, myoctaword@PAGEOFF LDP X1, X2, [X0] // 前8字节存入X1,后8字节存入X2
为什么不能用直接LDR伪指令?
苹果平台强制开启ASLR,程序的加载基址是随机的,直接用LDR X0, =mynumber这类伪指令会生成固定绝对地址,运行时会因地址不匹配失效。而ADRP+ADD是基于当前PC的相对地址计算,完全不受ASLR影响,能正确定位到数据的实际内存位置。
内容的提问来源于stack exchange,提问作者user303680
相关产品推荐
相关产品推荐

