¿Cuál es la diferencia entre las codificaciones de instrucciones ARM, Thumb y Thumb 2?
(2)
Además de la respuesta de Notlikethat , y como sugiere, ARMv8 introduce una nueva terminología para tratar de reducir la confusión (por supuesto, agregando aún más terminología nueva):
Hay un estado de ejecución de 32 bits (AArch32) y un estado de ejecución de 64 bits (AArch64).
El estado de ejecución de 32 bits admite dos conjuntos de instrucciones diferentes: T32 ("Thumb") y A32 ("ARM"). El estado de ejecución de 64 bits admite solo un conjunto de instrucciones: A64.
Todas las instrucciones A64, como todas las A32, tienen un tamaño de 32 bits (4 bytes) y requieren una alineación de 4 bytes.
Muchas / la mayoría de las instrucciones A64 pueden operar tanto en registros de 32 bits como de 64 bits (o posiblemente en vistas de 32 bits o de 64 bits del mismo registro subyacente de 64 bits).
Todos los procesadores ARMv8 (como todos los procesadores ARMv7) admiten instrucciones Thumb-2 en el conjunto de instrucciones T32.
Estoy un poco confundido acerca de los conjuntos de instrucciones. Hay Thumb, ARM y Thumb 2. De lo que he leído, las instrucciones de Thumb son todas de 16 bits, pero dentro del manual de usuario de ARMv7M (página vi) se mencionan las instrucciones de Thumb de 16 bits y Thumb de 32 bits.
Ahora tengo que superar esta confusión. Se dice que el Thumb 2 admite instrucciones de 16 y 32 bits. Entonces, ¿ARMv7M es de hecho compatible con las instrucciones del pulgar 2 y no solo del pulgar?
Una cosa más. ¿Puedo decir que Thumb (32 bits) es lo mismo que las instrucciones ARM que son todas de 32 bits?
Oh, ARM y sus nombres tontos ...
Es un error común, pero oficialmente no existe un "conjunto de instrucciones Thumb-2".
Ignorando ARMv8 (donde todo cambia de nombre y AArch64 complica las cosas), de ARMv4T a ARMv7-A hay dos conjuntos de instrucciones : ARM y Thumb. Ambos son "32 bits" en el sentido de que operan en datos de hasta 32 bits de ancho en registros de 32 bits de ancho con direcciones de 32 bits. De hecho, donde se superponen representan exactamente las mismas instrucciones: solo difiere la codificación de instrucciones, y la CPU solo tiene dos frontales de decodificación diferentes a su canalización con los que puede alternar. Para mayor claridad, ahora evitaré deliberadamente los términos "32 bits" y "16 bits" ...
Las instrucciones ARM tienen codificaciones de 4 bytes de ancho fijo que requieren una alineación de 4 bytes. Las instrucciones del pulgar tienen codificaciones de longitud variable (2 o 4 bytes, ahora conocidas como "angosta" y "ancha") que requieren alineación de 2 bytes: la mayoría de las instrucciones tienen codificaciones de 2 bytes, pero bl
y blx
siempre han tenido codificaciones de 4 bytes. * . El bit realmente confuso vino en ARMv6T2, que introdujo la "Tecnología Thumb-2". El Thumb-2 abarcó no solo agregar una carga más de instrucciones a Thumb (principalmente con codificaciones de 4 bytes) para llevarlo casi a la paridad con ARM, sino también extender el estado de ejecución para permitir la ejecución condicional de la mayoría de las instrucciones de Thumb, y finalmente introducir una nueva sintaxis de ensamblaje (UAL, "Lenguaje de ensamblado unificado") que reemplazó las sintaxis anteriores de ARM y Thumb y permitió escribir el código una vez y ensamblarlo en cualquiera de los conjuntos de instrucciones sin modificación.
Las arquitecturas Cortex-M solo implementan el conjunto de instrucciones Thumb - ARMv7-M (Cortex-M3 / M4 / M7) es compatible con la mayoría de la "Tecnología Thumb-2", incluida la ejecución condicional y las codificaciones de las instrucciones VFP, mientras que ARMv6-M (Cortex- M0 / M0 +) solo utiliza el Thumb-2 en forma de un puñado de instrucciones del sistema de 4 bytes.
Por lo tanto, las nuevas codificaciones de 4 bytes (y las agregadas más adelante en las revisiones ARMv7) siguen siendo instrucciones para el pulgar: el aspecto "Pulgar-2" de ellas es que pueden tener codificaciones de 4 bytes, y que pueden (en su mayoría) ser condicionales ejecutado a través de it
(y, supongo, que sus menmónicas solo se definen en UAL).
* Antes de ARMv6T2, en realidad era un detalle de implementación complicado en cuanto a si bl
(o blx
) se ejecutaba como una instrucción de 4 bytes o como un par de instrucciones de 2 bytes. La definición arquitectónica fue la última, pero como solo podían ejecutarse como un par en secuencia, había poco que perder (aparte de la capacidad de interrumpir una interrupción a la mitad) al fusionarlos en una sola instrucción por razones de rendimiento. ARMv6T2 simplemente redefinió las cosas en términos de la ejecución de una sola instrucción fusionada