ADRP指令
- 作用
- 将当前指令所在页的基地址加/减去字节差,并写入目标寄存器
- 字节差:与目标地址页基地址的间隔字节数,其为PAGE_SIZE的整数倍
- 此时的字节差就是指令所操作的立即数
- 该指令通常配合add指令来向目标寄存器写入完整的地址
- 最后通过br、blr实现长跳转
- 将当前指令所在页的基地址加/减去字节差,并写入目标寄存器
- 字节码对应关系
- Adrp指令字节码案例
0x90 0xFF 0xFF 0xE1
- 对应二进制
1001 0000 1111 1111 1111 1111 1110 0001
- 寄存器位 4-0
0 0001
-> 表示x1寄存器- 如果是
0 0000
-> 则表示x0寄存器 - 以此类推
0 0010
-> x20 0011
-> x3n nnnn
-> x...
- 立即数位(高19位) 23-5
1111 1111 1111 1111 111
- adr指令位 28-24
10000
- 至于为什么是adr指令位而不是adrp指令位,是因为我发现两者是相同的
- adr与adrp的差异在于第31位是否为1
- 立即数位(低2位) 30-29
00
- 64位操作位 31
1
- 当该位为1时表示adrp指令,当为0时表示adr指令
- Adrp指令字节码案例
- 对照表
1 00 10000 1111 1111 1111 1111 111 00001
|31| 30-29 | 28-24 | 23-5 | 4-0 |
|sf| immlo | | immhi | rd |
ADRP指令操作数的推导过程
- 在armv8指令手册中是这么写的
- SignExtend(immhi:immlo:Zeros(12), 64);
- 字面理解就是
- 有符号扩展(操作数高位:操作数低位:12个0,总长64位)
- 根据上述案例配合表达式进行计算
- 拼接结果
- =
1111 1111 1111 1111 111 00 0000 0000 0000
- = 0x1 FFFF C000
- =
- 符号扩展步骤及结果
- = 0x1 FFFF C000 << 31 >>31
- = 0xFFFF FFFF FFFF C000
- = -16384
- 也就是说,要在当前指令所在页基地址基础上减去16384字节
- -16384/PAGE_SIZE = -4, 也就是4页的大小
- 拼接结果