ARMv8寄存器实在太多了,本节主要针对系统软件常用的寄存器作为重点介绍。
ARMv8架构(针对Core来说)至少有上千个寄存器,更别提Core外SOC级外设寄存器。这两类寄存器的区别是:前者(不管通用寄存器还是系统寄存器)不占用地址空间,而后者是和内存统一编制的,要占用地址空间。
下面我们主要针对ARM Core内寄存器进行介绍。ARM核心寄存器可以分为:
而系统寄存器,根据其功能又可以分为11种:
这么多寄存器很难记得住,我们只需要重点关注以下寄存器,其余寄存器用到时候再查手册。
寄存器 | 描述 |
---|---|
PSTATE | 程序状态寄存器 |
SP_ELx(x>0) | 在EL1/EL2/EL3 level中,如果spsel=0,则使用SP_ELx(x>0) |
SP_EL0 | 在所有level中,如果spsel=1, 则使用SP_EL0 |
SPSR | 备份的程序状态寄存器 |
ELR_ELx(x>0) | 异常链接寄存器,记录着异常时程序的返回地 |
ESR_ELx(x>0) | 同步异常, 异常特征寄存器 |
VBAR_ELx(x>0) | 向量表基地址寄存器 |
TTBRn_ELx(n=1,2、x>0) | 地址翻译基地址寄存器,存放页表地址。 |
MAIR_ELx(x>0) | 内存属性寄存器 |
PAR_EL1 | 物理地址寄存器, 当使用指令操作MMU进行VA到PA的转换时,物理地址由PAR_EL1输出 |
SCR_EL3 | 安全控制寄存器 |
HCR_EL2 | Hypvisor控制寄存器 |
SCTLR_ELx(x>0) | 系统控制寄存器 |
TCR_ELx(x>0) | 地址翻译控制寄存器 |
AArch64执行状态提供了31个在任何时间任何特权级下都可访问的64位的通用寄存器,分别是X0-X30。而AArch32状态支持16个32位的通用寄存器。
每个AArch64 64位通用寄存器(X0-X30)也具有32位(W0-W30)形式。
32位W寄存器取自相应的64位X寄存器的低32位。也就是说,W0映射到X0的低32位,W1映射到X1的低32位。
从W寄存器读取时,忽略相应X寄存器高32位,并保持其它不变。写入W寄存器时,将X寄存器的高32位设置为零。也就是说,将0xFFFFFFFF写入W0会将X0设置为0x00000000FFFFFFFF。
通用寄存器在ACPS中用法
除了用于数据运算和存储外,通用寄存器还在函数的调用过程中起到特殊作用,ARM64体系结构的函数调用标准和规范对此有约定,如下图所示。
说明:
ARMv7中使用当前程序状态寄存器(CPSR)表示处理器当前状态。AArch64没有直接与之等价的寄存器。
在AArch64中,传统CPSR的组件作为可以独立访问的字段提供。这些状态被统称为处理器状态(PSTATE)。
该程序和备份程序状态寄存器(SPSR_ELx)是一对。当异常发生时,处理器会将PSTATE寄存器的值保存到当前异常级别对应的SPSR_ELx寄存器;当异常返回时(eret),处理器会将SPSR_ELx寄存器的值恢复到PSTATE寄存器。这是硬件自动行为,不需要编程人员操作。
上面的图不好,且容我从别处找个图。
条件判断相关的域
如cmp指令,tst指令,条件判断时用到这些标志位;还有像sbc等运算指令,会将标志位一并加入运算。
异常掩码标志位
部分字段有专门对应的寄存器,如NZCV寄存器、CurrentEL寄存器。注意:EL0级别只能访问PSTATE.{N, Z, C, V}和PSTATE.{D, A, I, F}字段。
ARMv8支持的特殊寄存器:
部分寄存器还可以当作32位的使用:
当异常发生时,处理器会将PSTATE寄存器的值保存到当前异常级别对应的SPSR_ELx寄存器;当异常返回时(eret),处理器会将SPSR_ELx寄存器的值恢复到PSTATE寄存器。这是硬件自动行为,不需要编程人员操作。
AArch64下各域的含义:
在ARMv8中,写入的SPSR依赖于异常级别。如果异常发生在EL1,则使用SPSR_EL1。如果异常发生在EL2,则使用SPSR_EL2,如果异常发生在EL3,则使用SPSR_EL3。处理器核会在异常发生时填充SPSR。
注意: 与异常级别相关联的寄存器对ELR_ELn和SPSR_ELn保存着在较低异常级别执行期间的状态。
异常链接寄存器保存异常返回地址。在执行eret指令后,会将该寄存器的值赋值给PC。
该寄存器表示PSTATE中的EL字段,其中保存了当前异常级别。使用MRS指令可以读取该寄存器。
该寄存器表示PSTATE中的{D, A, I, F}字段。使用MRS指令可以读取该寄存器。
该寄存器表示PSTATE中的SP字段,用于在SP_EL0和SP_ELx中选择使用哪个。
该寄存器表示PSTATE中的PAN(Privileged Access Never, 特权禁止访问)字段。可以通过MSR和MRS指令读取和设置寄存器。这是ARMv8.1新增特性,为了防止内核态恶意访问用户态内存。
PAN寄存器的值如下:
该寄存器表示PSTATE中的UAO(User Access Override, 用户访问覆盖)字段。可以通过MSR和MRS指令读取和设置寄存器。
UAO值为1 ,表示在EL1和EL2执行非特权指令(如LDTR、STTR)的效果和特权指令(例如LDR、STR)是一样的。
该寄存器表示PSTATE中的{N, Z, C, V}字段。
PC寄存器通常用来指向当前运行指令的下一条指令的地址。
在原来的ARMv7体系结构中,将通用寄存器R15作为程序计数器(PC),同时作为一个通用寄存器使用。编程人员可以通过修改PC寄存器的值控制程序中指令的运行顺序。但这增加了编译器和复杂的流水线的设计困难。
在ARMv8中,PC不再作为一个命名的寄存器来访问,编程人员无法通过指令来直接访问它。但是,可以在某些指令中隐式的使用PC,如PC相对加载和地址生成(adrp等指令)。
XZR:64位
WZR: 32位
当访问零寄存器时,所有写操作都被忽略(用于将一个结果丢弃),所有读操作返回0。
在ARMv8体系结构中,4个异常级别各有一个SP寄存器SP_ELn。认情况下,发生异常时会选择目标异常级别的SP_ELn作为栈指针。
EL0永远只能访问SP_EL0。其他异常级别ELx: