A64指令集¶
ARMv8 增加了新的 64 位指令集—— A64,它可以处理 64 位宽的寄存器和数据并且使用 64 位的指针来访问内存,但是其指令集的指令宽度依然是 32 位。ARMv8 兼容 A32 指令集,但 A64 指令集和 A32 指令集是不兼容的。
ARMv8 支持两种执行状态—— AArch64 和 AArch32。AArch64 状态用于执行 64 位指令,而 AArch32 状态用于执行 32 位指令。
加载与存储指令¶
LDR和STR指令¶
ldr x1,=0xE0000000 ;x1=0xE0000000
ldr x1,0xE0000000 ;将内存中地址为0xE0000000的内容载入到x1
ldr x1,[x0] ;将x0中的数所指定的地址的内容传输到x1
入栈与出栈¶
函数传递的参数如果少于8个,则使用 X0-X7 寄存器传递,如果多于8个,则使用栈传递。SP 指针指向栈顶,从栈底到栈顶的这段空间,称为栈帧。
A32 指令集提供了PUSH
与POP
指令来实现入栈与出栈,但是 A64 指令集已经移除,而转而使用加载与存储指令。
MOV指令¶
MOV
指令只能用于数据在寄存器之间的搬移,以及往寄存器里写立即数。
算术与移位指令¶
条件操作码¶
PSTATE 中有四个条件标志位,分别是N、Z、C、V,代表上一次运算的结果。
条件标志位 | 含义 |
---|---|
N | 负数 |
Z | 零 |
C | 进位 |
V | 溢出 |
ADD与SUB指令¶
有三种用法:
- 使用立即数
- 使用寄存器
- 使用移位操作
ADDS
和SUBS
:表示指令结果会影响 PSTATE 寄存器的标志位
ADC
和SBC
:带进位,计算时需要考虑 PSTATE 寄存器的C标志位
移位指令¶
- LSL:逻辑左移
- LSR:逻辑右移
- ASR:算术右移
- ROR:循环右移
逻辑移位和算术移位的区别在于是否考虑符号位。
位操作指令¶
AND
:按位与ORR
:按位或EOR
:按位异或BIC
:位清除
比较与跳转指令¶
CMP指令¶
比较两个数的大小,有三种用法:
- 使用立即数
- 使用寄存器
- 使用移位操作
跳转与返回指令¶
跳转指令:
B
:无条件跳转B.cond
:条件跳转BL
:带返回地址的跳转BR
:跳转到寄存器指定的地址BLR
:带返回地址的BR
返回指令:
RET
:通常用于子函数的返回,返回地址保存在 LRERET
:从当前的异常模式返回,它会把 SPSR 的内容恢复到 PSTATE 寄存器中。该指令可以实现处理器模式的切换。
比较并跳转指令:
CBZ
:如果寄存器为0,则跳转CBNZ
:如果寄存器不为0,则跳转
其他重要指令¶
PC相对地址加载指令¶
ADR
指令用于加载一个在当前 PC 值 ±1MB 范围内的 label 地址到 Xd 寄存器中。
LDR和ADR指令的区别
LDR 伪指令加载的是绝对地址,即程序编译时的链接地址。ADR 加载的是当前 PC 的相对地址,可以理解为当前运行时 label 的物理地址。由于运行地址和链接地址可能不同,因此需要在不同场景下选择使用。
内存独占指令¶
ARMv8 体系提供独占的内存访问(exclusive memory access)指令。LDXR
指令尝试在内存总线中申请一个独占访问的锁,然后访问一个内存地址。STXR
指令会往刚才LDXR
指令已经申请独占访问的内存地址中写入新内容。这两个指令配合使用来完成一些同步操作。
异常处理指令¶
SVC
:系统调用指令,陷入 EL1HVC
:虚拟化系统调用指令,陷入 EL2SMC
:安全监控系统调用指令,陷入 EL3
系统寄存器访问指令¶
在 ARMv7 体系结构中,通过 CP15 协处理器可以访问系统寄存器。在 ARMv8 体系结构中,访问的方式有了大幅的改进和优化。MRS
和MSR
两条指令可以直接访问系统寄存器。
MRS
:读取系统寄存器的值到通用寄存器MSR
:将通用寄存器的值写入系统寄存器
除了访问系统寄存器之外,MRS
和MSR
指令还可以访问与 PSTATE 寄存器相关的字段,比如 CurrentEL 等。
内存屏障指令¶
DMB
:数据存储屏障DSB
:数据同步屏障ISB
:指令同步屏障
除此之外,ARMv8 还提供了一组新的加载和存储指令,显示包含了内存屏障功能:
LDAR
:加载-获取指令,LDAR
指令后面的读写内存指令必须在LDAR
指令之后才能执行STLR
:存储-释放指令,所有的加载和存储指令必须在STLR
指令之前完成