Thumb-2
Ядра Cortex-M не умеют выполнять классические 32-битные команды ARM — только Thumb. Короткие 16-битные команды дают плотный код, а 32-битные, добавленные технологией Thumb-2, возвращают мощность полного набора команд.
Обновлено Редакция GAW
Thumb-2 — технология Arm, добавившая в 16-битный набор команд Thumb 32-битные команды с возможностями полного набора ARM. Её ввели в архитектуре ARMv6T2, и именно она позволила сделать профиль M — ядра Cortex-M, которые выполняют только Thumb (ARMv7-M ARM, A1.1). Сегодня «Thumb-2» и «Thumb» в разговоре о Cortex-M обычно означают одно и то же: набор, в котором 16- и 32-битные команды свободно перемешаны.
Как устроен набор
Команды Thumb имеют длину 16 или 32 бита и выравниваются по границе двух байт. Процессор читает поток полуслов: если биты [15:11] полуслова равны 0b11101, 0b11110 или 0b11111, это начало 32-битной команды, иначе — самостоятельная 16-битная команда (ARMv7-M ARM, A5.1). Короткие команды экономят память, но большинство из них работает только с регистрами R0–R7; длинные дают все регистры, большие константы и сложные режимы адресации (A4.1). Компилятор сам выбирает длину каждой команды, а квалификаторы .N и .W в ассемблере требуют 16- или 32-битную кодировку явно (A6.2).
| Ядро | Архитектура | Набор команд |
|---|---|---|
| Cortex-M0, M0+ | ARMv6-M | Thumb ARMv6-M: в основном исходный Thumb, часть Thumb-2 |
| Cortex-M3 | ARMv7-M | полный Thumb-2 |
| Cortex-M4 | ARMv7-M | Thumb-2 плюс DSP-команды и команды FPU |
ARMv6-M совместим с Thumb до Thumb-2, а ARMv7-M расширяет его технологией Thumb-2 (A4.1); DUI 0497A говорит, что набор ARMv6-M у Cortex-M0 включает технологию Thumb-2 в урезанном виде. Полный перечень команд по группам, с флагами и примерами — в справочнике «Система команд Thumb-2».
Бит T и нечётные адреса
Cortex-M выполняет команды только в состоянии Thumb, которое хранит бит T регистра EPSR. Он берётся из младшего бита адреса при переходах BX, BLX и POP {PC}, при возврате из исключения и из бита 0 вектора при сбросе и входе в исключение. Если бит окажется нулевым, ядро получит отказ INVSTATE или уйдёт в lockup (DUI 0552A, разд. 2.1.3). Поэтому все адреса кода в таблице векторов и в указателях на функции нечётные: 0x08000189 означает код по адресу 0x08000188. Вектор с нулевым младшим битом даёт INVSTATE на первой команде обработчика (ARM 100165, разд. 3.9.1), и при выключенном UsageFault это превращается в HardFault. Об архитектуре ядра в целом — в статье «Cortex-M3».
Частые вопросы
Что добавила технология Thumb-2 к исходному Thumb?
Исходный Thumb состоял из 16-битных команд — компактных, но урезанных: большинство работает только с регистрами R0–R7. Технология Thumb-2 добавила в тот же набор 32-битные команды с возможностями полного набора ARM. Процессор различает их по первому полуслову, и обе длины свободно смешиваются в одной функции.
Почему адреса функций на Cortex-M нечётные?
Младший бит адреса перехода и вектора прерывания попадает в бит T регистра EPSR и означает состояние Thumb. Cortex-M умеет выполнять только Thumb, поэтому у адресов кода этот бит должен быть равен 1. Компоновщик ставит его сам, а если в таблицу векторов или указатель на функцию попадёт чётный адрес, ядро получит отказ INVSTATE.
Может ли Cortex-M выполнять команды ARM?
Нет. Профиль M с ARMv6-M поддерживает только набор Thumb. Попытка перейти в состояние ARM — переход по адресу с нулевым младшим битом — вызывает UsageFault INVSTATE, а при выключенном UsageFault — HardFault.
Источники
- Arm. ARMv7-M Architecture Reference Manual, ARM DDI 0403C_errata_v3, 2010 — A1.1: технология Thumb-2 введена в ARMv6T2, она сбалансировала наборы ARM и Thumb и позволила создать профиль только с Thumb для микроконтроллеров; A4.1: ARMv7-M поддерживает множество 32-битных команд, введённых в набор Thumb технологией Thumb-2, их функциональность во многом совпадает с набором ARM; команды Thumb 16- или 32-битные, выровнены по 2 байта и свободно перемешиваются; большинство 16-битных команд работают только с R0–R7; язык UAL ассемблируется и в Thumb, и в ARM; A6.2: квалификаторы .N и .W требуют 16- или 32-битную кодировку, иначе ошибка ассемблера; A5.1: поток команд — последовательность полуслов; если биты [15:11] полуслова равны 0b11101, 0b11110 или 0b11111, это первое полуслово 32-битной команды, иначе — 16-битная команда; A4.1 (об архитектурных вариантах): ARMv6-M совместим с Thumb до Thumb-2, ARMv7-M расширяет его технологией Thumb-2
- Arm. Cortex-M3 Devices Generic User Guide, DUI 0552A, 2010 — разд. 2.1.3, Thumb state: Cortex-M3 выполняет команды только в состоянии Thumb; бит T сбрасывают команды BLX, BX и POP {PC}, восстановление xPSR из стека и бит 0 вектора при входе в исключение или сбросе; выполнение при T = 0 ведёт к отказу или lockup; табл. 2-18: попытка перейти в другое состояние набора команд — UsageFault INVSTATE
- Arm. Cortex-M3 Processor Technical Reference Manual, revision r2p1 (ARM 100165), 2016 — разд. 3.9.1: бит 0 значения вектора загружается в бит T регистра EPSR; у всех заполненных векторов бит 0 должен быть 1, вектор с нулевым битом 0 даёт INVSTATE на первой команде обработчика; разд. 3.3, табл. 3-1: сводка команд Cortex-M3 с тактами, в том числе MOVW и MOVT
- Arm. Cortex-M4 Devices Generic User Guide, DUI 0553B, 2011 — разд. 1.1: Cortex-M4 добавляет к набору команд одноцикловые и SIMD-умножения, насыщающую арифметику и команды одинарной точности FPU
- Arm. Cortex-M0 Devices Generic User Guide, DUI 0497A, 2009 — разд. 1.1: Cortex-M0 реализует архитектуру ARMv6-M и её набор команд Thumb, включающий технологию Thumb-2; разд. 3.1: процессор реализует версию набора Thumb, табл. 3-1 перечисляет команды
Нашли ошибку?
Смотрите также
- Система команд Thumb-2Команды по группам, Operand2, флаги и условия, IT, переходы, DSP и FPU, M0
- Cortex-M3Регистры, карта памяти, bit-banding, NVIC, SysTick, MPU, старт, пример
- Таблица векторов прерыванийАдреса обработчиков прерываний в начале флеш-памяти
- HardFaultИсключение Cortex-M при необработанной ошибке
- RISC-VАрхитектура набора команд: расширения, ядра в ESP32 и RP2350