Mnemonic Description Flags Notes Examples
Arm General Info The ARM processor is a 32 bit RISC processor, capable on most instructions
of executing 1 instruction per clock cycle. Also it can do up to a full 32 bit shift
or rotate left or right, without any time penalty. All instructions can be made
conditional on any flag. ARM has a 5 (3 on ARM<6) stage pipeline, with a full
32 bit data and address bus (26 bit address on ARM 2 & 3). ARM has 31
(27 on ARM<6) 32 bit general purpose registers, of which 16 are visible at any
one time and only one is tied up by the processor.



XXX{cond} {S} <dest> , <lhs> , <rhs> A brief Description of what the opcode does. Which Flags
affected by
operation.
Any Notes pertinent to the instruction.
{cond} is a two letter condition flag.
{S} if present, causes result flags to be set.
<dest> and <lhs> are registers,
<rhs> may be a register, which can be shifted or rotated, by a number, or a register; or an
immediate number, which can be represented by [(0 to 255), rotated right by (0 to 16)*2].
Some examples, if you are lucky!.
Status bits on ARM processors after ARM3

bit--43210----Name----------Meaning
------00000----usr_26-----26 bit PC User Mode
------00001----fiq_26------26 bit PC FIQ Mode
------00010----irq_26------26 bit PC IRQ Mode
------00011----svc_26-----26 bit PC SVC Mode,
New Modes
------10000----usr_32-----32 bit PC User Mode
------10001----fiq_32------32 bit PC FIQ Mode
------10010----irq_32------32 bit PC IRQ Mode
------10011----svc_32-----32 bit PC SVC Mode
------10111----abt_32-----32 bit PC Abt Mode
------11011----und_32----32 bit PC Und Mode

Flags in Register R15 ARM 2&3. bit 31 N Negative result flag
bit 30 Z Zero result flag
bit 29 C Carry flag
bit 28 V Overflow result flag,
bit 27 IRQ Interrupt disable flag
bit 26 FIQ Fast interrupt disable flag
bit 0 S0 Processor mode 0
bit 1 S1 Processor mode 1
NZCVIFxx xxxxxxxx xxxxxxxx xxxxxxSS (..xxxx..=PC)



Flags in status Register on ARM>=6. bit 31 N Negative result flag
bit 30 Z Zero result flag
bit 29 C Carry flag
bit 28 V Overflow result flag,
bit 7 IRQ Interrupt disable flag
bit 6 FIQ Fast interrupt disable flag
Bit 0-4 M Processor mode,
NZCVxxxx xxxxxxxx xxxxxxxx IFxMMMMM (x=not used)

R15 now only contains the PC, but optionally can be made to revert to,
ARM 2&3 mode, but only the bottom 64Mb of memory will be visible.

Interrupts.

The ARM has two interrupt types. IRQ and FIQ, both cause the current program to suspend,
while the interrupt is serviced. The IRQ can be disabled by setting the IRQ flag. The FIQ can
be disabled by setting the FIQ flag. If an FIQ is activated, the IRQ bit is automatically set.
The reverse is not true, and a FIQ can be processed while an IRQ is active. Each interrupt
has its own private copy of some of the regs, which replace the previous copies, but whose
contents are not lost, and are replaced when finished.

Processor Modes S1---S0------Modes ARM2 & 3 only
--0-----0----User mode. Normal operation.
--0-----1----FIQ or fast interrupt Has private set of regs R8-R14.
--1-----0----IRQ or interrupt Has private set of regs. R13-14.
--1-----1----SVC or supervisor. Has private set of regs R13-14
The private registers mentioned replace the standard registers, their contents
is only visible when in the appropriate mode. The S0 & S1 flags can only be
changed from within a mode other than user.



Registers Registers visible on ARM processor in various modes.
Mode--------------------------Registers available
USR---R0----------------------------------------------------------R14-----------R15
FIQ----R0------------R7 R8_FIQ------------------------------R14_FIQ---R15
IRQ---R0---------------------------------R12--R13_IRQ----R14_IRQ---R15
SVC--R0---------------------------------R12--R13_SVC---R14_SVC--R15
ABT--R0---------------------------------R12--R13_ABT---R14_ABT--R15 ( ARM>=6 )
UND--R0---------------------------------R12--R13_UND---R14_UND--R15 ( ARM>=6 )
There are six status registers on the ARM6 and later processors.
One is the current processor status register (CPSR) and holds information about
the current state of the processor. The other five are the saved processor status
registers (SPSRs): there is one of these for each privileged mode, it holds
information about the state the processor must be returned to when exception
handling in that mode is complete. These registers are set and read using the
MSR and MRS instructions respectively.

GE check for Greater or Equal (N clear & V clear or N set & V set) none This is not strictly a mnemonic, but a condition code which can be added after any instruction
mnemonic, to make it conditional. Use for signed numbers. For unsigned numbers use CS.

GT check Greater Than (N clr & V clr & Z clr) or (N set & V set & Z clr) none This is not strictly a mnemonic, but a condition code which can be added after any instruction
mnemonic, to make it conditional. Use for signed numbers. For unsigned numbers use HI.

LT check for Less Than (N set & V clear or N clear & V set) none This is not strictly a mnemonic, but a condition code which can be added after any instruction
mnemonic, to make it conditional. Use for signed numbers. For unsigned numbers use CC.

EQ check for EQual (Z flag set) none This is not strictly a mnemonic, but a condition code which can be added after any instruction
mnemonic, to make it conditional.

VC check for oVerflow Clear (V [overflow] flag clear) none This is not strictly a mnemonic, but a condition code which can be added after any instruction
mnemonic, to make it conditional. Add, subtract and compare instructions affect the V flag.

VS check for oVerflow Set (V [overflow] flag set) none This is not strictly a mnemonic, but a condition code which can be added after any instruction
mnemonic, to make it conditional. Add, subtract and compare instructions affect the V flag

HI check for HIgher (C flag set Z flag clear) none This is not strictly a mnemonic, but a condition code which can be added after any instruction
mnemonic, to make it conditional. The Carry flag is affected by instructions such as ADD, SUB
& CMP, it is also altered by shift or rotate operations. Use for unsigned, for signed use GT.

CC or LO check for Carry Clear or LOwer (C flag clear) none This is not strictly a mnemonic, but a condition code which can be added after any instruction
mnemonic, to make it conditional. The Carry flag is affected by instructions such as ADD, SUB
& CMP, it is also altered by shift or rotate operations. Use for unsigned, for signed use LT.

NE check for Not Equal (Z flag clear) none This is not strictly a mnemonic, but a condition code which can be added after any instruction
mnemonic, to make it conditional.

CS or HS check for Carry Set or Higher Same (C flag set) none This is not strictly a mnemonic, but a condition code which can be added after any instruction
mnemonic, to make it conditional. The Carry flag is affected by instructions such as ADD, SUB
& CMP, it is also altered by shift or rotate operations. Use for unsigned, for signed use GE.

MI check for MInus (N flag set) none This is not strictly a mnemonic, but a condition code which can be added after any instruction
mnemonic, to make it conditional. The N flag reflects the state of bit 31.

PL check for PLus (N flag clear) none This is not strictly a mnemonic, but a condition code which can be added after any instruction
mnemonic, to make it conditional. The N flag reflects the state of bit 31.

LS check for Lower or Same (C flag clear Z flag set) none This is not strictly a mnemonic, but a condition code which can be added after any instruction
mnemonic, to make it conditional. The Carry flag is affected by instructions such as ADD, SUB
& CMP, it is also altered by shift or rotate operations. Use for unsigned, for signed use LE.

LE check for Less or Equal (N set & V clr or N clr & V set or Z set) none This is not strictly a mnemonic, but a condition code which can be added after any instruction
mnemonic, to make it conditional. Use for signed numbers. For unsigned numbers use LS.

AL check for ALways none This is not strictly a mnemonic, but a condition code which can be added after any instruction
mnemonic, to make it conditional. To save having to add AL after the majority of instructions it
can be omitted Thus ADDAL and ADD are exactly the same.

NV check for NeVer. Instruction never executed. none This is not strictly a mnemonic, but a condition code which can be added after any instruction
mnemonic, to make it conditional. This would probably only ever be used to create a NOP.

ASR {#} <shift> Arithmetic Shift Right <reg> by <shift> bits, into C C This is not strictly a mnemonic, but an optional bit shift that may be applied to the <rhs> register
before it is used, the register contents is not affected, unless it is also the <dest> register.
The last bit shifted out from bit 0 is put in C, and the contents of bit 31 is repeated and
shifted down from bit 31. ie sign extended.
MOV R2, R2, ASR#1 ;R2=R2 shifted right by 1 (R2=R2/2)
ASL {#} <shift> Arithmetic Shift Left <reg> by <shift> bits, into C C This is not strictly a mnemonic, but an optional bit shift that may be applied to the <rhs> register
before it is used, the register contents is not affected, unless it is also the <dest> register.
The last bit shifted out from bit 31 is put in C, zeros are shifted into bit 0.
ASL has the same effect as LSL.
MOV R1, R2, ASL, R3 ;R1=R2 shifted left R3 (R1=R2/(2^R3))
LSR {#}<shift> Logical Shift Right <reg> by <shift> bits, into C C This is not strictly a mnemonic, but an optional bit shift that may be applied to the <rhs> register
before it is used, the register contents is not affected, unless it is also the <dest> register.
The last bit shifted out from bit 0 is put in C, zeros are shifted into bit 31.
MOV R1, R2, LSR #3 ; R1=R2 shifted right by 3 (R1=R2/8)
LSL {#}<shift> Logical Shift Left <reg> by <shift> bits, into C C This is not strictly a mnemonic, but an optional bit shift that may be applied to the <rhs> register
before it is used, the register contents is not affected, unless it is also the <dest> register.
The last bit shifted out from bit 31 is put in C, zeros are shifted into bit 0.
LSL has the same effect as ASL
MOV R1, R2, LSL, R3 ; R1=R2 shift left by R3 (R1=R2*(2^R3))
ROR {#}<shift> ROtate Right <reg> by <shift> bits, setting C C This is not strictly a mnemonic, but an optional bit shift that may be applied to the <rhs> register
before it is used, the register contents is not affected, unless it is also the <dest> register.
The register is rotated such that bit 0 goes into bit 31, also the last bit shifted out from bit 0 is put
in C. Note that there is no rotate right by 32 bits, this combination is reserved for RRX.
MOV R1, R2, ROR, R3 ; R1=R2 rotated right by contents of R3
RRX Rotate Right eXtended <reg> by one bit, using C as an extension. C This is not strictly a mnemonic, but an optional bit shift that may be applied to the <rhs> register
before it is used, the register contents is not affected, unless it is also the <dest> register.
The C flag is used as a bit 32 in the rotate, so the Carry is put into bit 31, and the bit in 0 is put in
the Carry. Note there is no RLX rotate, the same effect can be achieved by ADCS R0,R0,R0
MOV R1, R2, RRX ; R1=R2 rotated 1 bit using C
MOV{cond} {S} <dest> , <rhs> MOVe data <rhs> to <dest> N Z See the generic opcode XXX for more info. MOVS R0, R1 ; move content of R1 to R0 setting flags
MOVPL R0, R0, LSL #2 ; if positive shift R0 2 left, or R0 = R0 *4
MOV R2, #256 ; set R2 to 256
MVN{cond} {S} <dest>, <rhs> MoVe data iNverted, NOT<rhs> to <dest> N Z See the generic opcode XXX for more info., This enables negative immediate values to be loaded.
By taking the positive value, subtracting one, and using MVN.
MVNS R0, R0 ; invert all bits in R0 and set flags
MVN R2, #0 ; set R2 to &FFFFFFFF, ie. -1
MVN R3, #41 ; set R2 to -42
TEQ{cond} {S} {P} <lhs> , <rhs> Test EQual, bitwise <lhs> EOR <rhs> set flags, result not saved N Z See the generic opcode XXX for more info. If the P option is set, it is possible to change the
Status flags directly. TEQ always assumes TEQS, i.e. flags are always set.
TEQ R0, R5 ; test bits using R5 setting flags
TEQ R0, #0 ; test if Ro is zero, ie Z set
TEQP R15, #&20000000 ; Set only the carry flag
CMP{cond} {S} {P} <lhs>, <rhs> CoMPare <lhs> - <rhs> result not stored, flags set. N Z V C See the generic opcode XXX for more info. If the P option is set, it is possible to change the
Status flags directly. CMP always assumes CMPS, i.e. flags are always set.
CMP R1, #&100 ; test if R1 will fit in one byte, set flags
CMP R1, R2 ; compare R1 and R2 setting flags
MOVLT R1, R2 ; put largest number into R1
CMN{cond} {S} {P} <lhs>, <rhs> CoMpare Negative, <lhs> - -<rhs> result not stored, flags set. N Z V C See the generic opcode XXX for more info. If the P option is set, it is possible to change the
Status flags directly. Main use is to compare a reg with a small negative immediate value.
CMN R2, #2 ; compare R2 with -2, set flags
CMN R1, #&100 ; make sure R1 is less than or equal to -256
MVNLT R1, #&FF ; if too small set to -256
TST{cond} {S} {P} <lhs> , <rhs> TeST bits, bitwise <lhs> AND <rhs> result not stored, flags set. N Z See the generic opcode XXX for more info. If the P option is set, it is possible to change the
Status flags directly. TST always assumes TSTS, i.e. flags are always set.
TST R0, R5 ; test bits using R5 setting flags
TST R0, #&20 ; test for case of char, if Z set then it's caps
ADD{cond} {S} <dest>, <lhs>, <rhs> ADD <lhs> + <rhs> with result in <dest> signed or unsigned N Z V C See generic opcode XXX for more info. ADDNES R0,R0, #1 ; if flags Not Equal R0=R0+1, then set flags
ADD R0, R0, R0, LSL#1 ; R0=R0+R0*2 == R0*3, do not set flags
ADDS R8, R8, R3 ; R8=R3+R8, then set flags
ADC{cond} {S} <dest>, <lhs>, <rhs> ADd with Carry <lhs>+ <rhs>+ <carry> result in <dest> signed or unsigned N Z V C See generic opcode XXX for more info., This is to allow a 64 bit addition. e.g. add R6 R7 to R8 R9 ADDS R6, R6, R8 ; add lower half of 64 bit number, setting flags
ADC R7, R7, R9 ; add upper half of number with carry
SUB{cond} {S} <dest> , <lhs> , <rhs> SUBtact <lhs> - <rhs> result in <dest> signed N Z V C See generic opcode XXX for more info. SUBS R6, R6, #1 ; decrement R6 by one, setting flags
SUB R1, R1, R1, ASR #2 ; R1 = 3/4 * R1 (R1=R1-R1/4)
SBC{cond} {S} <dest> , <lhs> , <rhs> SuBtract with Carry <lhs> - <rhs> - NOT<carry> result in <dest> signed N Z V C See generic opcode XXX for more info., A subtract that does not need a borrow will set the C flag.
This is to allow a 64 bit subtraction R8 R9 from R6 R7
SBCS R6, R6, R8 ; subtract lower half of number, setting flags
SBC R7, R7, R9 ; subtract upper half of number with borrow
RSB{cond} {S} <dest>, <lhs>, <rhs> Reverse SuBtract <rhs> - <lhs> result in <dest> signed N Z V C See generic opcode XXX for more info. This is to allow a subtract to make full use of the shift facilities. RSB R6, R7, #1 ; R6 = 1 – R7
RSB R6, R7, R8, ASR#2 ; R6 = R8/4 - R7
RSC{cond} {S} <dest>, <lhs>, <rhs> Reverse Sub with Carry <rhs>- <lhs>- NOT<carry> result in <dest> signed N Z V C See generic opcode XXX for more info., A subtract that does not need a borrow will set the C flag.
This is to allow a 64 bit subtraction e.g. &10000000000-R6, R7
RSCS R6, R6, #0 ; subtract lower half of number, setting flags
RSC R7, R7, #4 ; subtract upper half of number with borrow
AND{cond} {S} <dest>, <lhs>, <rhs> logical bitwise <lhs> AND <rhs> result in <dest> N Z See the generic opcode XXX for more info., e.g. 01100101 AND 10110011 = 00100001 ANDNES R0, R0, R5 ; if flags NE mask bits with R5, then set flags
AND R0, R0, #&DF ; convert char to lower case
ORR{cond} {S} <dest> , <lhs> , <rhs> logical bitwise <lhs> OR <rhs> result in <dest> N Z See the generic opcode XXX for more info., e.g. 01100101 OR 10110011 = 11110111 ORRS R0, R0, R5 ; set desired bits using R5, then set flags
ORR R0, R0, #&80000000 ; set top bit of R0
EOR{cond} {S} <dest>, <lhs>, <rhs> logical bitwise <lhs> EOR <rhs> result in <dest> N Z See the generic opcode XXX for more info., e.g. 01100101 EOR 10110011 = 11010110 EORS R0 ,R0, R5 ; Invert required bits using R5, then set flags
EOR R0, R0, #16 ; toggle bit 4
MUL{cond} {S} <dest>, <lhs>, <rhs> MULtiply <lhs> by <rhs> putting result in <dest> N Z This is a simple multiply, the regs. used for <rhs> and <dest> must be different, and no shift or
rotate or immediate values of the <rhs> is allowed.
MUL R0, R1, R2 ; R0 = R1*R2
MLA{cond} {S} <dest>, <lhs>, <rhs>, <add> MuLtiply Accumulate <lhs> * <rhs> + <add> result in <dest> N Z This is a multiply with add, the regs. used for <rhs> and <dest> must be different, and no shift or
rotate or immediate values of the <rhs> is allowed. The extra add is done after the multiply.
MLA R0, R1, R2, R3 ; R0 = R1*R2 + R3
UMULL{cond} {S} <Rl> <Rh> <Rm> <Rs> Unsigned MULtiply Long, with 64 bit result, ( ARM>=7 only ) N Z Only on ARM 7 and above. Rm is multiplied by Rs to obtain a 64-bit product. The result is stored with
its least significant half in Rl and its most significant half in Rh. The program counter, R15 should not
be used. Rh, Rl and Rm should be different registers.
UMULL R1, R2, R3, R4 ; multiply R3 * R4 unsigned result in R1 and R2
SMLAL{cond} {S} <Rl> <Rh> <Rm> <Rs> Signed MuLtiply Long, with 64 bit result, ( ARM>=7 only ) N Z Only on ARM 7 and above. Rm is multiplied by Rs to give a 64-bit signed result, this is stored with its
least significant half in Rl and its most significant half in Rh. The program counter, R15 should not
be used. Rh, Rl and Rm should be different registers.
SMULL R1, R2, R3, R4 ; R3 * R4 signed result in R1 and R2
UMLAL{cond} {S} <Rl> <Rh> <Rm> <Rs> Unsigned MuLtiply and Add, Long, with 64 bit result, ( ARM>=7 only ) N Z Only on ARM 7 and above. Rm is multiplied by Rs to give a 64-bit result, and then added to Rl and Rh,
to give a final 64 bit result, this is stored with its least significant half in Rl and its most significant half
in Rh. The program counter, R15 should not be used. Rh, Rl and Rm should be different registers.
UMLAL R1, R2, R3, R4 ; R3 * R4 + (R1,R2) unsigned result in R1 and R2
SMLAL{cond} {S} <Rl> <Rh> <Rm> <Rs> Signed MuLtiply and Add, Long, with 64 bit result, (ARM >=7 only) N Z Only on ARM 7 and above. Rm is multiplied by Rs to give a 64-bit signed result and then added to Rl
and Rh, to give a final 64 bit signed result, this is stored with its least significant half in Rl and its most
significant half in Rh. The PC, R15 should not be used. Rh, Rl and Rm should be different registers.
SMLAL R1, R2, R3, R4 ; R3 * R4 + (R1,R2) signed result in R1 and R2
LDR{cond} {B} <src>, [<base>, <offset>]or[<base>], <offset> LoaD Register <src> using Pre-indexing or Post-indexing. none <src> is the register to which the data is to be transferred <base> is the reg with the base address of
the location required. <offset> is an optional value added to the <base>. The <offset> may be an
immediate number +/-4095, or a possibly shifted register, however the shift can only be an immediate
number, and not a register. The B option loads only the least significant byte. For Pre-indexing there is
not normally write back, i.e. the <base> + <offset> once used, is not stored, however if a ! is used after
the command, the new calculated <base> will be stored. e.g.
LDRB R0, [R2, #-8]! ;load byte at R2-8 into R0, reduce R2 by 8
LDR R0, [R2, R3, LSL#1] ;load from address R2+R3*2 into R0
For Post-indexing the <offset> is not added to <base> until after the the load occurs,
write-back always occurs, so no ! is needed.
LDRB R0, [R2], R3 ; load byte from address R2, then R2=R2+R3
LDR R0, [R5], #4 ; load R0 from address R5 and inc. R5 by 1 word.
A special form is LDR <dest>, <expression>, where <expression> yields an
address, this will use the PC as <base> and add the <expression>
if this is not in the range +/-4095 an error is given.
LDR R0, a_label ; load a value from location a_label
LDM{cond}<type> <base>{!}, <regs> {^} LoaD Multiple regs in <regs> starting at address <base> If ^ specified
N Z C V, In
non USR modes
processor status
flags also.
Used for loading multiple registers from stack. {cond} is as normal, <type> is a two letter code from the
letter pairs F/E (Full/Empty) or [I/D (Increment/Decrement)] and A/D (Ascending/Descending) or
[B/A (Before/After)] where ED or DA would be valid pairs, see relevant pair descriptions. <base> is the
stack pointer, {!} defines if write back of the new stack value is to occur, <regs> is a list of registers to
save, and {^} defines that if R15 is one of the registers to be loaded, the flags should be loaded as well.
Registers are always stored lowest reg at lowest address.
LDMEQIA R5!, {R1,R3,R6-R9} ;if equal, load R1,R3,R6,R7,R8,R9, replacing R5 with R5+#24
LDMIB R1, {R1-R5,R15}^ ;load R1,R2,R3,R4,R5,R15, including flags R1 is unchanged
STR{cond}{B} <src>, [<base>, <offset>] or [<base>], <offset> STore a Register using Pre-indexing or Post-indexing. none <src> is the register from which the data is to be transferred <base> is the reg with the base address of
The location required. <offset> is an optional value added to the <base>. The <offset> may be an
immediate number +/-4095, or a possibly shifted register, however the shift can only be an immediate
number, and not a register. The B option saves only the least significant byte. For Pre-indexing there is
not normally write back, i.e. the <base> + <offset> once used, is not stored, however if a ! is used after
the command, the new calculated <base> will be stored. e.g.
STRB R0, [R2, #-8]! ;store byte in R0 at R2-8, reduce R2 by 8
STR R0, [R2, R3, LSL#1] ;store R0 at address R2+R3*2
For Post-indexing the <offset> is not added to <base> until after the the store occurs,
write-back always occurs, so no ! is needed.
STRB R0, [R2], R3 ;store byte R0 at address R2, then R2=R2+R3
STR R0, [R5], #4 ;store R0 at address R5 & inc. R5 by 1 word.
A special form is STR <src>,<expression>, where <expression> yields an
address, this will use the PC as <base> and add the <expression>
if this is not in the range +/-4095 an error is given.
STR R0, a_label ;store value in R0 to location a_label. (not wise!)
STM{cond}<type> <base>{!}, <regs> {^} STore Multiple regs in <regs> starting from address <base> none Used for storing multiple registers in a stack. {cond} is as normal, <type> is a two letter code from the
letter pairs F/E (Full/Empty) or [I/D (Increment/Decrement)] and A/D (Ascending/Descending) or
[B/A (Before/After)] where FD or DB would be valid pairs, see relevant pair descriptions. <base> is the
Stack pointer, {!} defines if write back of the new value is to occur, <regs> is list of registers to save,
and {^} defines that if in a non USR mode, the regs saved will be from the USR set,
Not the current mode set of registers.
STMPLFD R9, {R1-R4} ; if positive store R1,R2,R3,R4, at address in R9, R9 is not updated with new address
STMED R1!, {R2,R4,R6} ; store R2,R4,R6 at address in R1, R1 is updated with R1-#12
SWP{cond} {S} {B} <dest>, <src>, [addrs] SWaP data at [addrs] into <dest>, and store <src> at same address N Z The <dest> and <src> may be the same, in which case the memory and register are swapped.
If the B option is selected then only a byte is transferred, if S is selected then flags are conditioned.
SWPGT R1, R1, R3 ; if > swap data at address R3 with data in R1
B{cond} <expression> Branch to a new location none This causes the execution to branch to a new location in the code, as usual the {cond} can be
added to make a more normal looking branch instruction. <expression> is the address where
the branch is to go, This would normally be a label which is defined else where.
BEQ reset ; if equal to zero branch to label reset
BVC no_overf ; if overflow flag clear branch to label no_overf
BAL finish ; always branch to label finish
BL{cond} <expression> Branch with Link, (branch saving the current location) none This command is used to implement subroutine calls, when it is called, R15 is automatically put
into R14, before the branch to <expression> occurs, then if the called routine needs to use R14 it
has to save it first. To return from a subroutine all that is required is MOV R15, R14
BLMI neg ; if negative branch to subroutine neg,
. . . . some code . . . .
MOVS R15, R14 ; return from the branch, restoring original flags
SWI{cond} <expression> SoftWare Interupt none This is the users way of accessing the operating system. When called the processor will save the
return address in R14_SVC and branch to location 8, from here the operating system will read the
value of <expression> and perform some task dependent on that value, anything from making a
sound, or displaying something, to reading a key, this is fully dependent on the operating system.
SWILT write_char ; if less than write a character to the screen.
BIC{cond} {S} <dest>, <lhs>, <rhs> BIts Clear, a bitwise <lhs> AND NOT <rhs> result in <dest> N Z See the generic opcode XXX for more info. eg. 01100101 AND NOT 10110011 = 01000100 BICS R0, R0, R5 ; zero unwanted bits with R5, then set flags
BIC R0, R0, #&20 ; convert char to caps by clearing bit 5
LDC{cond} {L},<cp#>,<dest>,[<base>,<offset>]{!} or [<base>],<offset> LoaD Co-processor registers using Pre-indexing or Post-indexing. none <cp#> is the co-processor number, <dest> is the co-processor reg to which the data is to be
transferred <base> is the reg with the base address of the location required. <offset> is an
optional value added to the <base>, the <offset> is an immediate number +/-1020 bytes.
The {L} option allows multiple registers to be loaded, it is up to the co-processor how many
registers are transferred For Pre-indexing there is not normally write back, ie the
<base> + <offset> once used, is not stored, however if a ! is used after the command, the
new calculated <base> will be stored. e.g.
LDC 1, F0, [R2, #-4]! ; load reg. F0 on co-proc #1, from address in R2-#4 then R2=R2-#4.
LDCL 1, F0, [R2, #-16]! ; load 4 regs. F0-F3 on co-proc #1, starting at address in R2-#16 then R2=R2-#16.
For Post-indexing the <offset> is not added to <base> until after the the store occurs, write-back always
occurs, so no ! is needed. e.g.
LDCL 1, F0, [R2], #16 ; load 4 regs. starting from address in R2, to regs. F0-F3, on co-proc #1, then R2=R2+#16
A special form LDC <cp#>,<dest>,<expresn>, where <expresn> yields an address, this will use the PC
as <base> and add the <expression> if this is not in the range +/-1020 an error is given.
LDC 1, F1, label ; load value at label into F1 on co-proc. #1
STC{cond} {L},<cp#>,<dest>,[<base>,<offset>]{!} or [<base>],<offset> STore Co-processor registers using Pre-indexing or Post-indexing. none <cp#> is the co-processor number, <dest> is the co-processor reg. from which the data is to be
transferred <base> is the reg. with the base address of the location required. <offset> is an
optional value added to the <base>, the <offset> is an immediate number +/-1020 bytes.
The {L} option allows multiple registers to be stored, it is up to the co-processor how many
registers are transfered. For Pre-indexing there is not normally write back, ie the
<base> + <offset> once used, is not stored, however if a ! is used after the command, the
New calculated <base> will be stored. e.g.
STC 1, F0, [R2, #-4]! ; store reg. F0 on co-proc #1, to address in R2-#4 then R2=R2-#4.
STCL 1, F0, [R2, #-16]! ; store 4 regs. F0-F3 on co-proc #1, starting at address in R2-#16 then R2=R2-#16.
For Post-indexing the <offset> is not added to <base> until after the the store occurs, write-back always
occurs, so no ! is needed. eg.
STCL 1, F0, [R2], #16 ; store 4 regs. starting from address in R2, from regs. F0-F3 on co-proc #1, then R2=R2+#16
A special form STC <cp#>,<dest>,<expresn>, where <expresn> yields an address, this will use the PC as
<base> and add the <expression> if this is not in the range +/-1020 an error is given.
STC 1, F1, label ; store reg. F1 on co-proc. #1, to label. (not wise!)
MCR{cond} <cp#>, <o>, <ARM dest>, <lhs>, <rhs>, {info} Move Co-processor Register to ARM
This command allows 32 bit values to be transferred from the co-processor to the ARM. {cond} is the
condition code, <o> is the operation required, <ARM dest> is the ARM register to which the data
is to be transferred, <lhs> and <rhs> are co-processor register numbers, {info} any extra information.
Apart from <cp#> the exact interpretation of the fields is not fixed, and depends on the co-processor.

MRC{cond} <cp#>, <o>, <ARM src>, <lhs>, <rhs>, {info} Move Register from AMR to Co-processor
This command allows 32 bit values to be transferred from the ARM to a co-processor. {cond} is the
condition code, <o> is the operation required, <ARM src> is the ARM register from which the data
is taken, <lhs> and <rhs> are co-processor register numbers, {info} any extra information.
Apart from <cp#> the exact interpretation of the fields is not fixed, and depends on the co-processor.

CDP{cond} <cp#>, <p>, <o>, <lhs>, <rhs>, {info} Co-processor Data Processing
This instruction is passed on to co-processor <cp#>. {cond} is the normal condition code, telling it to
perform operation <p>, on co-processor registers <lhs> and <rhs> placing result into <o>. {info} may
supply additional information about the operation concerned. Apart from co-processor number <cp#>
the above is only a recommendation and is entirely defined by how the co-processor interprets data.

MRS{cond} {S} <type>, <data> Move status RegiSter. ( ARM>=6 ) none MRS is used for transferring a status register to a processor register. The S bit, when set means
access the SPSR of the current privileged mode, rather than the CPSR. This bit must only be set
when in privileged mode. R15 should not be specified as destination register of an MRS instruction.
MRS R4, CPSR ; save proc status to register R4
MSR{cond} {S} <type>, <data> Move to Status Register transfer Load. ( ARM>=6 ) All, if requested. MSR is used for transferring a register or constant to a status register. The S bit, when set means
access the SPSR of the current privileged mode, rather than the CPSR. This bit must only be set
when in privileged mode. R15 should not be specified as the source register of an MSR instruction.
MSR SPSR_all, R3 ; set control and flag bits of the PSR from R3.
MSR CPSR_flg, #&F0000000 ; set only flag bits using constant
MSREQ CPSR_ctl, R2 ; if equal set only the control bits from R2
EA or [DB(load) or IA(store)] Empty Ascending stack [Decrement Before or Increment After]
These are not mnemonics, but a code added to STM or LDM commands to decide how data is to
be stored. Empty means that the stack pointer points at the next Empty location.
Ascending means that the stack pointer gets incremented as the stack gets filled.
STMEA R13!, {R1,R2} ; puts R1 low in memory, i.e. at end of stack
LDMEA R13!, {R1,R2} ; restores R1 and R2 or the same thing could be done with:
STMIA R13!, {R1,R2} ; puts R1 low in memory, i.e. at end of stack
LDMDB R13!, {R1,R2} ; restores R1 and R2
ED or [IB(load) or DA(store)] Empty Descending stack [Increment Before or Decrement After]
These are not mnemonics, but a code added to STM or LDM commands to decide how data is to
be stored. Empty means that the stack pointer points at the next Empty location.
Descending means that the stack pointer gets decremented as the stack gets filled
STMED R13!, {R1,R2} ; puts R1 low in memory, i.e. at top of stack
LDMED R13!, {R1,R2} ; restores R1 and R2 or the same thing could be done with:
STMDA R13!, {R1,R2} ; puts R1 low in memory, i.e. at top of stack
LDMIB R13!, {R1,R2} ; restores R1 and R2
FA or [DA(load) or IB(store)] Full Ascending stack [Decrement After or Increment Before]
These are not mnemonics, but a code added to STM or LDM commands to decide how data is to
be stored. Full means that the stack pointer points to the last item put on the stack.
Ascending means that the stack pointer gets Incremented as the stack gets filled.
STMFA R13!, {R1,R2} ; puts R1 low in memory, i.e. at end of stack
LDMFA R13!, {R1,R2} ; restores R1 and R2 or the same thing could be done with:
STMIB R13!, {R1,R2} ; puts R1 low in memory, i.e. at end of stack
LDMDA R13!, {R1,R2} ; restores R1 and R2
FD or [IA(load) or DB(store)] Full Descending stack [Increment After or Decrement Before]
These are not mnemonics, but a code added to STM or LDM commands to decide how data is to
be stored. Full means that the stack pointer points to the last item put on the stack.
Descending means that the stack pointer gets Decremented as the stack gets filled.
STMFD R13!, {R1,R2} ; puts R1 low in memory, i.e. at top of stack
LDMFD R13!, {R1,R2} ; restores R1 and R2 or the same thing could be done with:
STMDB R13!, {R1,R2} ; puts R1 low in memory, i.e. at top of stack
LDMIA R13!, {R1,R2} ; restores R1 and R2