我对指令集有点困惑。有Thumb、ARM和Thumb 2。从我所看到的,Thumb指令都是16位的,但在ARMv7M用户手册(第六页)中提到了Thumb 16位和Thumb 32位指令。
现在我必须克服这种困惑。据说Thumb 2支持16位和32位指令。那么ARMv7M是否实际上支持Thumb 2指令而不仅仅是Thumb呢?
还有一件事。我可以说Thumb(32位)和ARM指令(也都是32位)是相同的吗?
我对指令集有点困惑。有Thumb、ARM和Thumb 2。从我所看到的,Thumb指令都是16位的,但在ARMv7M用户手册(第六页)中提到了Thumb 16位和Thumb 32位指令。
现在我必须克服这种困惑。据说Thumb 2支持16位和32位指令。那么ARMv7M是否实际上支持Thumb 2指令而不仅仅是Thumb呢?
还有一件事。我可以说Thumb(32位)和ARM指令(也都是32位)是相同的吗?
哦,ARM和他们愚蠢的命名...
这是一个常见的误解,但正式来说并不存在所谓的“Thumb-2指令集”。
忽略ARMv8(其中一切都被重新命名,AArch64使事情变得复杂),从ARMv4T到ARMv7-A,有两个指令集:ARM和Thumb。它们都是“32位”的,因为它们在32位宽度的寄存器中处理最多32位宽度的数据和32位地址。实际上,在它们重叠的地方,它们代表完全相同的指令 - 只是指令编码不同,CPU有效地具有两个不同的解码前端,可以在其管道中切换。为了清晰起见,我现在故意避免使用“32位”和“16位”这些术语...
ARM指令具有固定宽度的4字节编码,需要4字节对齐。Thumb指令具有可变长度(2或4字节,现在称为“narrow”和“wide”)的编码,需要2字节对齐 - 大多数指令具有2字节编码,但bl
和blx
总是具有4字节编码*。真正令人困惑的部分出现在ARMv6T2中,它引入了“Thumb-2技术”。 Thumb-2不仅将更多指令(大多数采用4字节编码)添加到Thumb中,使其几乎与ARM相当,而且还扩展了执行状态,以允许对大多数Thumb指令进行条件执行,并最终引入了全新的汇编语法(UAL,“统一汇编语言”),取代了先前分别使用的ARM和Thumb语法,并允许编写一次代码,无需修改即可组装为任一指令集。
Cortex-M架构只实现Thumb指令集 - ARMv7-M(Cortex-M3/M4/M7)支持大多数“Thumb-2技术”,包括条件执行和VFP指令的编码,而ARMv6-M(Cortex-M0/M0 +)仅使用少量的4字节系统指令形式的Thumb-2。
因此,新的4字节编码(以及在ARMv7修订版中后来添加的编码)仍然是Thumb指令。它们的“Thumb-2”方面在于它们可以具有4字节编码,并且它们(大多数情况下)可以通过it
有条件地执行。我认为,它们的助记符仅在UAL中定义。bl
(或blx
)实际上是一个复杂的实现细节,因为它们是否作为4字节指令或一对2字节指令执行是一个问题。体系结构定义是后者,但由于它们只能按顺序作为一对执行,因此出于性能原因将它们融合成单个指令(除了能够在中断中断开它们之外),并不会有太多损失。ARMv6T2重新定义了事物,以便基于融合的单指令执行。-mthumb-interwork
是否允许将Thumb16与Thumb32或Thumb16和Thumb32与ARM结合使用?目前,我正在使用-mthumb
参数进行汇编,并在源文件中使用.syntax unified
以便汇编器允许使用Thumb16和Thumb32编码。但是,我可以从我的源文件中删除.syntax unified
并在汇编时使用-mthumb-interwork
参数吗?文档对此并不十分清楚... - 71GAarmv7e-m
。 - ConsistentProgrammerThumb: 16位指令集。
ARM: 32位指令集,因此具有更灵活的指令和较少的代码密度。
Thumb2 (混合16/32位): 是一种介于 ARM 和 thumb(16)之间的折衷方案(将它们混合使用),以获得ARM性能/灵活性和Thumb指令密度。因此,Thumb2指令既可以是带有32位宽指令的ARM(仅为子集),也可以是带有16位宽指令的Thumb指令。
对我来说,Cortex M3具有4字节指令,但却不能执行ARM指令,或者某些能够使用2字节和4字节操作码的CPU也可以执行ARM指令,这让我感到困惑。所以我读了一本有关Arm的书,现在稍微理解多了一点,但是命名和重叠部分仍然让我感到困惑。我认为先比较几个CPU的功能和重叠部分,然后再谈论ISA会很有趣。
比较一下几个CPU及其功能和重叠部分:
Cortex M0/M0+/M1/M23 是 Thumb(Thumb-1)指令集,可以执行 2-byte 的 Opcode。然而,一些指令如 mrs、msr、bl、dmb、dsb、isb 等是 Thumb-2 指令并需要 4-byte。Cortex M0/M0+/M1 的 ARMv6,而 Cortex M23 是 ARMv8。Thumb-1 指令在 ARMv7 中得到了扩展,因此可以说 ARMv8 Cortext M23 支持比 ARMv6 Cortex M0/M0+ 更完整的 Thumb-1(除 it 指令外),后者只支持 ISA 的子集(特别缺少 it、cbz 和 cbnz 指令)。我可能错了(如果不正确请纠正我),但注意到一个有趣的事情,那就是我所看到的仅支持 Thumb-1 的 CPU 都已经支持 Thumb-2,我不知道是否存在仅支持 Thumb-1 并支持 100% Thumb-1 的 CPU。我认为这是因为 it 被视为 Thumb-2 Opcode,它是 2-byte,实质上被添加到 Thumb-1。在 Thumb-1 CPU 上,4-byte Opcode 可以被视为两个 2-byte 表示 4-byte Opcode。Cortex M3/M4/M7/M33/M35P/M55 可以执行 2-byte 和 4-byte Opcode,都是 Thumb-1 和 Thumb-2,并支持全套 ISAs。2-byte 和 4-byte Opcode 混合得更均匀,而 Cortex M0/M0+/M1/M23 更倾向于大部分时间使用 2-byte Opcode。Cortex M3/M4/M7 是 ARMv7,而 Cortex M33/M35P/M55 是 ARMv8。
Cortex A/R 可接受 ARM 和 Thumb Opcode,因此有 2-byte 和 4-byte。要切换模式,需要将 PC 偏移一个字节(强制不对齐),例如可以使用 bx 分支指令来实现这一点,它设置 CPSR 的 T 位并根据地址的最低位切换模式。例如,在调用子例程时,PC(及其模式)被保存,然后在子例程内可以切换到 Thumb 模式,但在从 Thumb 模式返回时,它将恢复 PC(及其 T 位)并切换回调用者所在的模式(ARM 或 Thumb 模式),没有任何问题。
ARM7 仅支持 ARMv3 的 4-byte ISA。
ARM7T 支持 Thumb-1 和 ARM ISAs(2-byte 和 4-byte)。
ARM11(ARMv6、ARMv6T2、ARMv6Z、ARMv6K)支持 Thumb-1、Thumb-2 和 ARM ISAs。
我参考的书中提到,在ARMv7 及更高版本架构中,为了获得更好的性能,从Von Neumann(数据和指令共享一个总线)切换到Harvard(专用总线)。然而,“及更高版本”这个绝对术语并不准确,因为ARMv8是更高版本,但ARMv8 Cortex M23是Von Neumann。
ISA(指令集架构)包括:
ARM有16个寄存器(R0-R12, SP, LR, PC),只有4字节的操作码,ISA有不同的修订版本,但它们只是4字节的操作码。综上所述,一些 Arm CPU 可以执行以下操作:
该信息的参考来源:《ARM汇编语言编程与体系结构》Muhammad Ali Mazidi等人,2016年。该书在公司名称从 ARM 更名为 Arm 之前编写,因此有时会混淆引用了公司 Arm 还是 ARM ISA。
it
条件指令
系统级别
Thumb-2还添加了指令以访问协处理器并在Thumb-2模式下处理异常。早期版本的Thumb/Thumb-2不允许一些系统级概念,因此这些CPU需要ARM32。这些对Thumb-2 ISA的增加使Cortex-M变体成为可能。cortex-m
Cortex CPU(ARMv7+)中的Thumb-2操作码比传统的32位ARM操作码编码更紧凑。它们将执行速度更快(除非某些极端情况),并且代码密度更小。从2004年起,所有的ARM CPU都支持这个Thumb-2变体。真的没有必要生成传统的32位ARM二进制代码。只有在2005年左右之前设计的CPU才需要这个功能。
使用原始的'Thumb'的CPU非常受限,因为所有操作码只有八个寄存器可用。没有支持应用程序开发人员动态执行的手机或商业产品将使用'Thumb' ISA。只有深度嵌入式设备(可能用于遗留产品或升级)会使用此ISA。Thumb-2共享编码,并可以运行Thumb二进制文件,但这主要是一个历史注释。条件执行和混合16/32位ISA使得Thumb2能够取代ARM32操作码。
ARM/Thumb的特点是模式位。您必须确定CPU以了解是否适用Thumb/Thumb-2。Cortex-M CPU仅支持Thumb2操作码。它们不支持传统的ARM32操作码。Cortex-A CPU支持两种模式,以便运行遗留的ARM32二进制文件(或由误导的开发人员生成的文件)。
从2023年的ARM开始,
T32指令集,在Armv8之前的架构中被称为Thumb,是一种混合的32位和16位长度指令集,为设计者提供了出色的代码密度,以实现最小的系统内存大小和成本。
随着ARM试图重新定义术语,程序员应该注意到历史上的命名,因为其他第三方工具、操作系统配置、SOC文档等可能对“Thumb”和“Thumb-2”这两个词有不同的含义。即使这段文字也是一个误称,因为混合的32/16位ISA被称为“Thumb-2”并引入使用。