Instruction length
An A32 instruction is always 4 bytes, on a 4-byte boundary. A Thumb instruction is 2 or 4 bytes on a 2-byte boundary; the first halfword says which. Both are stored in the byte order of the file (little-endian in practice; BE8 files keep instructions little-endian and only the data big-endian).
| First halfword, bits 15:11 | Length | Meaning |
|---|---|---|
| 00000 to 11100 | 2 bytes | A T16 instruction (11100 is the unconditional branch b) |
| 11101, 11110, 11111 | 4 bytes | The first half of a T32 instruction; the second halfword follows. Before ARMv6T2 only the pair 11110 and 11111 (or 11101) exists: the two halves of bl and blx |
A 4-byte Thumb instruction therefore covers two halfword positions, and a decoder that starts in the middle of one reads different instructions. The explorer decodes at every halfword and lays the results out in columns (the first column is the reading from the start of the section) so both readings can be seen.
The format of a T32 instruction is set by bits 12:11 of the first halfword (01, 10, 11) and by bit 15 of the second; the encoding groups are listed on the Thumb page. The A32 groups are chosen by bits 27:25 and by bits 7:4 for the multiply, load/store extension and synchronisation space; see the A32 page.
Interworking: ARM state and Thumb state
The processor is in one state at a time, shown by the T bit of the status register. These instructions change it:
| Instruction | New state |
|---|---|
bx Rm, blx Rm | Bit 0 of Rm: 1 for Thumb, 0 for ARM. The target address has bit 0 cleared. |
blx label (A32, T32) | The other state: from A32 it goes to Thumb (the H bit selects the halfword), from Thumb to ARM (the target is rounded to a 4-byte boundary) |
ldr pc, …, pop {…, pc}, ldm with the PC in the list, mov pc, … (since ARMv5T, v7 for data processing) | Bit 0 of the loaded value, as bx |
b, bl, cbz, tbb | Unchanged |
Exception entry and return (eret, subs pc, lr, #n, rfe) | From the saved status register (the T bit of the SPSR) |
| The M profile | Always Thumb; loading a PC value with bit 0 clear raises a fault (an EXC_RETURN pattern excepted) |
In a file the state of each region is told by:
- Mapping symbols (ELF for the Arm Architecture): the local, untyped symbols
$a,$tand$d, optionally with a suffix ($a.1), mark where ARM code, Thumb code and data start in a section; each holds until the next one. The viewer reads them from the symbol table. Literal pools inside a function are$dand are shown as bytes. - The low bit of a function symbol’s value (
st_value) is 1 for a Thumb function, and so is the low bit of the ELF entry point. The viewer uses the entry’s bit when a file has no mapping symbols; the symbol names are shown at the real address. - Build attributes (
.ARM.attributes):Tag_CPU_arch,Tag_CPU_arch_profile(A, R, M),Tag_ARM_ISA_useandTag_THUMB_ISA_use(0 none, 1 Thumb-1, 2 Thumb-2),Tag_FP_arch(1 VFPv1, 2 VFPv2, 3 VFPv3, 4 VFPv3-D16, 5 VFPv4, 6 VFPv4-D16, 7 FP-ARMv8, 8 FP-ARMv8-D16),Tag_Advanced_SIMD_arch,Tag_DIV_use. They choose the default architecture level. e_flags: the EABI version in the top byte (5 for current files),EF_ARM_ABI_FLOAT_HARD(0x400) andEF_ARM_ABI_FLOAT_SOFT(0x200), andEF_ARM_BE8(0x800000).- Raw code has none of these: the viewer’s Mode and Architecture options are the only way, and a Game Boy Advance cartridge, a Nintendo DS binary or a Cortex-M vector-table image must pick the state itself.
Status columns
Every decoded instruction has a status: documented, unpredictable, deprecated, reserved or undefined. They are described on the overview. The three that need a rule of their own are:
- Should-be-zero and should-be-one fields. The decoder shows the instruction as the manual defines it and marks it unpredictable when such a field is wrong (
bx r0with bits 19:8 not 0xFFF;revwith Rn not 15;vmovwith bits 6:5 set). LLVM refuses most of them; GNU objdump shows them and, for some, adds<UNPREDICTABLE>. - Use of SP and PC where the manual forbids it (T32 divide and multiply with SP or PC,
popwith both LR and PC in the list of a Thumb-2ldm,strdorvmovwith an odd or SP register). - Deprecated:
swpandswpb(superseded byldrex/strex, removed in ARMv8) andsetend.