操作系统中硬件相关的部分集中体现在汇编指令和对寄存器的操作中,因此我们对ARM体系结构的介绍也围绕ARMv8-A的汇编指令和寄存器来展开。处理器架构是处理器厂商为同一个系列的处理器规定的一个规范。ARM架构是一种精简指令集(RISC)架构,具有以下RISC架构特点:
一、AMRv8架构概要 ARM体系结构自推出以来已经有了显著的发展,并且ARM还在继续开发它。到目前为止,已经有八个主要版本,由版本号1到8表示。其中前三个版本现在已经过时了。 通用名称AArch64和AArch32描述了64位和32位执行状态。AArch64是64位执行状态,意味着地址保存在64位寄存器中,并且基本指令集可以使用64位寄存器进行处理。AArch64支持A64指令集。AArch32是32位执行状态,这意味着地址保存在32位寄存器中,并且基本指令集使用32位寄存器进行处理。AArch32支持T32和A32指令集。 ARM支持三种架构配置:
二、ARMv8-A指令集 在ARMv8-A中,可能的指令集取决于执行状态:
ARM指令的基本格式如下[2]: <Opcode>{<Cond>}<S><Rd>,<Rn> {,<Opcode2>} 其中各个部分的含义为:
ARMv8-A指令集的条件码如下图所示: 下面以A64指令集为例简要介绍ARMv8-A的指令体系。A64指令集中的指令主要分为控制指令、访存指令和计算指令。控制指令主要包括有条件分支指令、无条件分支指令、异常产生和返回指令、系统寄存器指令、系统指令、提示指令、同步指令和清除独占访问标志指令。访存指令主要有Load指令和Store指令,这两种指令有许多变种。计算指令包含算数指令、逻辑指令、MOVE指令、移位指令、位扩展指令和SIMD指令等等。以下列出了一些常用的控制指令的名称与用途。 1. 控制指令:
例如: 2. 访存指令: ARMv8访存指令支持以下寻址模式:
具体情形见下表: 其中对于A64指令集来说,64bit的基址来自通用寄存器X0-X30或来自栈指针SP,立即数或寄存器偏移值则是可选的,对寻址方式的解释如下:
下面列出了一些load/store指令: 例如Load寄存器指令:
上表中指令的寻址方式有:
如果被load或store的指令的寻址模式会修改基址寄存器的内容,且被load/store寄存器恰好的是基址所在的寄存器,那么硬件的行为可能不确定。 3.计算指令: 在操作系统汇编语言中使用的计算指令主要是一些简单的算数计算指令,用于对寄存器的move操作和对地址的计算操作,一般计算指令既可以使用立即数作为操作数,也可以使用寄存器中的数作为操作数。下面简单列举了一些算数指令: 使用立即数的简单算数指令: 例如: 使用寄存器的逻辑操作指令: 例如: 其中: 寄存器移位指令: 例如: ARM架构寄存器在处理器中,寄存器用于保存需要被快速访问的数据,在操作系统中需要特别注意的寄存器主要有栈指针寄存器(SP)、连接寄存器(LR)、程序计数器(PC)以及当前程序状态寄存器(CPSR)和保存程序状态寄存器(SPSR)。本小节主要以ARMv8-A为例介绍ARM架构的寄存器的基本情况。详情可参见文献[3],D1.6小节。在这一小节中,我们主要介绍ARMv8架构中AArch64执行状态下的寄存器使用情况。ARM架构中的寄存器主要有两类,一类用于提供系统控制与状态报告;另一类用于指令运行和异常处理。我们主要讨论第二类。 通用寄存器主要用于基本指令集中的指令运行,通用寄存器共有31个,编号为R0-R31。这些通用寄存器可以被当成31个64bit的寄存器,编号为X0-X30;或者被作为31个32bit的寄存器,编号为W0-W30。 在AArch64执行状态下,除了通用寄存器外,每一个异常级别都会有一个栈指针寄存器(StackPointer Register, SP),栈指针寄存器为SPEL0和SPEL1。异常级别用于区分指令的执行权限,我们将在本章的第四期介绍。如果处理器实现中包含EL2,那么还有SPEL2。如果处理器实现中包含EL3,那么还有SPEL3。详情可参考链接[5]。 SIMD和浮点寄存器共用一系列寄存器,这些寄存器会用于浮点操作、向量操作和其它SIMD有关的标量操作。SIMD指令是能够复制多个操作数、并把它们打包在大型寄存器的一组指令集[3]。以加法指令为例,单指令单数据(SISD)的CPU对加法指令译码后,执行部件先访问内存,取得第一个操作数;之后再一次访问内存,取得第二个操作数;随后才能进行求和运算。而在SIMD型的CPU中,指令译码后几个执行部件同时访问内存,一次性获得所有操作数进行运算。浮点寄存器和SIMD寄存器共包含32个128bit位宽的寄存器,V0-V31。这些寄存器可以作为:
程序状态寄存器(Current Program Status Register,CPSR) 在用户级编程时用于存储条件码。CPSR包含条件码标志,中断禁止位,当前处理器模式以及其他状态和控制信息。 保存程序状态寄存器(SPSR,Saved Program StatusRegister)用于保存CPSR的状态,以便异常返回后恢复异常发生时的工作状态。在A64中,不再使用单一的CPSR寄存器,来保存当前处理器状态,而是用PSTATE来保存处理器状态,而在A32中依然使用CPSR。有关PSTATE和CPSR的详细信息可参考链接[4]。A64中SPSR 格式的示意图如下图所示: 其中N、Z、C、V均为条件码标志位。它们的内容可被算术或逻辑运算的结果所改变,并且可以用于决定某条指令是否被执行,其含义如下表所示[8]:
M[3:0]则用来确定异常级别和SP: 有关SPSR中各个位的详细信息可以参考文献[1] 1.6.4小节。 连接寄存器LR(R14)的主要作用有两个: 1. 保存子程序返回地址,用MOVE指令或BX指令可以用于实现返回,如MOV PC、LR或BXLR。若子程序中还需要调用子程序,则可以写为: 第一条指令将LR中的内容入栈,最后一条将栈中保存的LR寄存器的内容存入PC中用于返回。 2. 当异常发生时,异常模式的LR用于保存异常返回地址,将LR内容入栈可以处理嵌套中断。 PC是程序计数器,其中保存的是正在被加载的指令,而不是正在被执行的指令。例如,若指令长度为4byte,则PC指向当前正在被执行的指令的地址+8byte的地址。关于LR和PC的详细内容可参考文献[6]和[7]。 以下是异常级别EL3中使用的寄存器的例图: ARM架构中处理器有不同的运行模式,因此同一个功能的寄存器在不同的运行模式下可能对应不同的物理寄存器,这些寄存器被称为备份寄存器。如SPSR_svc表示svc模式下使用的SPSR寄存器。ARM架构中常用的运行模式如下表所示[9]:
ARMv8-A架构还有Monitor(mon)工作模式,用于处理器安全状态与非安全状态的切换,Hypervisor(hyp)模式则用于对虚拟化有关功能的支持。有关安全状态的详细内容在后续的文章中会介绍。 ARM架构中的执行状态 ARMv8-A有两种执行模式,一种是AArch64执行模式,另一种是AArch32执行模式。执行状态定义处理单元(Processing Element, PE)的执行环境,包括以下内容:
AArch64为64位执行状态。对应上述内容,此执行状态:
AArch32为32位执行状态。对应上述内容,此执行状态:
ARMv8-A有四个异常级别,从EL0到EL3。对于异常级别ELn,整数n增加表示软件执行的特权权限变大了。EL0级别下的执行叫非特权执行(unprivileged execution)。EL1主要用于运行操作系统内核。EL2可以支持非安全操作的虚拟化。EL3则支持安全状态和非安全状态之间的转换。安全状态与ARM TrustZone技术有关[2]。安全状态可以运行可信执行环境(TEE, Trusted Execution Environment)及安全应用,用于保障隐私数据和程序运行环境的安全性。 ARMv8-A架构并未直接指定哪些软件应该运行在哪些异常级别,但是在通常情况下,有如异常级别的使用模型: 1.应用程序运行在EL0; 2.操作系统内核和相关功能运行在EL1; 3.Hypervisor[3]运行在EL2; 4.安全世界状态和正常世界状态的切换在EL3完成。 下图反映了ARM-v8A架构中的执行状态、安全状态和异常级别之间关系[1]: 从图中我们可以看出,Hypervisor相关的支持特性主要是在EL2的非安全状态实现的。Hypervisor可以支持虚拟机之间的切换,而虚拟机主要被包含在EL1的非安全状态和EL0的非安全状态中。一些Guest OS可以运行在EL1状态里,每一个Guest OS可以运行在一个虚拟机上。而应用则运行在EL0的非安全状态中,同时也运行在Guest OS上。 引用 [1]ARM® Architecture Reference ManualARMv8, for ARMv8-A architecture profile** [2]https://blog.csdn.net/tanli20090506/article/details/71487570 [3]ARM® Architecture Reference ManualARMv8, for ARMv8-A architectureprofile [4]https://www.cnblogs.com/smartjourneys/p/6845078.html [5]https://baike.baidu.com/item/SIMD/3412835?fr=aladdin [6]http://www./?p=1676 [7]https://www.cnblogs.com/pengdonglin137/p/10259971.html [8]https://blog.csdn.net/layuetian2011/article/details/52039328 [9]https://blog.csdn.net/allan0508/article/details/52624618 [10]https://blog.csdn.net/myarrow/article/details/9701499 [11]《ARM体系结构与编程(第二版)》,杜春雷主编。 |
|