1、arm64体系结构基础知识
1.1 ARM v8 中的通用寄存器 零寄存器 系统寄存器 特殊寄存器 (XZR、WXR PC SP ) 功能 使用方法
1.2 PSTATE 寄存器中 NZCV DAIF EL 标志位含义
1.3 备份程序状态寄存器(Saved Program Status Register)
3、A64指令集 加载与存储指令 (第一位是寄存器,后面是内存或者立即数)
3.1 MOV STR LDR
`MOV X0, X1`会将X1的值复制到X0中,这里的目标寄存器是X0,源是X1
`MOV X0, #5`,目标寄存器同样是第一个操作数,立即数是第二个
`STR X0, [X1]`会将X0的值存储到X1寄存器所指向的内存地址。这里的目标是内存位置,源是寄存器X0
`MOV`是数据传输到寄存器,`STR`是传输到内存
`LDR X0, [X1]`是将内存中的数据加载到X0
3.2 前变基模式,后变基模式
LDR X0, [X1, #8] //内存地址为X1寄存器的值加上8的偏移量, 加载此内存地址的值到X0寄存器LDR X0, [X1, #8]! //前变基模式。 先更新X1寄存器的值为X1寄存器的值加8, 然后以新的值
//加载该内存地址的值到X0寄存器
LDR X0, [X1], #8 //后变基模式。 以X1寄存器的值为内存地址, 加载该内存地址的值到X0寄存
//新X1寄存器的值为X1寄存器的值加8
3.4 加载和存储指令 、前变基模式 后变基模式
LDR 目标寄存器, <存储器地址>
STR 源寄存器,<存储器地址>
前变基模式 : 先更新偏移量地址,后访问内存地址
后变基模式 : 先访问内存地址,后更新偏移量地址
3.4.1 多字节内存加载和储存指令
LDP <Xt1>, <Xt2>,[<Xn>|SP{,#<imm>}]
以 <Xn>|SP 为基地址,读取 <Xn>|SP{,#<imm>} 寄存器的值到 <Xt1> 寄存器中,读取X n /SP寄存器的值 + imm + 8地址的值到X t 2寄存器中
●X t 1: 目标寄存器1, 它对应指令编码中的R t 字段。 t 可以取0~30的整数。
●X t 2: 目标寄存器2, 它对应指令编码中的R t 2字段。 t 可以取0~30的整数。
●X n /SP: 用于基地址寄存器, 它对应指令编码中的R n 字段, 也可以使用SP寄存器。 n 可以取0~
30的整数。
●imm7: 偏移量, 该值必须是8的整数倍, 取值范围为-512~504。
STP <Xt1>, <Xt2>, [<Xn|SP>{, #<imm>}]
它以X n /SP寄存器的值为基地址, 然后把X t 1寄存器的内容存储到[X n /SP + imm]处, 把X t 2寄存
器的内容存储到[X n /SP + imm + 8]处。
3.4.4 独占内存访问指令
在A64指令集中, LDXR指令尝试在内存总线中申请一个独占访问的锁, 然后访问一个内存地址。 STXR指令会往刚才LDXR指令已经申请独占访问的内存地址中写入新内容。 LDXR和STXR指令通常组合使用来完成一些同步操作, 如Linux内核的自旋锁。
3.5 MOV指令
MOV指令常常用于寄存器之间的搬移和立即数搬移。
在寄存器之间搬移的 MOV 指令 : MOV <Xd|SP>, <Xn|SP>
用立即数搬移的 MOV 指令 : MOV <Xd>, #<imm>
3.6 加载和存储指令陷阱
3.6.1 怎么加载一个很大的立即数到通用寄存器
MOV 指令通常用于加载 16 位立即数,16位立即数左移16位 32位 或者48位后的立即数
在遇到大数据比如 0xffff0000ffffffff 是,可以使用 LDR,伪指令来实现
#define BIG_DATA 0xFFFF0000FFFFFFFF
ldr x0, =BIGDATA
3.6.2 ldr 和 mov 指令的区别
MOV 用于在寄存器之间移动数据,或者将立即数加载到寄存器,但是立即数的范围有限
mov r0, #42 @ 将立即数 42 加载到 r0 mov r1, r2 @ 将 r2 的值复制到 r1MOV 的限制是不能操作大立即数
ldr 用于在内存加载数据到寄存器,也可以用来加载大立即数(伪指令形式)
ldr{条件} 目标寄存器, [内存地址或标签] @ 真实指令(内存加载) ldr 目标寄存器, =立即数或地址 @ 伪指令(加载大立即数或地址) ldr r0, =0x12345678 @ 加载大立即数到 r0 ldr r1, =main @ 加载函数 main 的地址到 r1
4 A64指令集 算术和移位指令
PSTATE寄存器中有4个条件标志位, 即 N 、 Z 、 C、 V

4.1 ADD指令
ADD <Xd|SP>, <Xn|SP>, #<imm>{, <shift>}
add x0, x1, #1 //把x1寄存器的值加上立即数1, 结果写入x0寄存器中
add x0, x1, #1, LSL 12 //把立即数1算术左移12位, 然后再加上x1寄存器的值, 结果写入
add x0, x1, #4096
add x0, x1, #1, LSL 1
汇编器会报如下错误, 其中第一条语句中立即数超过了范围, 第二条语句中左移的位数只能是0或
者12。
4.1.2 使用寄存器的加法指令
add x0, x1, x2 //x0 = x1 + x2
add x0, x1, x2, LSL 2 //x0 = x1 + x2 << 2
4.2.2 ADDS指令
ADDS指令是ADD指令的变种, 唯一的区别是指令执行结果会影响PSTATE寄存器的 N 、 Z 、C、V 标志位, 例如当计算结果发生无符号数溢出时, C =1。
4.2 SUB 指令
4.3 CMP 指令
CMP指令用来比较两个数的大小。 在A64指令集的实现中, CMP指令内部调用SUBS指令来实现。
4.5 移位指令
● LSL: 逻辑左移指令, 最高位会被丢弃, 最低位补0, 如图4.10(a) 所示。
● LSR: 逻辑右移指令, 最高位补0, 最低位会被丢弃, 如图4.10(b) 所示
4.6 位操作指令
4.6.1 与操作指令
●AND: 按位与操作。
●ANDS: 带条件标志位的与操作, 影响 Z 标志位。
4.6.2 或操作指令
ORR <Xd|SP>, <Xn>, #<imm>
ORR <Xd>, <Xn>, <Xm>{, <shift> #<amount>}
4.6.3 异或指令
4.6.4 位清除指令
BIC <Xd>, <Xn>, <Xm>{, <shift> #<amount>}
BIC指令支持寄存器方式: 先对X m 寄存器的值做移位操作, 然后再与X n 寄存器的值进行位清除
操作。 BIC指令的参数说明如下。
●shift表示移位操作, 支持LSL、 LSR、 ASR以及ROR。
●amount表示移位数量, 取值范围为0~63。
5.比较指令与跳转指令
5.1 CMN 指令
CMN指令用来将一个数与另一个数的相反数进行比较
CMN <Xn|SP>, #<imm>{, <shift>}
CMN <Xn|SP>, <R><m>{, <extend> {#<amount>}}
上述两条CMN指令分别等同于如下的ADDS指令。
ADDS XZR, <Xn|SP>, #<imm> {, <shift>}
ADDS XZR, <Xn|SP>, <R><m> {, <extend> {#<amount>}}
5.2 返回指令 ret 和 ERET 的区别
RET指令: 通常用于子函数的返回, 其返回地址保存在LR里。
●ERET指令: 从当前的异常模式返回。 它会把SPSR的内容恢复到PSTATE寄存器中, 从ELR中获取跳转地址并返回到该地址。 ERET指令可以实现处理器模式的切换, 比如从EL1切换到EL0。
5.3 跳转指令

5189

被折叠的 条评论
为什么被折叠?



