指令集架构

ISA

指令集架构(Instruction Set Architecture,ISA)是计算机抽象模型的一部分。它定义了软件如何控制 CPU。CPU执行计算任务时都需要遵从一定的规范,程序在被执行前都需要先翻译为CPU可以理解的语言。这种规范或语言就是指令集。

程序被按照某种指令集的规范翻译为CPU可识别的底层代码的过程叫做编译(compile)。

CISC与RISC

常见的指令集架构大体上可以分为两大类:复杂指令集体系(CISC)和精简指令集体系(RISC)。

复杂指令集最常见的例子是现在绝大多数家用计算机和网络服务器所使用的 AMD64 指令集,除此以外有一定使用量,和有历史意义的复杂指令集还有 IA-32、MC68000、MOS6502、Intel 8051、Intel 8080 等等。复杂指令集其复杂在于指令种类数量巨大,非常多条常用或不常用的功能都会被整合进处理器指令集中。同时复杂指令集系统每条指令的操作数寻址方式复杂,几乎所有指令都可以直接访问内存;相应的指令的机器码编码方式复杂,普遍使用不定长指令等。同时,复杂指令集系统一般没有独立的专用内存访问指令,处理器内所设置的通用寄存器数量也偏少。(例如 IA-32 没有严格意义上的通用整数寄存器,到了 AMD64 也才勉强设置了八个通用整数寄存器。)

精简指令集最常见的例子则是智能设备和嵌入式平台的 ARM 指令集家族。除此以外还有一定使用量,和有历史意义的精简指令集还有龙芯 LoongArch、MIPS、RISC-V、PowerPC、AVR 等等。精简指令集其精简在于指保留最基本最必要的指令,将复杂功能完全交给上层的软件算法和下层的专用外设去解决。同时精简指令集系统指令寻址方式往往非常单一,除了专门的访问内存指令以外,所有指令都只能在寄存器范围内操作,相应的精简指令集系统普遍使用固定长度指令,也会配备相对比较多的通用寄存器。(例如上个世纪的 ARMv4T、MIPS32 就都已经有 29~31 个通用寄存器了,相比于同时期 IA-32 的 0 个。)

不过,实际到了应用层面上,对于高级语言程序来说,对于处理器设计来说,两种指令集架构分类的实际差异已经不大了。Intel 和 AMD 的 AMD64 实现都使用了微代码,而从复杂指令翻译出来的微代码普遍都用了类 RISC 设计。本世纪初的时候还普遍认为复杂指令集处理器速度更快,到了现在精简指令集的苹果 M1 同频率下已经可以吊打英特尔和AMD。

以上所说x86、ARMv8-A、MIPS等都是指令集的代号。指令集可以被扩展,如x86增加64位支持就有了x86_64。厂商开发兼容某种指令集的CPU需要指令集专利持有者授权,典型例子如Intel授权AMD,使后者可以开发兼容x86指令集的CPU。

ARM Base ISAs

Arm ISA 允许开发人员编写符合 Arm 规范的软件和固件,以此实现在任何基于 Arm 的处理器上都可以以同样的方式执行它们。ARM 指令集架构有三种:

A64: A64 指令集是在 Armv8-A 中引入的,以支持 64 位架构。A64 指令集有固定的 32 位指令长度。主要的特性有:

1. Clean decode table based on 5-bit register specifiers.
2. Instruction semantics broadly similar to A32 and T32.
3. 31 general-purpose 64-bit registers accessible at all times.
4. No modal banking of general purpose registers for improved performance and energy.
5. Program counter and stack pointer are not general purpose registers.
6. Dedicated zero register available for most instructions.

A32: A32 指令集有固定的 32 位指令长度,并在 4 字节边界上对齐。A32 指令集就是 Armv6 和 Armv7 架构中我们常说的 ARM 指令集,Armv8 及之后改名 A32 以与 A64 进行区分。 随着 Thumb-2 技术的引入,它的大部分功能都被纳入了 T32 中。
A32 指令主要被用于 A-profile 和 R-profile。

T32: T32 指令集最初是作为 16 位指令的补充集引入的,用于改进的用户代码的代码密度。随着时间的推移,T32 演变成 16 位和 32 位混合长度的指令集。因此,编译器可以在单个指令集中平衡性能和代码大小。
T32 指令集就是在在 Armv6 和 Armv7 架构中被我们所熟知的 Thumb 指令集,Armv8 及之后改名为 T32。 T32 支持所有架构的 profile,并且是 M-profile 架构所支持的唯一指令集。

以上这三种指令集被称为 ARM 基础指令集(ARM Base ISAs),除此之外,ARM 还提供指令集扩展:自定义指令、DSP、浮点等等。其中以我用的最多的浮点来简单说明一下。指令集是架构参考手册中一个重要的章节,详细的介绍可以在对应版本的架构参考手册中找到。

ARCH

架构(Architecture,ARCH)指的是一系列的功能规范。
ARM 架构 指的就是是基于 ARM 指令集架构的一系列功能规范,即 ARM CPU 架构。架构指定了处理器的行为方式。

它包含两部分主要内容:

  1. 一个架构必须基于一套指令集,像arm如内存读写的指令—load和store,指令集的各种功能可以理解为软件。
  2. 一个架构还必须有可以实现指令集功能的硬件,ldr/ldrh/ldrb Rn, [Rm],str/strh/strb Rn, [Rm],这些寄存器就可以理解为硬件。

所以可以将架构看作是硬件和软件之间的契约,描述了软件可以依赖硬件提供哪些功能。大体包含以下内容:

条目

说明

指令集

每条指令的功能;指令如何在内存中表示(它的编码)

寄存器组

有多少寄存器;寄存器的大小;寄存器的功能;寄存器的初始状态

异常模型

不同的权限级别;异常的类型;从异常中获取或返回时会发生什么

内存模型

内存访问是如何排序的;缓存是如何运作的,什么时候以及软件必须如何执行显式维护

调试、跟踪和分析

如何设置和触发断点;跟踪工具可以捕获什么信息,以什么格式捕获

ARCH与ISA

下图为指令集与架构的关系:

指令集架构 accumulator 指令集架构类型有哪些_arm


ARM 架构 可以认为就是个专有名词,是 ARM 制定的一些列功能规范的统称。至今已经有发展了很多版。最初的 ARMv1、ARMv2、……ARMv6,后来的 ARMv7、ARMv8;最新的 ARMv9。

ARM架构及其家族系列

家族系列即下文要讲的微架构:

指令集架构 accumulator 指令集架构类型有哪些_寄存器_02


每一代 ARM 架构 都有一个专门的文档(架构参考手册)来介绍该架构的具体细节。需要注意的是,架构参考手册是根据 Profile 来分开的,并不是一个统一的文档。例如,《Armv8-M Architecture Reference Manual》、《Armv8-A Architecture Reference Manual》等等。