基础篇(二).ARMv8寄存器(1)

ARMv8寄存器(1)


ARMv8寄存器实在太多了,本节主要针对系统软件常用的寄存器作为重点介绍。

1.ARMv8寄存器介绍

ARMv8架构(针对Core来说)至少有上千个寄存器,更别提Core外SOC级外设寄存器。这两类寄存器的区别是:前者(不管通用寄存器还是系统寄存器)不占用地址空间,而后者是和内存统一编制的,要占用地址空间。

下面我们主要针对ARM Core内寄存器进行介绍。ARM核心寄存器可以分为:

  • 通用寄存器。这类寄存器主要是用来暂存数据和参与运算。通过load\store指令操作。
  • 状态寄存器。AArch64体系结构使用PSTATE寄存器表示当前处理器状态。
  • 特殊寄存器。有专门的用途,用于控制处理器的行为,或表示CPU的状态。
  • 系统寄存器。除了以上寄存器,ARMv8体系结构还定义了很多系统寄存器,用来完成对处理器不同功能的配置。对应ARMv7的cp15寄存器。

而系统寄存器,根据其功能又可以分为11种:

  • 基本系统寄存器。
  • 特殊目的寄存器。3个ELR, 4个SP, 8个SPSR。
  • VMSA(虚拟内存架构)特殊寄存器。
  • ID寄存器。
  • 性能监控寄存器。
  • DEBUG寄存器。
  • RAS寄存器。
  • 通用定时器寄存器。
  • Cache维护相关寄存器。
  • 地址转换寄存器。
  • TLB维护寄存器。
  • 分支预测寄存器。

2.重点寄存器

这么多寄存器很难记得住,我们只需要重点关注以下寄存器,其余寄存器用到时候再查手册。

寄存器 描述
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) 地址翻译控制寄存器

3.通用寄存器

AArch64执行状态提供了31个在任何时间任何特权级下都可访问的64位的通用寄存器,分别是X0-X30。而AArch32状态支持16个32位的通用寄存器。

每个AArch64 64位通用寄存器(X0-X30)也具有32位(W0-W30)形式。

基础篇(二).ARMv8寄存器(1)_第1张图片
32位W寄存器取自相应的64位X寄存器的低32位。也就是说,W0映射到X0的低32位,W1映射到X1的低32位。

从W寄存器读取时,忽略相应X寄存器高32位,并保持其它不变。写入W寄存器时,将X寄存器的高32位设置为零。也就是说,将0xFFFFFFFF写入W0会将X0设置为0x00000000FFFFFFFF。

通用寄存器在ACPS中用法

除了用于数据运算和存储外,通用寄存器还在函数的调用过程中起到特殊作用,ARM64体系结构的函数调用标准和规范对此有约定,如下图所示。

基础篇(二).ARMv8寄存器(1)_第2张图片

说明:

  • X0-X7 用于参数传递
  • - [ ] X9-X15 在子函数中使用这些寄存器时,直接使用即可, 无需save/restore. 在汇编代码中x9-x15出现的频率极低。在子函数中使用这些寄存器时,直接使用即可, 无需save/restore.。在汇编代码中x9-x15出现的频率极低。
  • X19-X29 在callee子函数中使用这些寄存器时,需要先save这些寄存器,在退出子函数时再resotre。在callee子函数中使用这些寄存器时,需要先save这些寄存器,在退出子函数时再resotre。
  • X8, X16-X18, X29, X30 这些都是特殊用途的寄存器。
  • – X8: 用于返回结果
  • – X16、X17 :进程内临时寄存器
  • – X18 :resrved for ABI
  • – X29 :FP(frame pointer register)
  • – X30 :LR

4.处理器状态 (PSTATE)

ARMv7中使用当前程序状态寄存器(CPSR)表示处理器当前状态。AArch64没有直接与之等价的寄存器。

在AArch64中,传统CPSR的组件作为可以独立访问的字段提供。这些状态被统称为处理器状态(PSTATE)。

该程序和备份程序状态寄存器(SPSR_ELx)是一对。当异常发生时,处理器会将PSTATE寄存器的值保存到当前异常级别对应的SPSR_ELx寄存器;当异常返回时(eret),处理器会将SPSR_ELx寄存器的值恢复到PSTATE寄存器。这是硬件自动行为,不需要编程人员操作。

AArch64的处理器状态或PSTATE字段有以下定义:
基础篇(二).ARMv8寄存器(1)_第3张图片

上面的图不好,且容我从别处找个图。

条件判断相关的域
基础篇(二).ARMv8寄存器(1)_第4张图片
如cmp指令,tst指令,条件判断时用到这些标志位;还有像sbc等运算指令,会将标志位一并加入运算。

异常掩码标志位

基础篇(二).ARMv8寄存器(1)_第5张图片

  • 1:表示屏蔽了这个异常
  • 0:表示没有屏蔽这个异常

执行状态控制位
基础篇(二).ARMv8寄存器(1)_第6张图片

部分字段有专门对应的寄存器,如NZCV寄存器、CurrentEL寄存器。注意:EL0级别只能访问PSTATE.{N, Z, C, V}和PSTATE.{D, A, I, F}字段。

5.特殊寄存器

ARMv8支持的特殊寄存器:
基础篇(二).ARMv8寄存器(1)_第7张图片
部分寄存器还可以当作32位的使用:
基础篇(二).ARMv8寄存器(1)_第8张图片

5.1 备份程序状态寄存器(SPSR_ELx)

当异常发生时,处理器会将PSTATE寄存器的值保存到当前异常级别对应的SPSR_ELx寄存器;当异常返回时(eret),处理器会将SPSR_ELx寄存器的值恢复到PSTATE寄存器。这是硬件自动行为,不需要编程人员操作。
基础篇(二).ARMv8寄存器(1)_第9张图片
AArch64下各域的含义:

  • N 负数标志位,如果结果为负数,则N=1;如果结果为非负数,则N=0。
  • Z 零标志位,如果结果为零,Z=1,否则Z=0。
  • C 进位标志位
  • V 溢出标志位
  • SS 是否是能软件单步功能 ,若为1,说明在异常处理中软件单步功能开启
  • IL 非法执行状态位
  • D 程序状态调试掩码,在异常发生时的异常级别下,来自监视点、断点和软件单步调试事件中的调试异常是否被屏蔽。
  • A SError(系统错误)掩码位
  • I IRQ掩码位
  • F FIQ掩码位
  • M[4] 异常发生时的执行状态 ,0表示AArch64状态
  • M[3:0] 异常发生时的模式或异常级别

在ARMv8中,写入的SPSR依赖于异常级别。如果异常发生在EL1,则使用SPSR_EL1。如果异常发生在EL2,则使用SPSR_EL2,如果异常发生在EL3,则使用SPSR_EL3。处理器核会在异常发生时填充SPSR。

注意: 与异常级别相关联的寄存器对ELR_ELn和SPSR_ELn保存着在较低异常级别执行期间的状态。

5.2 异常链接寄存器(ELR)

异常链接寄存器保存异常返回地址。在执行eret指令后,会将该寄存器的值赋值给PC。

5.3 CurrentEL寄存器

该寄存器表示PSTATE中的EL字段,其中保存了当前异常级别。使用MRS指令可以读取该寄存器。

  • 0:表示EL0.
  • 1:表示EL1
  • 2:表示EL2.
  • 3:表示EL3.

5.4 DAIF寄存器

该寄存器表示PSTATE中的{D, A, I, F}字段。使用MRS指令可以读取该寄存器。

5.5 SPSel寄存器

该寄存器表示PSTATE中的SP字段,用于在SP_EL0和SP_ELx中选择使用哪个。

5.6 PAN寄存器

该寄存器表示PSTATE中的PAN(Privileged Access Never, 特权禁止访问)字段。可以通过MSR和MRS指令读取和设置寄存器。这是ARMv8.1新增特性,为了防止内核态恶意访问用户态内存。

PAN寄存器的值如下:

  • 0: 表示内核态可以访问用户态内存。
  • 1:表示内核态访问用户态内存会触发一个访问权限异常。

5.7 UAO寄存器

该寄存器表示PSTATE中的UAO(User Access Override, 用户访问覆盖)字段。可以通过MSR和MRS指令读取和设置寄存器。

UAO值为1 ,表示在EL1和EL2执行非特权指令(如LDTR、STTR)的效果和特权指令(例如LDR、STR)是一样的。

5.8 NACV寄存器

该寄存器表示PSTATE中的{N, Z, C, V}字段。

5.9 PC (Program Counter,程序计数器) 寄存器

PC寄存器通常用来指向当前运行指令的下一条指令的地址。

在原来的ARMv7体系结构中,将通用寄存器R15作为程序计数器(PC),同时作为一个通用寄存器使用。编程人员可以通过修改PC寄存器的值控制程序中指令的运行顺序。但这增加了编译器和复杂的流水线的设计困难。

在ARMv8中,PC不再作为一个命名的寄存器来访问,编程人员无法通过指令来直接访问它。但是,可以在某些指令中隐式的使用PC,如PC相对加载和地址生成(adrp等指令)。

5.10 零寄存器(WZR/XZR)

XZR:64位
WZR: 32位

当访问零寄存器时,所有写操作都被忽略(用于将一个结果丢弃),所有读操作返回0。

5.11 栈指针寄存器(SP)

在ARMv8体系结构中,4个异常级别各有一个SP寄存器SP_ELn。认情况下,发生异常时会选择目标异常级别的SP_ELn作为栈指针。

  • SP_EL0:程序在EL0时栈指针寄存器,EL0时只能使用此寄存器存放栈地址。
  • SP_EL1:程序在EL1时默认栈指针寄存器。
  • SP_EL2:程序在EL2时默认栈指针寄存器。
  • SP_EL3:程序在EL3时默认栈指针寄存器。

EL0永远只能访问SP_EL0。其他异常级别ELx:

  • 发生异常时,使用自己的SP_ELx寄存器存放栈地址;
  • 可以将SP_EL0寄存器作为临时寄存器来使用,例如Linux内核使用该寄存器存放进程中task_struct数据结构指针。

你可能感兴趣的:(ARMv8\ARMv9系列,ARM系列,arm开发,linux,arm,架构)