ARMv8寄存器

AArch64 中的寄存器

The general purpose registers

该架构提供了 31 个通用寄存器。每个寄存器都可以用作 64 位 X 寄存器 (X0…X30),或用作 32 位 W 寄存器 (W0…W30)。这是查看同一寄存器的两种不同方式。比如这张寄存器图,W0是X0的低32位,W1是X1的低32位:
image.png
图 1.寄存器图
对于数据处理指令,选择X或W决定操作的大小。使用X寄存器将导致 64 位计算,使用 W 寄存器将导致 32 位计算。
此示例执行 32 位整数加法:ADD W0, W1, W2
此示例执行 64 位整数加法:ADD X0, X1, X2
写入寄存器时W,如上例所示,64 位寄存器的前 32 位被清零。
image.png

特殊寄存器

image.png

Zero register

零寄存器XZR和WZR始终读为 0 并忽略写入。

stack pointer

  1. ARMv8体系结构为每个异常等级都实现了一个栈指针SP_ELn,以异常等级为后缀
  2. 当PE在某个异常等级处理异常时,可配置使用如下2个栈指针之一(通过PSTATE.SP配置),
    ① 所处理异常的target exception level对应的SP_ELn(默认情况)
    ② SP_EL0(注意,EL0是不会作为target exception level的,所以这不是默认情况,而是需要特殊配置的)
    说明1:配置使用SP_EL0是在PE已经切换到targe exception level上进行的
    说明2:即使异常处理没有发生异常等级切换,也需要处理上述栈指针的配置
    例如PE当前在EL1运行,并且使用SP_EL0。此时如果发生异常,并且target exception level也是EL1,虽然异常等级不会切换,但是栈指针也会自动切换为SP_EL1。此时如果想继续使用SP_EL0,则仍需要设置PSTATE.SP
    image.png
    t后缀表示thread,此时使用SP_EL0作为栈指针;h后缀表示handler,此时使用当前异常等级对应的栈指针。
    3:在Linux内核中,当从EL0陷入EL1时,使用SP_EL1作为当前栈指针。此时SP_EL0可以作为一个临时寄存器使用,Linux内核会使用该寄存器存放进程的task_struct结构指针

Saved Program Status Registers (SPSRs)

用于保存发生异常时的处理器状态

  1. ARMv8体系结构为每个可作为target exception level的异常等级都实现了一个SPSR_ELn,以异常等级为后缀
  2. 当异常发生时,处理器的状态将被保存在target exception level的SPSR寄存器;当异常返回时,将使用的SPSR寄存器中的值恢复PSTATE
  3. 保存异常发生时PSTATE状态的另一个作用,就是可以在异常处理时通过SPSR寄存器判断发生异常时的PE状态,例如发生异常时PE的异常等级和执行状态
    image.png
    SPSR寄存器保存的很多状态位与PSTATE中是相同的。这里特别说明一下M[4]和M[3:0]的含义
    ① M[4]:记录异常发生时的执行状态,即PSTATE.nRW位。0表示AArch64执行状态,1表示AArch32执行状态
    ② M[3:0]:记录异常发生时的异常等级及其使用的栈指针
    image.png
  • M[3:2]标识发生异常时的异常等级
  • M[1]为保留位,需要置为0
  • M[0]标识栈指针SP的选择,0表示使用SP_EL0,1表示使用与异常等级对应对应的SP_ELn

说明2:不像栈指针SP的使用可配置,异常发生时只能使用与targe exception level相应的SPSR_ELn
说明2:异常返回时,使用SPSR_ ELx的内容来恢复PSTATE。

Exception Link Registers (ELRs))

  1. ARMv8体系结构为每个可作为target exception level的异常等级都实现了一个ELR_ELn,以异常等级为后缀
  2. 当异常发生时,异常返回地址将被保存在target exception level的ELR寄存器;当异常返回时,将使用的ELR寄存器中的值恢复到PC寄存器
    说明:和SPSR寄存器一样,异常发生时也只能使用与targe exception level相应的ELR_ELn

其中,对于保存什么异常返回地址,对于不同的异常规则不同。
首选的异常返回地址取决于异常的性质,如下所示:
l 对于异步异常,它是发生中断的指令边界之后的指令的地址。因此,它是由于中断而没有执行或没有完成执行的第一条指令的地址。
l 对于系统调用以外的同步异常,它是生成异常的指令的地址。
l 对于系统调用,它是系统调用指令后面的指令的地址。
n 注意:如果由于异常级别没有足够的权限执行指令而导致系统调用指令被捕获、禁用或未定义,则首选的异常返回地址为系统调用指令的地址。
n 系统调用是通过执行SVC、HVC或SMC指令生成的。

Process state, PSTATE

在ARMv7体系结构中,使用CPSR寄存器来表示当前处理器的状态。在ARMv8中,将PE的状态抽象为PSTATE。在实现上,则是一组标志位的集合
image.png
image.pngimage.png

ARMv8体系结构提供了一组特殊寄存器,用于访问PSTATE状态位

CurrentEL寄存器 表示PSTATE寄存器中的EL字段
DAIF寄存器 表示PSTATE寄存器中的{ DAIF}字段
SPSel寄存器 表示PSTATE寄存器中的SP字段
PAN寄存器 PSTATE寄存器中的PAN
UAO寄存器 UAO为1表示在EL1和EL2执行这非特权指令(例如LDTR、STTR)的效果与特权指令(例如LDR、STR)是一样的。
NZCV寄存器

说明:当内核态拥有访问用户态内存或者执行用户态程序的能力时,攻击者就可以利用漏洞轻松地执行用户的恶意程序。为了修复这个漏洞,在ARMv8.1中新增了PAN特性,防止内核态恶意访问用户态内存。如果内核态需要访问用户态内存,那么需要主动调用内核提供的接口,例如copy_from_user()或者copy_from_user()函数。(将内核态与用户态隔离的思想,在很多方面都提现了出来,比如内存管理中的内存隔离,内存映射等)
PAN寄存器的值如下。

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

对于这些特殊寄存器的访问,只能通过MRS(读)/MSR(写)指令完成。
举例:仅设置C标志位为1
MRS R0,NZCV ;读NZCV到R0
ORR R0,R0,#0x200000000 ;设置R0的第29位
MSR NZCV,R0 ;写NZCV

Counter( PC)

Program Counter( PC)在A64中不是通用寄存器,不能和数据处理指令一起使用。可以使用以下方式读取 PC:ADR Xd, .
点 ( .) 表示“这里”,因此显示的指令返回其自身的地址。这相当于阅读PC.

系统寄存器

数据处理或加载/存储指令不能直接使用系统寄存器。相反,需要将系统寄存器的内容读入寄存器X,对其进行操作,然后写回系统寄存器。有两个用于访问系统寄存器的专用指令:
MRS Xd, 将系统寄存器读入Xd.
MSR , Xn 写入Xn系统寄存器。
系统寄存器由名称指定,例如SCTLR_EL1:MRS X0, SCTLR_EL1 读SCTLR_EL1入X0.
系统寄存器名称以_ELx. 指定_ELx访问寄存器所需的最低权限。

猜你喜欢

转载自blog.csdn.net/qq_52353238/article/details/131752372
今日推荐