ArmV8 寄存器简单概念:
ARMv8拥有两种执行模式:
AArch64执行A64指令,使用64bit的通用寄存器;
AArch32执行A32/T32指令,使用32bit的通用寄存器;
本篇主要描述aarch64执行模式的一些概念
OverView
寄存器类型 | 位宽 | 描述 |
---|---|---|
X0-X30 | 64bit | 通用寄存器,也可以用作32bit(w0-w30) |
PLR(X30) | 64bit | produce link register, 连接寄存器,保存跳转返回信息地址 |
SP_ELx(x=0,1,2,3) | 64bit | stack pointer registers,堆栈指针寄存器 |
ELR_ELx(x=1,2,3) | 64bit | exception link registers,异常链接寄存器,当发生异常时,目标异常级别的异常链接寄存器存储在异常处理完成后跳转到的返回地址 |
SPSR_ELx(x=1,2,3) | 32bit | saved program status registers, 保存进入ELx的PSTATE状态信息 |
V0-V31 | 128bit | 浮点寄存器,主要用于向量或标量的SIMD操作, 也可以用作32个64bit D0-D31或32个32bit S0-S31 或32个 16bit H0-h31 或 32个8bit B0-B31 |
PC | 64bit | 程序计数器,俗称PC指针,总是指向即将要执行的下一条指令 |
PSTATE不是一个寄存器,是保存当前PE状态的一组寄存器统称,其中可访问寄存器有:PSTATE.{NZCV,DAIF,CurrentEL,SPSel},属于ARMv8新增内容,64bit下代替CPSR
注:
没有名为X31或W31的寄存器。 一些指令被编码了,以使数字31代表零寄存器ZR(WZR / XZR)。 还有一组受限制的指令,其中一个或多个参数被编码,以使数字31代表堆栈指针(SP).
Exception levels:
ARMv8定义了四种异常类型, EL0-EL3, 级别依次从低到高。
EL0为普通用户程序
EL1是操作系统内核相关
EL2是Hypervisor, 可以理解为上面跑多个虚拟OS
EL3是Secure Monitor(ARM Trusted Firmware)
link registers:
链接寄存器(LR)在进行子程序调用时存储返回地址。如果返回地址存储在堆栈中,它也可以用作通用寄存器, LR会映射到寄存器X30.
有三个异常链接寄存器,ELR_EL1,ELR_EL2和ELR_EL3,对应3个异常级别。当发生异常时,目标异常级别的异常链接寄存器存储在异常处理完成后跳转到的返回地址。如果异常取自AArch32状态,则ELR中的前32位都设置为零。异常级别内的子程序调用使用LR存储子程序的返回地址。
例如,当异常级别从EL0更改为EL1时,返回地址存储在ELR_EL1中。
在异常级别中,如果启用使用相同异常级别的中断,则必须确保将ELR存储在堆栈中,因为在执行中断时将使用新的返回地址覆盖它。
stack pointer registers:
堆栈指针(SP)是一个指向堆栈顶部的寄存器。 选择使用的堆栈指针在某种程度上与“异常”级别是分开的。 默认情况下,发生异常时会为目标异常级别选择堆栈指针(SP_ELn)。 例如,发生EL1异常时选择SP_EL1。 每个异常级别都有自己的堆栈指针。
但是,当在AArch64中,异常级别的不是E0时,处理器可以使用下面中的任何一种:
与该异常级别(SP_ELn)关联的64位堆栈指针,或者,
与EL0(SP_EL0)关联的堆栈指针。 EL0只能访问SP_EL0。
SP不能被大多数指令引用。 但是,一些算术指令,例如ADD指令,可以读写当前的堆栈指针来调整函数中的堆栈指针。 例如:
ADD SP, SP, #0x10 // 将SP调整为当前值之前的0x10字节
ADD SP, SP, #256 // SP = SP + 256
saved program status registers:
当异常发生时,PSTATE在SPSR里面保存。
N:负于或小于
Z:零
C:进位或借位或扩展
V:溢出