32-bit ARM & Thumb-2
r0–r15, the 32-bit calling convention, IT blocks, push/pop — the instruction set of Cortex-M and older Cortex-A.
32-bit ARM (AArch32) is still everywhere: every Cortex-M microcontroller and many Cortex-A and Cortex-R parts. Its Thumb-2 instruction set mixes 16- and 32-bit instructions for better code density, which matters in small flash memories.
The same ideas, 32-bit style
.syntax unified and .thumb select modern Thumb-2 syntax; .thumb_func marks Thumb entry points.
Sixteen registers: r0–r12, sp (r13), lr (r14), pc (r15). Arguments in r0–r3, result in r0.
it lt / movlt: an IT block makes up to four following instructions conditional.
push {r4, r5, lr} saves registers; pop {r4, r5, pc} restores them and returns in one instruction.
bx lr returns to the caller.
Forgetting .thumb_func on a Thumb function called through a pointer
Mark Thumb functions with .thumb_func (or .type name, %function)
The lowest bit of a Thumb function's address must be 1 so bx/blx switch to Thumb state; without the marker the call can jump into the function in ARM state and crash.
What is the advantage of Thumb-2 over the original 32-bit ARM instruction set?
Better code density: common instructions are 16 bits, the rest 32 bits, giving near-ARM performance with considerably smaller code — important for flash-limited microcontrollers.