ARM Thumb mode
The ARM processor has 2 instruction sets, the traditional ARM set, where the instructions are all 32-bit long, and the more condensed Thumb set, where most common instructions are 16-bit long (and some are 32-bit long). Which instruction set to run can be chosen by the developer, and only one set can be active (i.e. once the processor is switched to Thumb mode, all instructions will be decoded as using the Thumb instead of ARM).
Although they are different instruction sets, they share similar functionality, and can be represented using the same assembly language.
For example, the instruction {{{code: lang=“c” linenumbers=“True” ADDS R0, R1, R2 }}} can be compiled to
- ARM (‘‘E0910002 / 11100000 10010001 00000000 00000010’’)
- Thumb (‘‘1888 / 00011000 10001000’’).
Thumb instructions are a subset of the ARM instruction set, encoded in 16 bits instead of 32 bits. They can perform most of the common operations, such as arithmetic, logical, data movement, branch, and load/store. However, they have some limitations, such as fewer registers, reduced addressing modes, and no conditional execution. Thumb instructions can only access the lower 8 registers (R0-R7) and the program counter (PC), link register (LR), and status register (CPSR). To access the upper 8 registers (R8-R15), you need to use special instructions or switch to ARM mode.
In assembly language, you can use the ‘’.thumb’’ and ‘’.arm’’ directives to indicate the mode of the following instructions.
For example, you can write: {{{code: lang=“asm” linenumbers=“True” .arm MOV R0, #0x1000 BX R0 ; branch to Thumb mode at 0x1000 .thumb ADD R0, R0, #1 ; Thumb instruction MOV R1, PC BIC R1, R1, #1 ; clear LSB of PC BX R1 ; branch back to ARM mode You can also use the .thumb_func directive to mark the start of a Thumb function, which will automatically set the LSB of the function address. For example, you can write: .thumb_func func: PUSH {R4-R7, LR} ; save registers ; do some work POP {R4-R7, PC} ; restore registers and return }}}
In C language, you can use the ‘‘attribute’’‘’((thumb))‘’ and ‘‘attribute’’‘’((arm))‘’ keywords to specify the mode of a function.
For example, you can write:
{{{code: lang=“c” linenumbers=“True” attribute((thumb)) void thumb_func(void) { // do some work in Thumb mode } attribute((arm)) void arm_func(void) { // do some work in ARM mode } }}}
You can also use the ‘‘asm’’ keyword to insert assembly code in your C program. For example, you can write:
{{{code: lang=“c” linenumbers=“True” asm(“BX R0”); // branch to the mode indicated by R0 }}}
Thumb instruction set encoding is a useful feature of the ARM architecture that can help you optimize your code for size, speed, and power. By understanding how to switch between ARM and Thumb modes in assembly and C languages, you can take advantage of both modes and interwork seamlessly.
https://www.youtube.com/watch?v=XbVONAOYKTw

📽️ https://www.youtube.com/watch?v=Usjax7H0xuA Modes of ARM7