【问题标题】:What is the difference between the ARM, Thumb and Thumb 2 instruction encodings?ARM、Thumb 和 Thumb 2 指令编码之间有什么区别?
【发布时间】:2022-03-07 16:29:07
【问题描述】:

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

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

还有一件事。我可以说 Thumb(32 位)与同样是 32 位的 ARM 指令相同吗?

【问题讨论】:

  • 我可以说 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-2”方面是他们可以有4 字节编码,并且它们可以(大部分)通过 it 有条件地执行(而且,我想,它们的 menmonics 仅在 UAL 中定义)。

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

【讨论】:

  • 同样,在拇指2,随着时间的推移添加了一些操作码。所以不是所有拇指2是一样的。从主 CPU 的角度来看,没有称为拇指2(我认为这就是你所说的“官方”的意思?);当然 ARM 控股似乎有想法拇指2作为混合的 16/32 位编码,但除此之外它是模糊的。
  • 谢谢!这帮我解决了问题。不管怎样,我两天前参加了在纽伦堡举行的嵌入式世界博览会,那真是太棒了。我得到了很多关于 ARM 的信息。惊人的事件!
  • 那么参数 -mthumb-interwork 实际上允许 (a) Thumb16 与 Thumb32 或 (b) Thumb16&32 与 ARM 的组合吗?目前我正在使用 -mthumb 参数进行汇编,在源文件中我正在使用 .syntax unified 以便汇编器允许使用 Thumb16 和 Thumb32 编码。但是我可以从我的源文件中删除 .syntax unified 并在汇编时使用 -mthumb-interwork 参数吗?文档对此并不完全清楚......
  • 皮质 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。

与所有 A32 一样,所有 A64 指令的大小都是 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】:

拇指: 16 位指令集

手臂: 32 位宽指令集因此更灵活的指令和更低的代码密度

Thumb2(混合 16/32 位): 不知何故之间的妥协手臂大拇指(16)(混合它们),以获得 ARM 的性能/灵活性和 Thumb 的指令密度。因此 Thumb2 指令可以是具有 32 位宽指令的 ARM(仅是其子集)或具有 16 位宽的 Thumb 指令。

【讨论】:

  • 实际上,这是一个很好的简单答案,用于一般理解,因为细节很血腥。 Thumb1 限制了寄存器,这对性能有影响。使用 thumb2,您几乎可以通过压缩指令流获得 ARM32 的所有功能。 Thumb2 的结果是性能更高(更少的指令获取)并且几乎在所有情况下都具有更小的代码大小。
  • Thumb2 32 位指令的编码与其等效的 ARM 模式不同。将 Thumb2 视为包含实际的 ARM 指令可能是一种有用的简化,但如果您查看细节,就会发现差异。 ARM 模式在每条指令中使用 4 位进行预测。 Thumb2 模式使用一个位来表示一条指令是 1 个还是 2 个 16 位块,并且仍然需要一个 it 指令来预测后面的指令。
【解决方案4】:

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

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

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

  • 皮层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。

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

  • ARM7只支持ARMv3 4 字节艾萨

  • ARM7T两者都支持Thumb-1 和 ARMISA(2 字节和 4 字节)

  • ARM11(ARMv6, ARMv6T2, ARMv6Z, ARMv6K) 支持Thumb-1、Thumb-2 和 ARM国际检索协议

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

ISA 是:

  • 手臂有16个寄存器(R0-R12,SP,LR,PC),只有4字节的操作码,ISA有改版,但都是4字节的操作码。

  • 拇指(又名 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 的选项也是如此。

  • 拇指2是 Thumb 的扩展,可以像 ARM 一样访问所有寄存器,具有 4 字节操作码,与 ARM 相比有一些差异。在程序集中,可以使用 .n.w 后缀强制 Thumb-1 2 字节窄操作码和 Thumb-2 4 字节宽操作码(示例 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 相比,这种情况要好得多,其中 ARM 程序集更有可能被重写为目标 Thumb-1,而 ARM 到 Thumb-2 重写的可能性较小。另一个区别是数据处理指令。 ARM 和 Thumb-2 都支持 8 位立即数,而 ARM 只能向右循环位且只能循环偶数位,而 Thumb 可以向左循环并按偶数/奇数位进行循环,最重要的是允许重复字节模式例如 0xXYXYXYXY0x00XY00XY0xXY00XY00。因为移位是旋转的,左右移位可以通过“溢出”来实现,向一个方向移位太多以至于它实际上是向相反方向的移位1 << (32 - n) == 1 >> n

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

  • 只有纯 ARM ISA 的 4 字节操作码指令
  • 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。你的答案是解决我的问题的唯一答案。谢谢你。
【解决方案5】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-25
    • 1970-01-01
    • 2013-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多