Science Zero
[ Science ] [ Electronics ] [ Experiments ] [ Computing ] [ About us ] [ Links ]

 

History The original ARM design was a stroke of pure genious that was decades ahead of it's time. The development started in 1983 and the first chips were produced two years later.

Today it is everywhere but the original beauty has faded somewhat as different attempts at improvement have been done. The original instructionset will live on as it is timeless.

       

Hardware vectors Possible contents (Acorn)
&00 Reset B branchThru0error
&04 Undefined instruction LDR PC,UndHandler
&08 SWI B decodeSWI
&0C Prefetch abort LDR PC,PabHandler
&10 Data abort LDR PC,DabHandler
&14 Address exception LDR PC,AexHandler
&18 IRQ B handleIRQ
&1C FIQ FIQ code...

 

The Processor Status Register (PSR) is the 8 bits MMNZCVIF. (ROL #6)
The Program Counter (PC) is the 24 address bits.

Register 15 (PC) definition:
MSB NZCVIFAAAAAAAAAAAAAAAAAAAAAAAAMM LSB

N Negative flag
Z Zero flag
C Carry flag
V Overflow flag
I Interrupt request disable
F Fast interrupt request disable
A Address bits. The two LSBs are always zero, so they are used as mode bits.
M Mode bits
"00"  User mode (USR mode)
"01"  Fast interrupt processing mode (FIQ)
"10"  Interrupt processing mode (IRQ)
"11"  Supervisor mode (SVC)
Private registers

R8 - R14
R13, R14
R13, R14


The instruction set
Description syntax:
  <> Optional.
  (x|y) Either x or y but not both.
  #exp Expression.
  Rn Register number(0-15).

<shift> indicates one of the following:
  ASL (Rn|#exp) Arithmetic shift left by contents of Rn or #exp
  LSL (Rn|#exp) Logical shift left.
  ASR (Rn|#exp) Arithmetic shift right.
  LSR (Rn|#exp) Logical shift right.
  ROR (Rn|#exp) Rotate right.
  RRX Rotate right one bit with extend. LSB -> C, C -> MSB
  ASL and LSL are the same, but LSL is preferred.
  #exp has a range of 0-31.


Condition codes <cond>

AL Always This is the default
CC Carry clear C=0
CS Carry set C=1
EQ Equal Z=1
GE Greater than or equal N=V
GT Greater than N=V and Z=0
HI Higher (unsigned) C=1 and Z=0
LE Less than or equal N<>V or Z=1
LS Lower or same (unsigned) C=0 or Z=1
LT Less than N<>V
MI Negative N=1
NE Not equal Z=0
NV Never ** Do not use **
PL Positive N=0
VC Overflow clear V=0
VS Overflow set V=1
LO Lower (unsigned) Same as CC
HS Higher/same (unsigned) Same as CS



Arithmetic and logical instructions
opcode<cond><S> Rd,<Rn>,(#exp|Rm<,shift>)
#exp has a range of X ROR N*2 where X=0-255 and N=0-15
ADC Add with carry Rd=Rn+Rm+C
ADD Add Rd=Rn+Rm
SBC Subtract with carry Rd=Rn-Rm-(1-C)
SUB Subtract Rd=Rn-Rm
RSC Reverse subtract with carry Rd=Rm-Rn-(1-C)
RSB Reverse subtract Rd=Rm-Rn
AND Bitwise AND Rd=Rn AND Rm
BIC Bitwise AND NOT Rd=Rn AND (NOT Rm)
ORR Bitwise OR Register Rd=Rn OR Rm
EOR Bitwise EOR Rd=Rn EOR Rm
MOV Move Rd=Rm
MVN Move NOT Rd=NOT Rm
If the "S" is present the condition codes may be altered.
The condition codes N,Z,C,V are set by the ALU in arithmetic operations.
The bitwise operations set N and Z from the ALU and C from the shifter.

Special actions are taken if any of the source registers are R15:
If Rm=R15 all 32 bits of R15(PC+PSR) are used in the operation.
If Rn=R15 only the 24 bits of the PC are used in the operation.

If the destination register is R15, then the action depends on "S"
If "S" is not present only then 24 bits of the PC are used
If "S" is present the whole result is written to R15, depending on mode.


Comparisons
opcode<cond><S|P> Rn,(#exp|Rm<,shift>)
CMN Compare Rn+Rm
CMP Compare Rn-Rm
TEQ Test equal Rn EOR Rm
TST Test Rn AND Rm
These are similar to the arithmetic and logical instructions
except that they do not take a destination register.
"P" can set the PSR to a given value if in a privileged mode.


Multiply instructions
opcode<cond><S> Rd,Rm,Rs
opcode<cond><S> Rd,Rm,Rs,Rn
MUL Multiply Rd=Rm*Rs
MLA Multiply-accumulate Rd=Rm*Rs+Rn
Integer multiplication returns 32LSB of product of two 32bit operands. Rd must not be R15 or same as Rm. Timing is dependent of Rs. If "S" is given, N and Z are set on the result, C and V are undefined.


Branching instructions
opcode<cond> expression
B Branch PC = PC + expression
BL Branch and link R14 = PC + 4 & PSR, PC = PC + expression


Single register load/store instructions
opcode<cond><B><T> Rd,(address|#exp)
#exp has a range of +-4095 bytes.
LDR Load Register  
STR Store Register  
"B" Byte transfer.
"T" Force address translation from a privileged mode. (Not pre-index!)
"!" Update Rn after use

 

  pre-index   post-index
  [Rn]  
  [Rn, #exp]<!>   [Rn], #exp
  [Rn, <->Rm]<!>   [Rn], <->Rm
  [Rn, <->Rm, shift #s]<!>   [Rn], <->Rm, shift #s
The PSR is never modified.
The PSR flags are not used if Rn=R15. (PC is 8 bytes ahead, pipelining!)
The PSR flags are used when the PC is used as Rm.


Multiple load/store instructions
opcode<cond>type Rn<!>,{Rlist}<^>
LDM Load Registerlist  
STM Store Registerlist  

"!" update Rn after use
For a load with R15 in the list "^" forces update of the PSR.
Otherwise "^" forces the load/store to access the User mode registers.
Rn is taken from the current bank, so update of Rn goes to the User bank.
Rlist is a list of register to transfer in a low to high order.


The four types of multiple transfer

  DA   Decrement Rn After   FD   Full Descending stack
  DB   Decrement Rn Before   ED   Empty Descending stack
  IA   Increment Rn After   FA   Full Ascending stack
  IB   Increment Rn Before   EA   Empty Ascending stack
In an empty stack the stack pointer points to first free slot.
In a full stack the  stack pointer points to the last slot written to.
An ascending stack grows from low to high memory addresses.
A descending stack grows from high to low memory addresses.

You can always load the base register(Rn).
Only if Rn is the lowest register then the original Rn is stored.
This will only have effect if you use "!".

If R15 is in the Rlist:
  The PSR is saved with the PC, the PC is 12 bytes ahead.
  The PSR is only loaded if you use "^", the mode decides what to update.

If R15 is used as Rn:
  The PSR is used as a part of the address!.
  Write back is switched off.


SWI instruction
opcode<cond> <expression>
SWI Software interrupt  

The R14_svc will be corrupted if you execute a SWI in SVC mode.


Sample Code
(If you can do improve on this then let us know!)

Pseudorandom number generator        sub     r0, r0, r0, ror #7
Square root algorithm
r0 = sqr(r1)

.sqr   mov     r0, #0
       mov     r3, #1<<15
.sl    orr     r0, r0, r3
       mul     r2, r0, r0
       cmp     r2, r1
       bichi   r0, r0, r3
       movnes  r3, r3, lsr #1
       bne     sl
       mov     pc, r14

32 by 8 bit multiplication (ARM1) .mul   mov     r2, #0
       movs    r0, r0, lsl #25
       addcs   r2, r2, r1, lsl #7
       addmi   r2, r2, r1, lsl #6
       movs    r0, r0, lsl #02
       addcs   r2, r2, r1, lsl #5
       addmi   r2, r2, r1, lsl #4
       movs    r0, r0, lsl #02
       addcs   r2, r2, r1, lsl #3
       addmi   r2, r2, r1, lsl #2
       movs    r0, r0, lsl #02
       addcs   r2, r2, r1, lsl #1
       addmi   r2, r2, r1, lsl #0
       mov     pc, r14
32 by 8 bit division .div   rsb     r1, r1, #0
       mov     r2, #0
       cmn     r0, r1, lsl #7
       addpl   r0, r0, r1, lsl #7
       addpl   r2, r2, #1<<7
       cmn     r0, r1, lsl #6
       addpl   r0, r0, r1, lsl #6
       addpl   r2, r2, #1<<6
       cmn     r0, r1, lsl #5
       addpl   r0, r0, r1, lsl #5
       addpl   r2, r2, #1<<5
       cmn     r0, r1, lsl #4
       addpl   r0, r0, r1, lsl #4
       addpl   r2, r2, #1<<4
       cmn     r0, r1, lsl #3
       addpl   r0, r0, r1, lsl #3
       addpl   r2, r2, #1<<3
       cmn     r0, r1, lsl #2
       addpl   r0, r0, r1, lsl #2
       addpl   r2, r2 ,#1<<2
       cmn     r0, r1, lsl #1
       addpl   r0, r0, r1, lsl #1
       addpl   r2, r2, #1<<1
       cmn     r0, r1, lsl #0
       addpl   r0, r0, r1, lsl #0
       addpl   r2, r2, #1<<0
       mov     pc, r14