处理器架构是处理器厂商为同一个系列的处理器规定的一个规范。ARM架构是一种精简指令集(RISC)架构,具有以下RISC架构特点:
·
较大的通用寄存器堆。
·
·
load/store体系结构,其中数据处理操作仅对寄存器内容进行操作,而不是直接对内存内容。
·
·
简单寻址模式,所有load/store地址由寄存器内容和指令确定。该体系结构定义了处理单元与内存(包括缓存)的交互,并包括内存地址翻译系统。它还描述了多个处理单元如何相互作用。面积小、性能强和非常低的功耗是ARM体系结构的关键特性。本小节主要以ARMv8-A架构为例来介绍ARM体系结构的基本特性。ARMv8-A体系结构的一个重要特性是向后兼容,可以支持诸多标准和应用场景下的最优设计。ARMv8-A架构支持64bit的执行模式(AArch64)和32bit的执行模式(AArch32),这一模式兼容之前的ARM架构。两种执行状态都支持SIMD和浮点指令。
·
一、AMRv8架构概要
ARM体系结构自推出以来已经有了显著的发展,并且ARM还在继续开发它。到目前为止,已经有八个主要版本,由版本号1到8表示。其中前三个版本现在已经过时了。
通用名称AArch64和AArch32描述了64位和32位执行状态。AArch64是64位执行状态,意味着地址保存在64位寄存器中,并且基本指令集可以使用64位寄存器进行处理。AArch64支持A64指令集。AArch32是32位执行状态,这意味着地址保存在32位寄存器中,并且基本指令集使用32位寄存器进行处理。AArch32支持T32和A32指令集。
ARM支持三种架构配置:
·
A系列,面向应用场景的架构(Application Profile)。该系列支持基于内存管理单元(MMU)的虚拟内存系统体系结构(VMSA)。它支持A64、A32和T32指令集。
·
·
R系列,面向实时场景的架构配置。该系列支持基于内存保护单元(MPU)的受保护内存系统体系结构(PMSA)。它支持A32和T32指令集。
·
·
M系列,面向微处理器的架构。该系列实现了一个为低延迟中断处理而设计的程序员模型(programmers’ model),该模型具有寄存器硬件堆栈和对中断处理程序的高级语言支持。它支持T32指令集的变种。
·
(注:内存保护单元(MPU)是ARM中配备的有效保护系统资源的一种硬件,提供了内存区域保护功能。)
·
二、ARMv8-A指令集
在ARMv8-A中,可能的指令集取决于执行状态:
1.
AArch64:AArch64 state只支持A64指令集。这是一个固定长度的指令集,使用32位指令编码。
2.
3.
Arch32:AArch32 state支持以下指令集:
4.
·
A32:这是一个固定长度的指令集,使用32位指令编码。它是与ARMv7 ARM指令集兼容。
·
·
T32:这是一个可变长度指令集,它同时使用16位和32位指令编码。它与ARMv7 Thumb®指令集兼容。
·
ARM指令的基本格式如下[2]:
<Opcode>{<Cond>}<S><Rd>,<Rn> {,<Opcode2>}
其中各个部分的含义为:
·
Opcode:操作码,也就是助记符,说明指令需要执行的操作类型;
·
·
Cond:指令执行条件码;
·
·
S:条件码设置项,决定本次指令执行是否影响PSTATE寄存器相应状态位值;
·
·
Rd/Xt:目标寄存器,A32指令可以选择R0-R14,T32指令大部分只能选择RO-R7,A64指令可以选择X0-X30;
·
·
Rn/Xn:第一个操作数的寄存器,和Rd一样,不同指令有不同要求;
·
·
Opcode2:第二个操作数,可以是立即数,寄存器Rm和寄存器移位方式(Rm,#shit);
·
ARMv8-A指令集的条件码如下图所示:
下面以A64指令集为例简要介绍ARMv8-A的指令体系。A64指令集中的指令主要分为控制指令、访存指令和计算指令。控制指令主要包括有条件分支指令、无条件分支指令、异常产生和返回指令、系统寄存器指令、系统指令、提示指令、同步指令和清除独占访问标志指令。访存指令主要有Load指令和Store指令,这两种指令有许多变种。计算指令包含算数指令、逻辑指令、MOVE指令、移位指令、位扩展指令和SIMD指令等等。以下列出了一些常用的控制指令的名称与用途。
1. 控制指令:
·
条件分支指令:
·
·
无条件分支指令:
·
·
使用寄存器的无条件分支指令:
·
·
异常产生指令:
·
·
异常返回指令:
·
·
系统寄存器指令:
·
·
同步指令和独占状态清除指令:
·
例如:
2. 访存指令:
ARMv8访存指令支持以下寻址模式:
·
基址加上无符号立即数的寻址和基址加上有符号立即数的寻址;
·
·
基址加上寄存器偏移值;
·
·
基址加上扩展的寄存器偏移;
·
·
pre-index模式;
·
·
post-index模式;
·
·
PC相对寻址模式。
·
具体情形见下表:
其中对于A64指令集来说,64bit的基址来自通用寄存器X0-X30或来自栈指针SP,立即数或寄存器偏移值则是可选的,对寻址方式的解释如下:
·
寄存器偏移寻址是指来自64bit基址寄存器的地址加上一个偏移值;
·
·
Pre-indexed模式是指寻址地址是64bit基址加上一个偏移值,这个计算和将会写入基址寄存器;
·
·
Post-indexed模式是指寻址地址是64bit的基址,但之后基址和偏移值的和将会写入基址寄存器;由此可见pre-indexed和post-indexed的区别在于使用的地址是先加上偏移值再使用还是先使用再加上偏移值;
·
·
PC相对寻址是指寻址地址是这条指令64bit的PC值加上一个19bit的有符号字偏移,这个地址在当前指令的PC值的 ±1MB范围内并且是4byte对齐的。使用PC相对寻址所load的数据大小至少为32bit并且只能用来预取指令,且PC值不能被其他寻址方式使用。
·
·
一个立即数偏移可以为有符号的,也可以为无符号的,可以为scaled也可以为unscaled。当一个立即数偏移是scaled的时候,它被编码为传输数据大小的整数倍。虽然汇编程序总是使用byte对齐的偏移,但汇编器或反汇编器会做必要的转换工作,因此可用的byte偏移值取决于load/store指令类型和数据传输的大小。
·
下面列出了一些load/store指令:
例如Load寄存器指令:
上表中指令的寻址方式有:
·
基址加上12bit无符号scaled立即数偏移寻址;
·
·
基址加上9bit有符号unscaled立即数偏移寻址;
·
·
基址加上64bit寄存器偏移,可选为scaled;
·
·
基址加上32bit可拓展寄存器偏移,可选为scaled;
·
·
有unscaled9bit有符号立即数偏移的pre-indexed模式;
·
·
有unscaled9bit有符号立即数偏移的post-indexed模式;
·
·
Load至少32bit数据的PC相对寻址模式。
·
如果被load或store的指令的寻址模式会修改基址寄存器的内容,且被load/store寄存器恰好的是基址所在的寄存器,那么硬件的行为可能不确定。
3.计算指令:
在操作系统汇编语言中使用的计算指令主要是一些简单的算数计算指令,用于对寄存器的move操作和对地址的计算操作,一般计算指令既可以使用立即数作为操作数,也可以使用寄存器中的数作为操作数。下面简单列举了一些算数指令:
使用立即数的简单算数指令:
例如:
使用寄存器的逻辑操作指令:
例如:
其中:
寄存器移位指令:
例如: