| 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 |