【问题标题】:What is the difference between the ARM, Thumb and Thumb 2 instruction encodings?ARM、Thumb 和 Thumb 2 指令编码有什么区别?
【发布时间】:2015-02-23 08:53:40
【问题描述】:

我对指令集有点困惑。有 Thumb、ARM 和 Thumb 2。据我阅读,Thumb 指令都是 16 位的,但在 ARMv7M 用户手册(第 vi 页)中有 Thumb 16 位和 Thumb 32 位指令提及。

现在我必须克服这种困惑。据说 Thumb 2 支持 16 位和 32 位指令。那么 ARMv7M 实际上是否支持 Thumb 2 指令而不仅仅是 Thumb?

还有一件事。我能说 Thumb(32 位)和 ARM 指令一样,都是 32 位吗?

【问题讨论】:

  • 我能说 Thumb(32 位)与 32 位的 ARM 指令相同吗? 答案是否定的。 Thumb2 是 32/16 位的混合体,其编码与直接 ARM 32 位不同。

标签: arm thumb


【解决方案1】:

哦,ARM 和他们愚蠢的命名...

这是一个常见的误解,但官方并没有“Thumb-2 指令集”之类的东西。

忽略 ARMv8(所有内容都被重命名并且 AArch64 使事情变得复杂),从 ARMv4T 到 ARMv7-A 有两个指令集:ARM 和 Thumb。从某种意义上说,它们都是“32 位”,它们在具有 32 位地址的 32 位宽寄存器中操作高达 32 位宽的数据。事实上,在它们重叠的地方,它们代表完全相同的指令——只是指令编码不同,CPU实际上只有两个不同的解码前端到它的流水线,它可以在它们之间切换。为清楚起见,我现在将故意避免使用“32 位”和“16 位”这两个术语...

ARM 指令具有固定宽度的 4 字节编码,需要 4 字节对齐。 Thumb 指令具有可变长度(2 或 4 字节,现在称为“窄”和“宽”)编码,需要 2 字节对齐 - 大多数指令具有 2 字节编码,但 blblx 一直有4 字节编码*。真正令人困惑的是 ARMv6T2,它引入了“Thumb-2 技术”。 Thumb-2 不仅包括向 Thumb 添加更多指令(主要使用 4 字节编码)以使其几乎与 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 中定义)。

* 在 ARMv6T2 之前,bl(或blx)是作为 4 字节指令执行还是作为一对 2 字节指令执行,实际上是一个复杂的实现细节。架构定义是后者,但由于它们只能作为一对按顺序执行,因此出于性能原因将它们融合到一条指令中几乎没有什么损失(除了中途中断的能力)。 ARMv6T2 只是在融合的单指令执行方面重新定义了事物

【讨论】:

  • 同样,在 Thumb2 中,随着时间的推移添加了一些操作码。所以并不是所有的 Thumb2 都是一样的。从主 CPU 的角度来看,没有称为 Thumb2 的模式(我认为这就是您所说的“官方”?);当然 ARM 控股公司似乎认为 Thumb2 是混合 16/32 位编码,但除此之外它是模糊的。
  • 谢谢!这为我解决了问题。无论如何,两天前我参加了在纽伦堡举行的嵌入式世界博览会,真是太棒了。我得到了很多关于 ARM 的信息。惊人的事件!
  • 那么参数-mthumb-interwork 实际上是否允许将 (a) Thumb16 与 Thumb32 或 (b) Thumb16&32 与 ARM 结合?目前我正在使用-mthumb 参数进行汇编,在源文件中我使用.syntax unified 以使汇编程序减少对Thumb16 和Thumb32 编码的使用。但是我可以从源文件中删除.syntax unified 并在汇编时使用-mthumb-interwork 参数吗?文档对此并不十分清楚......
  • Cortex M4 是armv7e-m
  • 我知道这是一个老答案,但我不同意“没有 Thumb-2 指令集之类的东西”的说法,因为 ARM 的官网有一个标题为 "The Thumb-2 instruction set"
【解决方案2】:

除了Notlikethat's answer,正如它所暗示的那样,ARMv8 引入了一些新术语来试图减少混淆(当然添加更多新术语):

有 32 位执行状态 (AArch32) 和 64 位执行状态 (AArch64)。

32 位执行状态支持两种不同的指令集:T32(“Thumb”)和 A32(“ARM”)。 64位执行状态只支持一种指令集——A64。

所有 A64 和所有 A32 一样,指令大小为 32 位(4 字节),需要 4 字节对齐。

许多/大多数 A64 指令可以在 32 位和 64 位寄存器上运行(或者可以说是同一底层 64 位寄存器的 32 位或 64 位视图)。

所有实现 AArch32 的 ARMv8 处理器(与所有 ARMv7 处理器一样)都支持 T32 指令集中的 Thumb-2 指令。

并非所有 ARMv8-A 处理器都实现 AAarch32,有些不实现 AArch64。一些处理器同时支持两者,但仅支持较低异常级别的 AArch32。

【讨论】:

  • 我没有足够的声誉直接评论 unixsmurf 的答案,但它需要调整。 ARMv8A 处理器内核可以选择根本不实现 aarch32 状态。这样的内核不支持 T32 和 A32 指令。如果给定的处理器内核确实实现了 aarch32 状态(如 ARM ltds 的 cortex-A53、A57 和 A72),那么它也支持该状态下的 Thumb-2 模式。
  • @wmills:你刚刚直接评论了它:)你可以添加你自己的澄清作为答案。
  • @wmills 确实,既然写了这个答案,some of them don't support AArch64 either ;)
【解决方案3】:

Thumb:16 位指令集

ARM:32 位宽指令集,因此指令更灵活,代码密度更低

Thumb2(混合 16/32 位):以某种方式在 ARMthumb(16) 之间妥协(混合它们),以获得ARM 的性能/灵活性和 Thumb 的指令密度。因此,Thumb2 指令可以是 32 位宽指令的 ARM(只是其子集),也可以是 16 位宽的 Thumb 指令。

【讨论】:

    【解决方案4】:

    请参考https://developer.arm.com/documentation/ddi0344/c/programmer-s-model/thumb-2-instruction-set 它详细解释了 Thumb2 架构的增强。同样也隐含地涵盖了 ARM、Thumb 和 Thumb2 指令集的描述。

    【讨论】:

      【解决方案5】:

      让我感到困惑的是 Cortex M3 具有 4 字节指令,但不执行 ARM 指令。或者 CPU 能够具有 2 字节和 4 字节操作码,但也能够执行 ARM 指令。所以我读了一本关于 Arm 的书,现在我对它的理解稍微好一些。尽管如此,命名和重叠仍然让我感到困惑。我想先比较几个 CPU 然后再讨论 ISA 会很有趣。

      比较几个 CPU 以及它们可以做什么以及它们如何重叠:

      • Cortex M0/M0+/M1/M23 被认为是 Thumb (Thumb-1) 并且可以执行 2-byte 操作码,这些操作码是与其他人相比有限。但是,mrsmsrbldmbdsbisb 等一些指令来自 Thumb-2,并且是 4 字节。 Cortex M0/M0+/M1 是 ARMv6,而 Cortex M23 是 ARMv8。 Thumb-1 指令在 ARMv7 中进行了扩展,因此可以说 ARMv8 Cortex M23 支持更完整的 Thumb-1(it 指令除外),而 ARMv6 Cortex M0/M0+ 只是 ISA 的一个子集(它们特别缺少@ 987654328@、cbzcbnz 指令)。我可能是错的(如果这不对,请纠正我),但注意到一些有趣的事情,只有我看到的完全支持 Thumb-1 的 CPU 是已经支持 Thumb-2 的 CPU,我不知道只有 Thumb-1 CPU 支持 100% 的 Thumb-1。我认为这是因为 it 可以看作是 2 字节的 Thumb-2 操作码,本质上是添加到 Thumb-1 中的。在 Thumb-1 CPU 上,4 字节操作码可以被视为两个 2 字节来表示 4 字节操作码。

      • Cortex M3/M4/M7/M33/M35P/M55可以执行2字节和4字节操作码,都是Thumb-1和Thumb -2 并支持全套 ISA。 2 字节和 4 字节操作码混合更均匀,而上面的 Cortex M0/M0+/M1/M23 大部分时间都偏向于使用 2 字节操作码。 Cortex M3/M4/M7 是 ARMv7,而 Cortex M33/M35P/M55 是 ARMv8。

      • Cortex A/R 可以同时接受 ARM 和 Thumb 操作码,因此具有 2 字节和 4 字节。要在模式之间切换,PC 需要偏移一个字节(强制未对齐),这可以通过例如分支指令bx 来完成,该指令设置CPSRT 位并根据地址的最低位。这很好用,例如,当调用子程序时,PC(及其模式)被保存,然后在子程序中它可以切换到 Thumb 模式,但是当从 Thumb 模式返回时,它将恢复 PC(及其 T 位)和毫无问题地切换回调用方(ARM 或 Thumb 模式)。

      • ARM7 仅支持 ARMv3 4-byte ISA

      • ARM7T 支持 Thumb-1 和 ARM ISA(2 字节和 4 字节)

      • ARM11(ARMv6、ARMv6T2、ARMv6Z、ARMv6K)支持 Thumb-1、Thumb-2 和 ARM ISA

      我参考的书指出,在 ARMv7 及更新版本中,架构从冯诺依曼(数据和指令共享总线)切换到哈佛(专用总线)以获得更好的性能。然而,绝对术语“和更新”是不正确的,因为 ARMv8 更新,但 ARMv8 Cortex M23 是冯诺依曼。

      ISA 是:

      • ARM有16个寄存器(R0-R12、SP、LR、PC),只有4字节的操作码,ISA有修改,但都是4字节的操作码。 p>

      • Thumb(又名 Thumb-1)将 16 个寄存器分为低位(R0-R7)和高位(R8-R12、SP、LR、PC),大多数指令只能访问低位集,而只有一些人可以访问更高的集合。只有 2 字节的操作码。在具有 16 位总线(并且必须分两步执行 32 位字访问)的低端设备上,当它们执行与总线匹配的 2 字节操作码时,它们的性能会更好。命名让我感到困惑,Thumb 可以用作 Thumb-1 和 Thumb-2 的家族术语,或者有时 Thumb 只能用于 Thumb-1。我认为 Thumb-1 不是 Arm 的官方术语,只是我看到人们使用它来区分 ISA 的 Thumb 系列和第一个 Thumb ISA。 ARM 中的指令可以有可选的s 后缀来更新CPSR 寄存器(例如andsorrsmovsaddssubs 指令),而在 Thumb-1 s 始终处于开启状态,它一直保存CPSR 寄存器。在一些较旧的工具链中,不需要隐式 s,但是在统一汇编语言 (UAL) 的努力中,即使没有不使用 s 的选项,现在也需要显式指定 s

      • Thumb-2 是 Thumb 的扩展,可以像 ARM 一样访问所有寄存器,具有 4 字节操作码,与 ARM 相比有一些差异。在程序集中,Thumb-1 2 字节窄操作码和 Thumb-2 4 字节宽操作码可以强制使用 .n.w 后缀(例如 orr.w)。 ARM 和 Thumb-2 操作码格式/编码不同,它们的功能也不同。可以使用指令的条件执行,但只有在 it (if-then) 指令/块被前置时。这可以显式或隐含地完成(并由用户背后的工具链完成)。并且混淆实际上可能很好,因为 Arm(该公司)希望它们相似,很多努力都用于统一汇编语言 (UAL),因此为 ARM 制作的汇编文件可以在 Thumb-2 上编译而无需更改。如果我理解正确,则不能 100% 保证,并且在 ARM 程序集无法编译为 Thumb-2 的情况下可能会出现一些边缘情况,这是另一个不完全正确的绝对陈述。例如,ARM7 bl 指令可以寻址 +-32MB,而在 Cortex M3 上它只能寻址 +-16MB。与 Thumb-1 相比,这种情况要好得多,在 Thumb-1 中,ARM 程序集更有可能被重写为目标 Thumb-1,而 ARM 到 Thumb-2 的重写不太可能发生。另一个区别是数据处理指令。 ARM 和 Thumb-2 都支持 8 位立即数,而 ARM 只能向右旋转位并且只能旋转偶数位,而 Thumb 可以向左旋转以及偶数/奇数位,并且在此之上允许重复的字节模式例如0xXYXYXYXY0x00XY00XY0xXY00XY00。因为移位是旋转的,所以左右移位可以通过“溢出”来实现,向一个方向移动太多以至于实际上是向相反方向移动1 << (32 - n) == 1 >> n

      总之,一些 Arm CPU 可以做到:

      • 只有 4 字节的操作码指令是纯 ARM ISA
      • 2 字节/4 字节 Thumb-1/Thumb-2 ISA,大部分时间专注于使用 2 字节,只有少数 4 字节操作码,这些通常被标记为 Thumb (Thumb-1 ) 2 字节操作码 CPU(少数 4 字节操作码有时不会被提及)
      • 2 字节/4 字节 Thumb-1/Thumb-2 ISA,在 2 字节和 4 字节操作码之间更均匀地混合,通常标记为 Thumb-2
      • 通过在 ARM/Thumb 模式之间切换的 2 字节/4 字节操作码

      此信息的参考:ARM Assembly Language Programming & Architecture Muhammad Ali Mazidi et al 2016。这本书是在公司名称从 ARM 更改为 Arm 之前编写的,因此有时在引用公司 Arm 时会让人感到困惑,而当ARM ISA。

      【讨论】:

      • 我想知道 M4 处理器是否可以像 Thumb2 一样执行 ARM。你的答案是解决我问题的唯一答案。谢谢。
      猜你喜欢
      • 2022-03-07
      • 1970-01-01
      • 1970-01-01
      • 2012-05-25
      • 1970-01-01
      • 2013-03-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多