ARM体系结构简介

一、概述

从1995年,ARMV4(主要对应ARM7 family)开始到现在ARM RISC体系结构到现在已经演化了20多年。从设计一开始ARM就关注到了低功耗。到2011年,所有的ARM-Cotex family都被设计成使用ARMV7架构。
在这里插入图片描述
ARM7:采用ARMV4架构

ARM9:ARMV4的变体

ARM11:ARMV4的变体

Cotex-A8:为了匹配不同的市场,ARMV7从Cotex-A8开始被划分为三种属性:Application-Profile、RealTime-Profile、Microcontroller-Profile

Cotex-A9:引入了多核

Cotex-A5:引入低功耗、低成本的网络互联

Cotex-A7:引入了出色的能效管理,可以延长手机的续航时间

Cotex-A15:引入了很多可选的扩展,如LPAE、虚拟化

为何要引入ARMV8?

(1)考虑到ARMV7被市场广泛接受,以及形成的成熟的生态,因此后续的体系结构升级需要做到向后兼容;

(2)另外要让厂商能够愿意将软件系统迁移到新的体系结构,新的体系结构一定要有原体系结构不具有的优势;

(3)为了解决旧有架构遗留的问题,提供一种更加清晰的架构,同时考虑到将来的发展趋势,采用一种全新的架构来实现。

基于如上三点,确立了ARMV8的关键功能属性。

在这里插入图片描述

ARMV8目前只定义了Application profile

ARMV8定义了48bit符号虚拟地址和达到48bit物理地址

ARMV8采用了新的指令集A64

ARMV8兼容ARMV7的指令

A32和A64的转换只能发生在异常级别转换时

下面我们将会将重点投入到ARMV7上。

二、ARM,Thumb,Thumb-2 和 Thumb-2EE 指令集

ARM 指令集是一组提供一整套运算的 32 位指令。

ARMv4T 及更高版本定义了一个名为 Thumb 指令集的 16 位指令集。 32 位 ARM
指令的多数功能都可用,但有些运算需要与其他指令结合使用。 Thumb 指令集
提供了更好的代码密度,但会损害性能。

ARMv6T2 定义了 Thumb-2,它与 Thumb 指令集相比有了重大改进。 Thumb-2
提供了几乎与 ARM 指令集完全相同的功能。 它同时具有 16 位和 32 位指令,并
可同时实现类似于 ARM 的性能以及类似于 Thumb 的代码密度。

ARMv7 定义了 Thumb-2 执行环境 (Thumb-2EE)。 Thumb-2EE 指令集基于
Thumb-2,但与后者相比有一些变更和补充,从而可以更好地适用于动态生成
的代码,即在即将执行前或在执行期间在设备上编译的代码。

三、ARM,Thumb 和 ThumbEE 状态

正执行 ARM 指令的处理器在 ARM 状态 下工作。 正执行 Thumb 指令的处理器在
Thumb 状态 下工作。 正执行 ThumbEE 指令的处理器在 ThumbEE 状态 下工作。
处理器也可以在称为 Jazelle 状态 的另一种状态下工作。

在其中一种状态下工作的处理器不能执行不同指令集内的指令。 例如,处于
ARM 状态下的处理器不能执行 Thumb 指令,而处于 Thumb 状态下的处理器不
能执行 ARM 指令。 您必须确保处理器始终不会收到与当前状态不相符的指令
集的指令。

大多数 ARM 处理器始终在 ARM 状态下开始执行代码。 但也有些处理器只能执
行 Thumb 代码,或者可以配置为在 Thumb 状态下开始执行代码。

更改状态

每种指令集都包含用于更改处理器状态的指令。

要在 ARM 和 Thumb 状态之间进行转换,必须切换汇编器模式,以便使用 ARM
或 THUMB 指令生成正确的操作码。 若要生成 Thumb-2EE 代码,请使用 THUMBX。

四、寄存器

ARM 处理器拥有 37 个寄存器。 这些寄存器按部分重叠组方式加以排列。 每个
处理器模式都有一个不同的寄存器组。 编组的寄存器为处理处理器异常和特权
操作提供了快速的上下文切换。

提供了下列寄存器:

• 三十个 32 位通用寄存器

• 程序计数器 (pc)

• 应用程序状态寄存器 (APSR)

• 保存的程序状态寄存器 (SPSR)

4.1 三十个 32 位通用寄存器

在任一时刻都存在十五个通用寄存器,这取决于当前的处理器模式。 它们分别
是 r0-r12、sp、lr。

sp (或 r13)是堆栈指针。 C 和 C++ 编译器始终将 sp 用作堆栈指针。 在
Thumb-2 中, sp 被严格定义为堆栈指针,因此许多对堆栈操作无用而又使用了
sp 的指令会产生不可预测的结果。 建议您不要将 sp 用作通用寄存器。

在用户模式下, lr (或 r14)用作链接寄存器 (lr),用于存储调用子例程时的返回地址。 如果返回地址存储在堆栈上,则也可将 r14 用作通用寄存器。

在异常处理模式下, lr 存放异常的返回地址;如果在一个异常内执行了子例程
调用,则 lr 存放子例程的返回地址。如果返回地址存储在堆栈上,则可将 lr 用
作通用寄存器。

4.2 程序计数器 (pc)

程序计数器被当作 pc (或 r15)进行访问。 在 ARM 状态下,它对每个指令以一
个字(四字节)为增量递增,在 Thumb 状态下则按所执行指令的大小递增。 跳
转指令将目标地址加载到 pc 中。 您也可以使用数据操作指令来直接加载 PC。
例如,若要从子例程返回,可以使用以下指令将链接寄存器复制到 PC 中:

MOV pc,lr

在执行期间, pc 不包含当前执行的指令的地址。 在 ARM 状态下,当前执行的
指令的地址通常是 pc–8,而在 Thumb 状态下通常是 pc–4。

4.3 应用程序状态寄存器 (APSR)

APSR 存放算术逻辑单元 (ALU) 状态标记的副本。 这些标记用于确定是否执行
条件指令。

在 ARMv5TE 和 ARMv6 及更高版本中, APSR 还存放 Q 标记。

在 ARMv6 及更高版本中,APSR 还存放 GE 标记。

可在所有模式下使用 MSR 和 MRS 指令访问这些标记。

4.4 当前程序状态寄存器 (CPSR)

CPSR 存放下列内容:

• APSR 标记

• 当前处理器模式

• 中断禁用标记

• 当前处理器状态(ARM、Thumb、ThumbEE 或 Jazelle)

• IT 块的执行状态位

执行状态位控制 IT 块中的条件执行,并且仅可用于
ARMv6T2 及更高版本。

在所有模式下均可访问的标记只有 APSR 标记。 对于 CPSR 的其余位,只能在
特权模式下使用 MSR 和 MRS 指令访问它们。

4.5 保存的程序状态寄存器 (SPSR)

当发生异常时,使用 SPSR 来存储 CPSR。 在每种异常处理模式下,可访问一个
SPSR。 用户模式和系统模式没有 SPSR,因为二者不是异常处理模式。

五、指令集概述

所有 ARM 指令的长度都是 32 位。 这些指令是按字对齐方式存储的,因此在 ARM 状态下,指令地址的两个最低有效位始终为零。

Thumb、Thumb-2 和 Thumb-2EE 指令的长度是 16 位或 32 位。 这些指令按半字对齐方式存储。 其中有些指令使用最低有效位来确定跳转到的目标代码是 Thumb 代码还是 ARM 代码。

在引入 Thumb-2 之前,Thumb 指令集只是 ARM 指令集功能的一个限定的子集。几乎所有 Thumb 指令都是 16 位。 Thumb-2 指令集的功能与 ARM 指令集的功能几乎相同。

ARM 和 Thumb 指令可划分为多个功能组:

• 跳转指令

• 数据处理指令

• 寄存器加载和存储指令

• 多个寄存器加载和存储指令

• 状态寄存器访问指令

• 协处理器指令

六、指令功能

6.1 条件执行

可以根据 APSR 中 ALU 状态标记的值,有条件地执行几乎所有 ARM 指令。虽然不需要使用跳转来跳过条件指令,但当一系列指令依赖于相同的条件时,这样做的效果会更好。

在没有 Thumb-2 的处理器上的 Thumb 状态下,条件跳转是提供条件执行的唯一机制。大多数数据处理指令会更新 ALU 标记。通常不能指定指令是否更新 ALU 标记的状态。

Thumb-2 通过使用 IT (If-Then) 指令和同样的 ALU 标记为条件执行提供了另一种机制。IT 是一个 16 位指令,最多可为后面的四个指令提供条件执行。此外,还有其他几个指令为条件执行提供了其他机制。

在 ARM 和 Thumb-2 代码中,可以指定数据处理指令是否更新 ALU 标记。可以使用一个指令所设置的标记来控制其他指令的执行,即使在它们之间有很多非标记设置指令也是如此。

6.2 寄存器访问

在 ARM 状态下,所有指令都可访问 r0 到 r14,并且大多数指令也可访问 r15(pc)。 MRS 和 MSR 指令可将状态寄存器的内容移到通用寄存器中,在通用寄存器中可以用普通的数据处理操作来处理这些内容。

Thumb-2 处理器上的 Thumb 状态提供了同样的功能,但会禁止一些对 r13 和 r15 的无用访问。

在没有 Thumb-2 的处理器上的 Thumb 状态下,大多数指令只能访问 r0 到 r7。 只有少数指令能够访问 r8 到 r15。 寄存器 r0 到 r7 称为低位寄存器。 寄存器 r8 到 r15 称为高位寄存器。

6.3 访问内联的滚筒式移位器

ARM 算术逻辑单元具有一个 32 位滚筒式移位器,可执行移位和循环操作。 对于所有 ARM 和 Thumb-2 数据处理指令和单寄存器数据传送指令的第二个操作数,可以在执行数据处理或数据传送之前,将其作为指令的一部分执行移位操作。

此操作支持(但不限于):

• 比例寻址

• 乘以一个常数

• 构造常数

Thumb-2 指令与 ARM 指令对滚筒式移位器的访问方式几乎相同。

16 位 Thumb 指令集只允许使用单独的指令来访问滚筒式移位器。