ARM公司在其Cortex-M内核中嵌入了新的Thumb-2 指令集,新的Thumb-2 指令集保留了紧凑代码质量并与现有ARM代码兼容,提供改进的性能和质量,基于Cortex-M4 的处理器支持Thumb-2 指令集技术。
指令集的设计是处理器设计的核心之一,是嵌入式系统中与程序设计相关联的部分,主要用于寄存器操作、寻址操作、存储操作、中断、异常处理以及外部I\O处理等高性能的数据处理。ARM指令的长度是 32 位,对应处理器ARM状态。Thumb指令集由 16 位指令组成,每条Thumb指令都可以通过等效的 32 位ARM指令来执行。然而,并不是所有的ARM指令都在Thumb子集中可用,例如,Thumb指令无法访问状态或协处理器寄存器。此外,一些可以在ARM指令中完成的功能只能通过Thumb指令序列来模拟。实际上,ARM只包含一种指令集,那就是 32-bit的ARM指令集。当处理器运行在Thumb状态时,处理器把从内存中读取的Thumb指令扩展成与它等价的 32-bit的ARM指令后执行。Thumb指令和与它等价的ARM指令并不是功能上的不同,而是在指令执行前的取指(fetch)和译码(interpret)的不同。由于将 16-bit的指令扩展成 32-bit的指令是通过芯片上专门的硬件完成的,所以这一过程并不会影响整个执行的速率,反而更狭小的 16-bit的Thumb指令在内存的利用上更有优势。Thumb指令集提供了典型应用程序所需的大部分功能,例如,算术和逻辑操作,加载/存储数据移动,以及条件和无条件的分支跳转。任何用C编写的代码都可以在Thumb状态下成功执行。但设备驱动程序和异常处理程序通常有部分在ARM状态下编写。
在ARM状态的用户模式下,17 个寄存器是可见的,Thumb状态下 12 个寄存器可见,并且它们是在物理上和ARM状态下完全相同的寄存器。因此软件运行在ARM状态和Thumb状态时,可以通过R0~R7 来传递数据,这在实际的应用中非常普遍。在Thumb状态下,SP寄存器的操作由专门的助记符PUSH和POP完成,但在ARM状态下,PUSH和POP是不存在的,它们以R13 为堆栈指针,并将助记符转换成ARM状态下的LDR和STR指令。
在ARM处理器中,CPSR寄存器用来保存处理器模式(用户或异常标志)、中断掩码位、条件代码和Thumb状态位。Thumb状态位(T)表示处理器的当前状态:当该位为 0 时表示ARM状态(默认),为 1 时表示Thumb状态。虽然CPSR中的其他位可能在软件中被修改,但直接写入T是危险的,不适当的状态改变会产生不可预测的结果。
Thumb-2 是Thumb指令集的一项主要增强功能,它由ARMv6T2 和ARMv7M体系结构定义。Thumb-2 提供了几乎与ARM指令集完全一样的功能。它兼有 16 位和 32 位指令,并可检索与ARM类似的性能,但其代码密度与Thumb代码类似。如图3.2 所示,Thumb-2 指令集在现有的Thumb指令的基础上做了如下的扩充并增加了一些新的 16 位Thumb指令来改进程序的执行,流程增加了一些新的 32 位Thumb指令以实现一些ARM指令的专有功能,32 位的ARM指令也得到了扩充,增加了一些新的指令来改善代码性能和数据处理的效率,增加32 位指令解决了原Thumb指令集不能访问协处理器、特权指令和特殊功能指令的局限。
图3.2 Thumb-2 与Thumb指令集的关系
新的Thumb-2 技术可以带来很多好处,可以实现ARM指令的所有功能,增加了 12 条新指令,可以改进代码性能和代码密度之间的平衡代码性能,达到了纯ARM代码性能的 98%。相对于ARM代码,Thumb-2 代码的大小仅有其 74%代码密度,比现有的Thumb指令集更高效,代码大小平均降低 5%,代码速度平均提高 2%~3%。