AArch32

A32和T32间的状态切换

当一个处理器在A32状态下时,不能执行T32指令,当一个处理器在T32状态下时,也不能执行A32指令,必须要保证处理器不会收到与当前处理器状态不相容的指令集指令。

处理器的初始化状态依赖于它自身的配置。同时,在汇编代码中,通常应用用如CODE16CODE32或者THUMB这样类似的关键子标示指令集,如果代码只执行过程中面临两种指令集的切换,则可以用BXBLX这样的分支指令跳转到相应代码,从而达到改变处理器执行状态为A32或者T32的目的,其中状态的改变由处理器自动完成。

处理器模式

Arm架构支持不同的运行特权级。而不同的特权级与不同的处理器模式密切相关。

如下为Arm处理器所支持的所有模式。

处理器模式 模式编号
User 0b10000
FIQ 0b10001
IRQ 0b10010
Supervisor 0b10011
Monitor 0b10110
Abort 0b10111
Hyp 0b11010
Undefined 0b11011
System 0b11111

用户模式是非特权级模式,在该模式下,只能受限地访问系统资源。其它模式在安全状态下都具有完全的系统资源访问权限,也能够自由地改变模式和在特权级下执行程序。

与用户模式相比,其它模式是进入异常服务或者访问特权级资源可的状态。

代码能够运行在安全状态,也能够运行在非安全状态。Hypevisor(Hyp)模式是非安全状态下的特权级执行状态。

在Arm-M系列的架构下,Thread Mode为非特权级模式,Handler Mode为特权级模式,用于处理所有异常。

AArch32下的寄存器

Arm处理器提供了通用寄存器和特殊目的寄存器。还有一些其它的寄存器能够在特权级模式下访问。对所有Arm处理器而言,在AArch32下,如下这些寄存器是能够在所有的处理器模式下都可以访问的。

  • 15个通用寄存器r0~r12,堆栈指针寄存器SP和链接寄存器LR
  • 1一个程序计数器PC
  • 1个应用程序状态寄存器APSR

Note SP和LR寄存器可以像通用寄存器一样被使用,尽管ARM强烈反对将SP用作其它用途,除用于状态状态指针寄存器外。

除了如上这些寄存器外,其它的寄存器能够在特权级模式下访问。Arm处理器总共有43个寄存器。每个处理器模式都有其对应的特殊寄存器。这些寄存器为异常处理和特权级操作提供了快速的上下文切换。

如下为所有模式下寄存器的可用寄存器表:

寄存器 User System Hyp+ Supervisor Abort Undefined Monitor- IRQ FIQ
R0 R0_usr
R1 R1_usr
R2 R2_usr
R3 R3_usr
R4 R4_usr
R5 R5_usr
R6 R6_usr
R7 R7_usr
R8 R8_usr R8_fiq
R9 R9_usr R9_fiq
R10 R10_usr R10_fiq
R11 R11_usr R11_fiq
R12 R12_usr R12_fiq
SP SP_usr SP_hyp SP_svc SP_abt SP_und SP_mon SP_irq SP_fiq
LR LR_usr LR_svc LR_abt LR_und LR_mon LR_irq LR_fiq
PC PC
APSR CPSR
SPSR SPSR_hyp SPSR_svc SPSR_abt SPSR_und SPSR_mon SPSR_irq SPSR_fiq
ELR ELR_hyp
  • +表示仅存在于安全状态
  • -表示仅存在于非安全状态
  • 表中为空的位置表示于用户模式下所用的基础器相同

通用目的寄存器

如果将SP和LR作为通用目的寄存器使用的话存在一些限制田间。在Arm M系列架构下,拥有33个32位的通用寄存器。其中15个通用寄存器在任何一个时间点都可见,它们是R0~R12、SP和LR。PC(R15)不是通用寄存器。

SP(R13)是堆栈指针寄存器,C和C++编译器总是将SP用来表示堆栈指针。同时ARM也不推荐将SP用作其它目的的通用寄存器来使用。在T32下,SP总是被用来表示堆栈指针。

在用户模式下,LR(R14)被当作链接寄存器使用,其作用是用于存储函数调用的返回地址。它也可以作为通用寄存器使用,如果函数返回地址被存储在堆栈中的话。

在异常处理模式下,LR被用来存储异常调用返回地址,这个返回地址可以是一个用户态函数地址,也可以是另一个异常处理程序中的地址。同样这个地址也可以被存在堆栈中中。

寄存器访问

16位的T32指令只能访问有限的寄存器。大部分的16位T32指令仅能访问R0~R7,只有少部分16位的T32指令能够访问R8~R12,SP,LR和PC。R0~R7被称为低位寄存器,R8~R12,SP,LR和PC被称作高位寄存器。

所有的32位T32指令都能够访问R0~R12和LR。由于SP被设计用来作为堆栈指针寄存器,因此大部分T32指令不能使用SP,同样PC寄存器由于其特殊作用,也仅有少部分T32指令能够访问。

在A32状态下,所有的指令都能够访问R0~R12,SP和LR,同时大部分指令也能够访问PC(R15)寄存器。

MRS指令能够将状态寄存器的内容移动到通用寄存器中,用于对当前程序状态进行操作和判断,同时也可以使用MSR将通用寄存器的内容移入状态寄存器。这两个指令正好相反。

核心寄存器的别名定义

许多寄存器都具有别名,在汇编程序中,可以方便的使用别名来指代它们。如下为AArch32中常用寄存器的别名。

寄存器名 描述
r0~r15或R0~R15 通用寄存器
a1~a4 参数或返回值寄存器,它们是R0~R3的别名
v1~v8 变量寄存器,它们是R4~R11的别名
SB 静态基址寄存器,R9的别名
IP 内部处理调用寄存器,R12的别名
SP 堆栈指针寄存器,R13的别名
LR 链接寄存器,R14的别名
PC 程序计数器,R15的别名
Q0~Q15 高级SIMD四字寄存器
D0~D31 高级SIMD双字寄存器,双精度浮点寄存器
S0~S31 单精度浮点寄存器

程序计数器

一些T32的数据处理指令和分支指令能够直接使用PC,PC寄存器每次增加的值由当前指令字长决定,如果是32位指令,则PC=PC+4。

分支指令可以直接将目的地址加载到PC,同时,你也可以用数据操作指令来加载PC值,例如要跳转到一个存储在通用寄存器R0中的地址处。

1
MOV PC, R0

当在执行时,PC包含当前正在执行的指令的地址,当前正在执行的指令地址通常位PC-8(A32)或者位PC-4(T32)

NOTE Arm建议使用BX分支指令来进行地址跳转或函数返回,而尽量不要直接对PC进行读写。

Q标志

Q标志用于指示溢出,它是位于APSR中的程序状态标志之一。Q标志如果被置为1时,则表示当前的算术指令的运算发生溢出。由于Q标志被设置后,算术指令无法清除该标志,因此对于溢出状态的检查不必每条都检查,可以在运行多条算数指令后再看是否发生过溢出。如果要清除Q标志,可以使用MSR指令对APSR寄存器进行读-修改-写。

1
2
3
MRS r4, APSR
BIC r5, r5, #(1<<17)
MSR APSR_nzcvq, r5

Q标志不能被直接用于条件码测试,必须要先读到通用寄存器后才能进行测试。

1
2
MRS r6, APSR
TST r6, #(1<<27); Z is clear if Q flag was set

程序状态寄存器

APSR保存了程序的状态标志,APSR能够在任何处理器模式下进行访问。

其中包含N,Z,C和V这几个条件标志,处理器能够根据它们的状态来决定是否执行条件指令。

Q标志虽然也能用于条件判断,但需读出来才能进行。同时APSR中还包含GE(Greater than or Equal)标志,并行的加法和减法指令都能够设置GE标志,GE标志可以被用于SEL指令的判断。

当前程序状态寄存器

CPSR包含了APSR中的所有信息,同时又有一些额外的信息。其中包括:

  • APSR标志
  • 处理器模式
  • 中断关闭标志
  • 指令集标志
  • 大小端状态
  • 执行状态标志位,用于IT阻塞

Saved Program Status Registers

当发生异常时,SPSR用于存储CPSR的值,用于从异常退出时CPSR寄存器的恢复,每个异常处理模式都能够访问它们自己的SPSR,用户模式和系统模式没有SPSR,因为它们是属于异常处理模式。


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 yxhlfx@163.com

文章标题:AArch32

本文作者:红尘追风

发布时间:2019-09-14, 20:43:43

原始链接:http://www.micernel.com/2019/09/14/AArch32/

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。

目录