我对指令集感到有点困惑。有Thumb,ARM和Thumb 2.从我所看到的Thumb指令都是16位但在 ARMv7M用户手册(第vi页)内有Thumb 16位和Thumb 32位指令提及。
现在我必须克服这种困惑。据说Thumb 2支持16位和32位指令。那么ARMv7M实际上支持Thumb 2指令而不仅仅是Thumb吗?
还有一件事。我可以说Thumb(32位)与ARM指令相同,它们都是32位吗?
答案 0 :(得分:51)
哦,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字节编码,但bl
和{{1}总是有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”方面是它们可以拥有< / em> 4字节编码,并且它们(通常)可以通过blx
有条件地执行(并且,我认为,他们的menmonics仅在UAL中定义)。
*在ARMv6T2之前,关于it
(或bl
)是作为4字节指令还是作为一对2字节指令执行,实际上是一个复杂的实现细节。架构定义是后者,但由于它们只能按顺序执行,因此出于性能原因将它们融合到一条指令中,除了中断中断的能力之外几乎没有损失。 ARMv6T2刚刚根据融合的单指令执行重新定义了东西
答案 1 :(得分:11)
除了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位视图)。
所有ARMv8处理器(与所有ARMv7处理器一样)都支持T32指令集中的Thumb-2指令。
答案 2 :(得分:0)
请参考https://developer.arm.com/documentation/ddi0344/c/programmer-s-model/thumb-2-instruction-set 它详细解释了 Thumb2 架构的增强。相同的内容隐含地涵盖了 ARM、Thumb 和 Thumb2 指令集描述。
答案 3 :(得分:0)
Cortex M3 具有 4 字节指令,但不执行 ARM 指令,这让我感到困惑。或者 CPU 能够具有 2 字节和 4 字节操作码,但也能够执行 ARM 指令。所以我读了一本关于 Arm 的书,现在我对它的理解稍微好一点。尽管如此,命名和重叠仍然让我感到困惑。我想先比较几个 CPU 然后再讨论 ISA 会很有趣。
比较几个 CPU 以及它们可以做什么以及它们如何重叠:
Cortex M0/M0+/M1/M23 被认为是 Thumb (Thumb-1) 并且可以执行 2 字节与其他操作码相比有限的操作码。但是,一些指令如 mrs
、msr
、bl
、dmb
、dsb
、isb
来自 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 的一个子集(它们缺少特别是 it
、cbz
和 cbnz
指令)。我可能错了(如果不对,请纠正我),但注意到一些有趣的事情,只有我看到的完全支持 Thumb-1 的 CPU 也是已经支持 Thumb-2 的 CPU,我不知道只有 Thumb-1支持 100% Thumb-1 的 CPU。我认为这是因为 it
可以被视为 Thumb-2 操作码,它是 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
来完成,它设置 T
的 CPSR
位和根据地址的最低位切换模式。这很有效,例如当调用子程序时,PC(及其模式)被保存,然后在子程序内部它可以切换到 Thumb 模式,但是当从 Thumb 模式返回时,它将恢复 PC(及其 T 位)和切换回调用者的任何模式(ARM 或 Thumb 模式),没有任何问题。
ARM7 仅支持 ARMv3 4 字节 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 字节操作码.
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
寄存器(例如 ands
、orrs
、movs
、adds
、{ {1}} 指令),而在 Thumb-1 中,subs
始终处于开启状态,并始终保存 s
寄存器。在一些较旧的工具链中,不需要隐式 CPSR
,但是在统一汇编语言 (UAL) 的努力中,即使没有不使用 { 的选项,现在也要求显式指定 s
{1}}。
Thumb-2 是 Thumb 的扩展,可以像 ARM 一样访问所有寄存器,与 ARM 相比具有 4 字节的操作码。在程序集中,可以使用 s
和 s
后缀(例如 .n
)强制使用 Thumb-1 2 字节窄操作码和 Thumb-2 4 字节宽操作码。 ARM 和 Thumb-2 操作码格式/编码不同,它们的功能也不同。可以使用指令的条件执行,但仅当 .w
(if-then) 指令/块被前置时。这可以明确或隐含地完成(并由用户背后的工具链完成)。并且混淆可能实际上是好的,因为 Arm(公司)希望它们相似,统一汇编语言 (UAL) 付出了很多努力,因此为 ARM 制作的汇编文件可以在 Thumb-2 上编译而无需更改。如果我理解正确,那不能 100% 保证,并且可能会出现一些边缘情况,其中 ARM 程序集无法编译为 Thumb-2,这是另一个不完全正确的绝对陈述。例如,ARM7 orr.w
指令可以寻址 +-32MB,而在 Cortex M3 上它只能寻址 +-16MB。与 Thumb-1 相比,这种情况要好得多,其中 ARM 程序集必须更有可能重写为目标 Thumb-1,而 ARM 重写为 Thumb-2 的可能性较小。另一个区别是数据处理指令。 ARM 和 Thumb-2 都支持 8 位立即数,而 ARM 只能向右旋转位,只能旋转偶数位,而 Thumb 可以向左旋转偶数/奇数位,在此之上允许重复字节模式例如 it
、bl
或 0xXYXYXYXY
。因为移位是旋转的,左右移位可以通过“溢出”来实现,向一个方向移位太多以至于实际上是向相反方向移位0x00XY00XY
总之,一些 Arm CPU 可以做到:
此信息参考:ARM Assembly Language Programming & Architecture Muhammad Ali Mazidi et al 2016。这本书是在公司名称从 ARM 更改为 Arm 之前编写的,因此有时在引用公司 Arm 和ARM ISA。