一 通用寄存器
AArch64执行状态有31个64位的通用寄存器,这些寄存器在所有ELn中均可使用,命名为X0-X30:
每个AArch64 64位通用寄存器X0-X30都有一个对应的32位寄存器,Wn寄存器是Xn寄存器的底32位:
读Wn寄存器时会保持Xn寄存器的高32位不变,如果写W寄存器时,会将X寄存器的高32位设为0
二 AArch64 特殊寄存器
除了以上31个通用寄存器外,还有几个特殊寄存器:
注意:没有叫做X31/W31的寄存器,一些指令会将31号寄存器编译为zero 寄存器WZR/XZR,极少情况下会将31号指为栈指针SP
特殊寄存器命令如下,注意AArch64下的SP没有前缀:
-
zero register
写操作被忽略,读操作都返回0
-
SP/WSP
当前栈指针 -
PC program counter
ARMv7指令集使用通用寄存器R15作为PC,直接操作PC可以做一些机智的编程操作,但是ARMv8不能直接进入PC,这使返回更好预测,并且使ABI规范更加简单。 -
ELR / SPSR
当armV8执行在AArch64,每个ELn异常返回状态取决于ELR和SPSR
ELR exception link register 保存exception返回地址
SPSR saved processor state register 执行exception前保存当前的processor state, 执行exception完返回时restore
在ARMv8中,如果异常发生在EL1,就使用SPSR_EL1,如果发生在EL2, 使用SPSR_EL2,如果发生在EL3, SPSR_EL3使用
ELR 和SPSR时成对的,其和对应的ELn相关
-
SP 每个 exception level 都有对应的 SP:
大多数指令不会涉及SP寄存器,但是一些术指令会操作SP,比如:
ADD SP, SP, #0x10 // adjust SP to be 0x10 bytes before its current value
三 processor state
AArch64中没有像ARMv7中的CPSR,但有一个类似的PSTATE.
当执行指令ERET从一个异常返回时,会将SPSR_ELn拷贝到PSTATE。
四 system register 系统寄存器
在AArch64中,控制system configuration是通过 system register的,使用MSR 和 MRS指令进入system register。
相比于ARMv7中,ARMv7使用CP15协处理器进入这些寄存器
这些寄存器的名字告诉了你最低的可以访问的异常级别,比如:
TTBR0_EL1, 可以被EL1 EL2 EL3访问
TTBR0_EL2, 可以被EL2 EL3访问
几乎没有system register可以从EL0访问,但是 cache type register CTR_EL0是个例外
代码通过如下方式进入system register :
MRS x0, TTBR0_EL1 // move TTBR0_EL1 into x0
MSR TTBR0_EL1, x0 //move x0 into TTBR0_EL1
ARMv8之前的版本使用协处理器来做system configuration,但是AArch64不支持协处理器
system registers 具体有哪些寄存器,请看4.3章
比如system registers 中的系统控制寄存器SCTLR:SCTLR_ELn
五 大小端
六 改变执行状态
笔记二中描述AArch64和AArch32直接的转换是从ELn角度,这里从寄存器角度
当一个运行AArch32的exception level进入到运行AArch64的exception level时:
- 对于运行AArch32的较低exception level可以访问的高32位寄存器值是未知的
- AArch32执行时不能进入的寄存器值依然保留其执行AArch32前的值
- EL2处于AArch32状态,异常进入EL3时, ELR_EL2寄存器的高32位未知
在AArch32状态下的寄存器:
v8向后兼容,ARMv7有16个32位通用寄存器R0-R15, R15作为PC, 软件也可以访问CPSR, 发生异常时将CPSR的值可以保存到SPSR
ARMv7寄存器如下:
AArch64有31个在任何时间任何exception level都可以访问的64位寄存器, 所以在AArch64和AArch32之间转换时,AArch64的寄存器要映射到AArch32下的寄存器:
七 NEON和浮点寄存器
armV8有32个 128bit的浮点寄存器 V0-V31. 这32个寄存器用来处理标量浮点预算和NEON指令指令