目录
通用寄存器
其他寄存器
系统寄存器
通用寄存器
大多数A64指令在寄存器上操作。该架构提供了31个通用寄存器。 每个寄存器可以作为64位的X寄存器(X0..X30)使用,或者作为32位的W寄存器(W0..W30)使用。这两种是查看同一个寄存器的两种不同方式。
例如,这个寄存器图示显示了W0是X0的低32位,W1是X1的低32位:
图6-1:寄存器图示
对于数据处理指令,选择X或W决定了操作的大小。使用X寄存器将得到64位的计算结果,使用W寄存器将得到32位的计算结果。
这个示例执行了一个32位整数加法:
ADD W0, W1, W2
这个示例执行了一个64位整数加法:
ADD X0, X1, X2
当写入W寄存器时,如上例所示,64位寄存器的高32位将被清零。
有一组单独的32个寄存器用于浮点和向量操作。这些寄存器是128位的,但像通用寄存器一样,可以通过几种方式访问。Bx是8位,Hx是16位,以此类推,到Qx是128位。
图6-2:寄存器图示
你使用的寄存器名称决定了计算的大小。这个示例执行了一个32位浮点加法:
FADD S0, S1, S2
这个示例执行了一个64位浮点加法:
FADD D0, D1, D2
这些寄存器也可以被称为V寄存器。当使用V形式时,寄存器被视为一个向量。这意味着它被看作包含多个独立值,而不是单个值。这个示例执行了向量浮点加法:
FADD V0.2D, V1.2D, V2.2D
这个示例执行了向量整数加法:
ADD V0.2D, V1.2D, V2.2D
其他寄存器
以下是一些A64中你应该了解的其他寄存器:
- 零寄存器,XZR和WZR,总是读取为0并忽略写入。
- 你可以使用堆栈指针(SP)作为加载和存储的基础地址。你还可以使用堆栈指针与一组有限的数据处理指令,但它不是常规的通用寄存器。Armv8-A有多个堆栈指针,每个都与特定的异常级别相关联。当SP在指令中使用时,它指的是当前的堆栈指针。异常模型指南解释了如何选择堆栈指针。
- X30用作链接寄存器,可以称为LR。用于从异常返回的单独寄存器,ELR_ELx,在异常模型指南中有更详细的讨论。
- 程序计数器(PC)不是A64中的通用寄存器,它不能与数据处理指令一起使用。PC可以通过以下方式读取: ADR Xd, . ADR指令返回一个标签的地址,根据当前位置计算。点(.)意味着“这里”,所以显示的指令是返回它自己的地址。这等同于读取PC。一些分支指令和一些加载/存储操作,隐式地使用PC的值。
在A32和T32指令集中,PC和SP是通用寄存器。 在A64指令集中,情况并非如此。
系统寄存器
除了通用寄存器外,架构还定义了系统寄存器。系统寄存器用于配置处理器以及控制诸如内存管理单元(MMU)和异常处理等系统。
系统寄存器不能直接由数据处理或加载/存储指令使用。相反,系统寄存器的内容需要先读入一个X寄存器,进行操作,然后再写回系统寄存器。有两条专门的指令用于访问系统寄存器:
MRS Xd, <系统寄存器>
将系统寄存器读入Xd。
MSR <系统寄存器>, Xn
将Xn写入系统寄存器。
系统寄存器通过名称指定,例如SCTLR_EL1:
MRS X0, SCTLR_EL1
将SCTLR_EL1读入X0。
系统寄存器名称以_ELx结尾。_ELx指定访问寄存器所需的最低权限。例如: SCTLR_EL1 需要EL1或更高权限。 SCTLR_EL2 需要EL2或更高权限。 SCTLR_EL3 需要EL3权限。 尝试使用不足的权限访问寄存器将导致异常。
有时你会看到_EL12或_EL01。这些在虚拟化中使用。 有关更多信息,请参阅虚拟化指南。