For the ARMv6-M architecture used in the Cortex-M0 and Cortex-M0+ Processors, in order to reduce the circuit size to a minimum, only the 16-bit Thumb instructions and a minimum subset of 32-bit Thumb instructions(BL, MSR, MRS, DMB, DSB, ISB) are supported.
Moving Data within the Processor
MOV <Rd>, <Rm> // Rm and Rn can be high or low registers.
MOVS <Rd>, <Rm>
MOVS <Rd>, #immed8
MRS <Rd>, <SpecialReg>
MSR <SpecialReg>, <Rd>
Memory Accesses
It is important to make sure the memory address accessed is aligned.Unaligned transfers are not supported on the ARMv6-M Architecture (include Cortex-M0 and Cortex-M0 processors). Any attempt at unaligned memory access result in a HardFault exception.
LDR <Rt>,[<Rn>, <Rm>] // Rt = memory[Rn + Rm]
STR <Rt>,[<Rn>, <Rm>] // memory[Rn + Rm] = Rt
LDRH <Rt>,[<Rn>, <Rm>] // Rt = memory[Rn + Rm]
STRH <Rt>,[<Rn>, <Rm>] // memory[Rn + Rm] = Rt
LDRB <Rt>,[<Rn>, <Rm>] // Rt = memory[Rn + Rm]
STRB <Rt>,[<Rn>, <Rm>] // memory[Rn + Rm] = Rt
LDRSH <Rt>,[<Rn>, <Rm>] // Rt = SignExtend(memory[Rn + Rm])
LDRSB <Rt>,[<Rn>, <Rm>] // Rt = SignExtend(memory[Rn + Rm])
LDR <Rt>,[<Rn>, #immed5] // Rt = memory[Rn + ZeroExtend (#immed5<<2)]
STR <Rt>,[<Rn>, #immed5] // memory[Rn + ZeroExtend(#immed5<<2)] = Rt
LDRH <Rt>,[<Rn>, #immed5] // Rt = memory[Rn + ZeroExtend (#immed5<<1)]
STRH <Rt>,[<Rn>, #immed5] // memory[Rn + ZeroExtend(#immed5<<1)] = Rt
LDRB <Rt>,[<Rn>, #immed5] // Rt = memory[Rn + ZeroExtend (#immed5)]
STRB <Rt>,[<Rn>, #immed5] // memory[Rn + ZeroExtend(#immed5)] = Rt
LDR <Rt>,[SP, #immed8] // Rt = memory[SP + ZeroExtend(#immed8<<2)]
STR <Rt>,[SP, #immed8] // memory[SP + ZeroExtend(#immed8<<2)] = Rt
LDR <Rt>,[PC, #immed8] // Rt = memory[WordAligned(PC + 4) + ZeroExtend(#immed8<<2)]
LDR <Rd>, =immed32 // pseudo instruction translated to LDR <Rt>,[PC, #immed8]
LDR <Rd>, label // pseudo instruction translated to LDR <Rt>,[PC, #immed8]
LDM <Rn>,{<Ra>, <Rb>,..} // Load Multiple
// Ra = memory[Rn]
// Rb = memory[Rn + 4],
// ...
LDMIA <Rn>!, {<Ra>, <Rb>,..} // Load Multiple Increment After
LDMFD <Rn>!, {<Ra>, <Rb>,..}
// Ra = memory[Rn],
// Rb = memory[Rn + 4],
// ...
// and then update Rn to last read address plus 4.
STMIA <Rn>!, {<Ra>, <Rb>,..} // Store Multiple Increment After
STMEA <Rn>!, {<Ra>, <Rb>,..}
// memory[Rn] = Ra,
// memory[Rn + 4] = Rb,
// ...
// and then update Rn to last store address plus 4.
Stack Memory Accesses
PUSH {<Ra>, <Rb>, ..}
PUSH {<Ra>, <Rb>, .., LR}
POP {<Ra>, <Rb>, ..}
POP {<Ra>, <Rb>, .., PC}
Arithmetic Operations
ADD <Rd>, <Rm> // Rd = Rd + Rm. Rd, Rm can be high or low registers.
ADDS <Rd>, <Rn>, <Rm> // Rd = Rn + Rm
SUBS <Rd>, <Rn>, <Rm> // Rd = Rn – Rm
ADDS <Rd>, <Rn>, #immed3 // Rd = Rn + ZeroExtend(#immed3)
SUBS <Rd>, <Rn>, #immed3 // Rd = Rn – ZeroExtend(#immed3)
ADDS <Rd>, #immed8 // Rd = Rd + ZeroExtend(#immed8)
SUBS <Rd>, #immed8 // Rd = Rd – ZeroExtend(#immed8)
ADCS <Rd>, <Rd>, <Rm> // Rd = Rd + Rm + Carry
SBCS <Rd>, <Rd>, <Rm> // Rd = Rd – Rm – Borrow
ADD SP, SP, #immed7 // SP = SP + ZeroExtend(#immed7<<2)
SUB SP, SP, #immed7 // SP = SP – ZeroExtend(#immed7<<2)
ADD SP, <Rm> // SP = SP + Rm. Rm can be high or low register.
ADD <Rd>, SP, <Rd> // Rd = Rd + SP. Rd can be high or low register.
ADD <Rd>, SP, #immed8 // Rd = SP + ZeroExtend(#immed8<<2)
ADD <Rd>, PC, #immed8 // Rd = (PC[31:2]<<2) + ZeroExtend(#immed8<<2)
ADR <Rd>, <label> // pseudo instruction translated to ADD <Rd>, PC, #immed8
RSBS <Rd>, <Rn>,#0 // Rd = 0 – Rm, Reverse Subtract (negative)
MULS <Rd>, <Rm>, <Rd> // Rd = Rd * Rm
CMP <Rn>, #immed8 // Rd – ZeroExtended(#immed8)
CMP <Rn>, <Rm> // Rn – Rm
CMN <Rn>, <Rm> // Rn – NEG(Rm)
Logic Operations
ANDS <Rd>, <Rd>, <Rm> // Rd = AND(Rd, Rm)
ORRS <Rd>, <Rd>, <Rm> // Rd = OR(Rd, Rm)
EORS <Rd>, <Rd>, <Rm> // Rd = XOR(Rd, Rm)
BICS <Rd>, <Rd>, <Rm> // Rd = AND(Rd, NOT(Rm))
MVNS <Rd>, <Rm> // Rd = NOT(Rm)
TST <Rn>, <Rm> // AND(Rn, Rm)
Shift and Rotate Operations
ASRS <Rd>, <Rm>, #immed5 // Rd = Rm>>immed5
LSLS <Rd>, <Rm>, #immed5 // Rd = Rm<<#immed5
LSRS <Rd>, <Rm>, #immed5 // Rd = Rm>>#immed5
ASRS <Rd>, <Rd>, <Rm> // Rd = Rd>>Rm
LSLS <Rd>, <Rd>, <Rm> // Rd = Rd<<Rm
LSRS <Rd>, <Rd>, <Rm> // Rd = Rd>>Rm
RORS <Rd>, <Rd>, <Rm> // Rd = Rd rotate right by Rm bits
// Rotate_Left(Data, offset) = Rotate_Right(Data, (32-offset))
Reverse Ordering Operations
These reverse instructions are usually used for converting data between little endian and
big endian systems.
REV <Rd>, <Rm> // Byte-Reverse Word
// Rd = {Rm[7:0], Rm[15:8], Rm[23:16], Rm[31:24]}
REV16 <Rd>, <Rm> // Byte-Reverse Packed Half Word
// Rd = {Rm[23:16], Rm[31:24], Rm[7:0] , Rm[15:8]}
REVSH <Rd>, <Rm> // Byte-Reverse Signed Half Word
// Rd = SignExtend({Rm[7:0] , Rm[15:8]})
Extend Operations
They are usually used for data type conversions.
SXTB <Rd>, <Rm> // Signed Extended Byte
// Rd = SignExtend(Rm[7:0])
SXTH <Rd>, <Rm> // Signed Extended Half Word
// Rd = SignExtend(Rm[15:0])
UXTB <Rd>, <Rm> // Unsigned Extended Byte
// Rd = ZeroExtend(Rm[7:0])
UXTH <Rd>, <Rm> // Unsigned Extended Half Word
// Rd = ZeroExtend(Rm[15:0])
Program Flow Control
B <label> // Branch, Branch range is ±2046 bytes of current PC
B<cond> <label> // Conditional Branch, Branch range is ±254 bytes of current PC
BL <label> // Branch and Link, Branch range is ±16 MB of current PC
BX <Rm> // Branch and Exchange
BLX <Rm> // Branch and Link with Exchange
Conditional branch instructions B
Required branch control | Unsigned data | Signed data |
---|---|---|
If (R0 equal R1) then branch | BEQ label | BEQ label |
If (R0 not equal R1) then branch | BNE label | BNE label |
If (R0 > R1) then branch | BHI label | BGT label |
If (R0 >= R1) then branch | BCS label/BHS label | BGE label |
If (R0 < R1) then branch | BCC label/BLO label | BLT label |
If (R0 <= R1) then branch | BLS label | BLE label |
If (overflow(R0 + R1)) then branch | BCS label | BVS label |
If (no_overflow(R0 + R1)) then branch | BCC label | BVC label |
If (overflow(R0 – R1)) then branch | BCC label | BVS label |
If (no_overflow(R0 – R1)) then branch | BCS label | BVC label |
If (result >= 0) then branch | Not applicable | BPL label |
If (result < 0) then branch | Not applicable | BMI label |
Memory Barrier Instructions
The memory barrier instructions are supported on the Cortex-M0 and Cortex-M0 processors to provide better compatibility within the Cortex-M processors and other ARM processor families.
// Data Memory Barrier, Ensures that all memory accesses are completed
// before new memory access is committed.
DMB
// Data Synchronization Barrier, Ensures that all memory accesses are completed
// before next instruction is executed.
DSB
// Instruction Synchronization Barrier, Flushes the pipeline and
// ensure that all previous instructions are completed
// before executing new instructions.
ISB
Exception-Related Instructions
SVC <immed8> // Supervisor call
CPSIE I // Enable Interrupt (Clearing PRIMASK)
CPSID I // Disable Interrupt (Setting PRIMASK)
Sleep Mode Feature-Related Instructions
// Wait For Interrupt, Stops program execution until an interrupt arrived,
// or if the processor entered a debug state.
WFI
// Wait For Event, If the internal event register is set, it clears the
// internal event register and continues execution.
// Otherwise stop program execution until an event (e.g., an interrupt) arrive,
// or if the processor enters debug state.
WFE
// Send Event, Set local event register and send out an event pulse to
// other microprocessor in a multiple processor system.
SEV
Other Instructions
NOP // No Operation
BKPT <immed8> // Break point
YIELD // Execute as NOP on the Cortex-M0 processor