Sei sulla pagina 1di 30

Il processore ARM

Breve introduzione
v1.4 (29/5/2007) M.Moro DEI UNIPD

1. Il modello di programmazione

1.0 Memoria
ARM (Advanced Risc Machine) è un processore a 32 bit ma è in grado di manipolare dati da 8 bit (byte) e 16 bit (halfword)
(Fig. 1). In memoria questi dati sono ordinati di default secondo la convenzione little endian.

Byte Byte Byte Byte 4 x 8 bit


Halfword Halfword 2 x 16 bit: allineati su frontiera multiplo di 2 byte
Word 1 x 32 bit: allineato su frontiera multiplo di 4 byte
Figura 1 - Tipi di dati

Le istruzioni che leggono byte o halfword da memoria eseguono un’estensione a 32 bit, diversa nel caso del trattamento di
valori con o senza segno.
Es.: LDRB R0, [R1]
Forma unsigned: carica in R0 il byte memorizzato all’indirizzo contenuto in R1. Il dato, prima di essere memorizzato
in R0, viene esteso in un word azzerandone i primi 24 bit.
Es.: LDRSB R0, [R1]
Forma signed: carica in R0 il byte memorizzato all’indirizzo contenuto in R1. Il dato, prima di essere memorizzato in
R0, viene esteso in un word estendendo il segno ai primi 24 bit.
In queste note la locazione di memoria all’indirizzo <expr> sarà indicata come B[<expr>] se byte (8 bit), H[<expr>] se
halfword (16 bit), W[<expr>] se word (32 bit).

2.0 Modi d’esecuzione


La versione 4 del processore ARM supporta sette modi di funzionamento (processor mode). (Tabella 1)

Processor mode Descrizione Codifica M[4:0]


1 User (usr) Modo d’esecuzione dei programmi comuni. 0b10000
2 FIQ (fiq) Gestione di interrupt veloce. 0b10001
3 IRQ (irq) Gestione di interrupt generico. 0b10010
4 Supervisor (svc) Modo protetto per l’esecuzione di codice del sistema operativo. 0b10011
5 Abort (abt) Errore nell’accesso di memoria 0b10111
(anche per implementare memoria virtuale o protezione della memoria).
6 Undefined (und) Istruzione illegale. 0b11011
7 System (sys) Modo provilegiato d’esecuzione di un task del sistema operativo. 0b11111
Tabella 1 - Modi di esecuzione
Il modo può essere cambiato via software, in modalità privilegiata, oppure per effetto di una eccezione. Di solito i programmi
utente vengono eseguiti in modo User; gli altri modi, noti come modi privilegiati, sono utilizzati per accedere alle risorse
protette o per servire le eccezioni. Per questo motivo non è possibile passare dal modo User ad un modo protetto se non
attraverso un’eccezione (un’istruzione di software interrupt, un’interruzione esterna o altra eccezione).

3.0 Registri
Il processore ARM è dotato di 37 registri: 31 sono registri generici, 6 sono registri di stato (dei quali 5 sono di salvataggio).
Tre dei registri generali hanno anche un significato speciale: R13 (SP) viene utilizzato come Stack Pointer a supporto della
realizzazione di subroutine e routine di servizio, R14 (LR) viene utilizzato come Link Register per memorizzare l’indirizzo di
ritorno in una chiamata a subroutine (vedi istruzione BL), R15 (PC) è il Program Counter. I registri sono organizzati in banchi
parzialmente sovrapposti (Tabella 2), un banco di registri associato ad ogni processor mode (il modo System utilizza lo stesso
banco del modo User). Nel modo corrente sono visibili 15 registri d’uso generale (dal R0 al R14), uno o due registri di stato
(quello corrente ed eventualmente quello di salvataggio) ed il PC. Tutti i registri, tranne quelli di stato, possono essere utilizzati
1
da tutte le istruzioni di tipo generale.
Es.: Se il processore si trova nello stato “IRQ” (Interrupt), l’istruzione MOV PC, R14 copia il valore del registro R14 relativo
al modo “IRQ” (R14_irq) nel registro PC. Notare che R14_irq è fisicamente un registro diverso da R14 in modo “usr”,
nonostante vengano indicati dalla stessa sigla mnemonica.

Modo
User Supervisor Abort Undefined Interrupt Fast
(usr)/ (svc) (abt) (und) (IRQ) inturrupt
system (FIQ)
(sys)
R0 R0 R0 R0 R0 R0
R1 R1 R1 R1 R1 R1
R2 R2 R2 R2 R2 R2
R3 R3 R3 R3 R3 R3
R4 R4 R4 R4 R4 R4
R5 R5 R5 R5 R5 R5
R6 R6 R6 R6 R6 R6
R7 R7 R7 R7 R7 R7
R8 R8 R8 R8 R8 R8_FIQ
R9 R9 R9 R9 R9 R9_FIQ
R10 R10 R10 R10 R10 R10_FIQ
R11 R11 R11 R11 R11 R11_FIQ
R12 R12 R12 R12 R12 R12_FIQ
R13 R13_SVC R13_ABT R13_UNDEF R13_IRQ R13_FIQ
R14 R14_SVC R14_ABT R14_UNDEF R14_IRQ R14_FIQ
PC=R15 PC PC PC PC PC

CPSR CPSR CPSR CPSR CPSR CPSR


SPSR_SVC SPSR_ABT SPSR_UNDEF SPSR_IRQ SPSR_FIQ
Tabella 2 – Registri (con sfondo grigio sono indicati i 37 registri fisici distinti)
La presenza di una coppia specifica di registri R13(SP)/R14(LR) per ogni modo facilita l’associazione ai singoli modi di uno
stack privato e rende più efficiente il ritorno da eccezione.
Nel modo “FIQ” esiste una copia ‘fisica’ anche dei registri da R8 a R12: quest’accorgimento permette di servire una chiamata
ad un’interruzione ‘veloce’ senza dover salvare quei registri, ottenendo una maggiore efficienza nella realizzazione della
corrispondente routine di servizio.
Il CPSR (Current Program Status Register) è il registro di stato ed è illustrato in Figura 2. Include i bit di condizione (i 4 bit
più significativi), le maschere per le interruzioni e la codifica del processor mode.

Bit di Bit di controllo


condizione

31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
M M M M M
N Z C V Riservati I F T 4 3 2 2 0

Figura 2 - Registro di stato


M0-M4 definiscono il modo di processore (vedi Tab. 1);
F indica lo stato di disabilitazione (valore 1) dei "Fast Interrupt" (FIQ)
I indica lo stato di disabilitazione (valore 1) delle interruzioni "generiche" (IRQ).
V Overflow: bit di condizione overflow per l'aritmetica con segno in complemento a due.
C Carry: bit di condizione carry per l'aritmetica senza segno e shift.
Z Zero: indica il risultato di un’operazione pari a zero.
N Negative: indica il risultato di un’operazione negativo.
I bit di condizione (V, C, Z e N) possono essere modificati in accordo con il risultato di una qualsiasi istruzione d’elaborazione
dei dati (ADD, SUB, RSC ecc.). Tuttavia, con l’eccezione delle istruzioni di "Compare" (CMP e CMN) e di "Test" (TEQ e
TST), le istruzioni d’elaborazione dei dati non alterano i bit di condizione a meno che il bit S (Set Condition Codes)
dell'istruzione non sia impostato a 1. Questo si ottiene posponendo la lettera al simbolo operativo dell’istruzione (ADDS,
SUBS, RSCS, ecc.). Per le istruzioni CMP, CMN, TEQ e TST, il bit S e' sempre attivo.
2
I bit N, Z e C possono essere modificati da tutte le istruzioni d’elaborazioni dei dati, mentre il flag V (Overflow) è modificabile
solo dalle operazioni aritmetiche (ADC, ADD, CMN, CMP, RSB, RSC, SBC, SUB).
Per quanto riguarda in particolare il bit C, le istruzioni additive (ADCS, ADDS, CMN) impostano a 1 il bit C se nella somma
risulta un riporto dal bit piu` significativo; quelle sottrattive (CMP, RSBS, RSCS, SBCS, SUBS) impostano a 0 il bit C se nella
differenza risulta un prestito nel bit piu` significativo; le istruzioni di tipo logico e di movimento (ANDS, EORS, MOVS,
MVNS, ORRS, TEQ, TST) impostano il bit C con il valore del carry in uscita allo shifter (vedi Modo di indirizzamento 1); se
l'istruzione e` una moltiplicazione, il bit C assume un valore non prevedibile.
Il registro SPSR (Saved Program Status Register) ha il compito di preservare il valore di CPSR durante la gestione di
un’eccezione. Come si vede dalla Tabella 2, c’è uno SPSR per ogni modo del processore tranne che per il modo User/System,
durante il quale non è prevista la gestione di un’eccezione.

4.0 Istruzioni condizionate


Quattro bit della codifica di ogni istruzione sono riservati per indicare le condizioni che devono essere preliminarmente
soddisfatte (valutando i bit di condizione) perché l’istruzione venga effettivamente eseguita. A questo scopo, ogni simbolo
operativo d’istruzione può essere esteso con le lettere illustrate nella Tabella 3. Nel caso in cui non sia specificata alcuna
condizione, si assume implicitamente la condizione AL.

Estensione Significato Flag di condizione Opcode


mnemonica [31:28]
EQ Uguali Z=1 0000
NE Non uguali Z=0 0001
CS/HS Carry Attivato / Senza segno maggiore o uguale C=1 0010
CC/LO Carry Disattivato / Senza segno minore C=0 0011
MI Negativo N=1 0100
PL Positivo o Zero N=0 0101
VS Overflow V=1 0110
VC Non Overflow V=0 0111
HI Senza segno maggiore C=1 e Z=0 1000
LS Senza segno minore o uguale C=0 o Z=1 1001
GE Con segno maggiore o uguale N=V 1010
LT Con segno minore N!=V 1011
GT Con segno maggiore Z=0 e N=V 1100
LE Con segno minore o uguale Z=1 o N!=V 1101
AL Sempre (è il default) - 1110
NV Mai - 1111
Tabella 3 - Condizioni

5.0 Stack
Lo stack è una struttura di tipo LIFO (Last-In First-Out) solitamente utilizzata dai microprocessori per salvare
momentaneamente i registri (o il contesto) prima dell’esecuzione di una subroutine o di una routine di servizio al fine di
garantirne la rientranza. Questo vale in particolare nel caso ARM per il registro LR che deve essere salvato (su uno stack)
prima che dall’interno di una subroutine se ne chiami un’altra, al fine di ottenere il corretto ripristino della successione di
indirizzi di ritorno alle subroutine chiamanti. I registri vengono salvati nello stack in una determinata sequenza, e recuperati
normalmente nella sequenza inversa. Come già detto, il registro SP (R13) viene convenzionalmente utilizzato per identificare
l'indirizzo della testa di uno stack in memoria che cresce per indirizzi decrescenti.
Nei processori ARM, gli stack vengono facilmente gestiti tramite le istruzioni LDM (Load Multiple Register) e STM (Store
Multiple Register). Quattro formati di stack diversi sono supportati (Tab.4, Fig. 3), ognuno dei quali può essere specificato
utilizzando un’appropriata sigla di due caratteri posposta al simbolo operativo LDM/STM. Gli stack possono essere di tipo
"full stack" o di tipo "empty stack" a seconda che SP punti rispettivamente all'ultimo dato inserito o alla prima posizione di
memoria libera (dopo l'ultimo dato inserito). Inoltre possono essere di tipo "ascendente" o "discendente" a seconda che SP
venga incrementato o decrementato per effetto dell'inserimento. Per ulteriori dettagli si veda la descrizione del modo di
indirizzamento 4 e delle due istruzioni LDM/STM.

3
Istruzione Modo d’indirizzamento Tipo di stack
LDM (Load) IA (Increment After) FD (Full Descending)
STM (Store) IA (Increment After) EA (Empty Ascending)
LDM (Load) IB (Increment Before) ED (Empty Descending)
STM (Store) IB (Increment Before) FA (Full Ascending)
LDM (Load) DA (Decrement After) FA (Full Ascending)
STM (Store) DA (Decrement After ) ED (Empty Descending)
LDM (Load) DB (Decrement Before) EA (Empty Ascending)
STM (Store) DB (Decrement Before) FD (Full Descending)
Tabella 4 - Tipi di istruzioni LDM/STM per stack

FA EA ED FD

Memoria
Bassa
SP SP
SP SP
Memoria
Alta

Memoria occupata Memoria libera


Figura 3 - Tipi di stack

6.0 Eccezioni
Nel processore ARM sono previsti 7 tipi d’eccezione (un’ottavo tipo, Address Exception, citato nella tabella per completezza,
si riferisce ad una particolare modalità operativa con address space ridotto a 26 bit, in queste note non descritta). Associato a
ciascun tipo di eccezione v’è un indirizzo denominato ‘vettore d’eccezione’ (hard vector) (Tab. 5). L’elaborazione di una
eccezione, tra l’altro, forza il PC ad assumere il valore del corrispondente vettore. Di norma a quell’indirizzo è collocata
un’istruzione di salto alla corrispondente routine di servizio: solo per l’ultima eccezione (FIQ), non essendoci altri vettori che
seguono nella tabella, all’indirizzo del corrispondente vettore può direttamente iniziare la sua RSI.

Hard vector (Hex) Funzione Modo


0x00000000 Reset SVC
0x00000004 Undef. Inst. UNDEF
0x00000008 Soft. Int.(SWI) SVC
0x0000000c Prefetch Abort ABORT
0x00000010 Data Abort ABORT
0x00000014 Address Excep. SVC
0x00000018 IRQ Interrupt IRQ
0x0000001c FIQ Interrupt FIQ

Tabella 5 - Eccezioni nel processore ARM


Quando viene sollevata un'eccezione e inizia la corrispondente elaborazione, vengono eseguite le seguenti azioni:

; salva il contenuto del PC nel registro LR


; corrispondente all’eccezione in corso di elaborazione
R14_<exception_mode> = PC

; salva il registro di stato nella copia di salvataggio


; corrispondente all’eccezione in corso di elaborazione
SPSR_<exception_mode> = CPSR

4
; aggiorna il registro di stato col modo di processore.
CPSR[4:0] = <identificativo eccezione>

; se il modo d’eccezione è Reset o FIQ allora


; disabilita le interruzioni ‘veloci’ (imposta a 1 il bit F)
if <exception_mode> == (Reset or FIQ) then CPSR[6] = 1

; disabilita le interruzioni ‘comuni’ (imposta a 1 bit I )


CPSR[7] = 1

; salta all'indirizzo del corrispondente vettore


PC = <exception hard vector>

L’indirizzo di ritorno, salvato nel registro R14_<exception_mode> dipende dal tipo di eccezione:
- non prevedibile per l’eccezione ‘Reset’,
- è l’indirizzo dell’istruzione che ha provocato l’eccezione + 4 nei casi ‘Undefined Instruction’, ‘Software Interrupt’,
‘Prefetch Abort’;
- è l’indirizzo dell’istruzione che ha provocato l’eccezione + 8 nel caso ‘Data Abort’,
- è l’indirizzo della prossima istruzione nel codice interrotto + 4 nei casi IRQ e FIQ.
Pertanto, conclusa la routine di servizio, il ritorno al codice interrotto ha luogo eseguendo, con un'istruzione atomica, il
ripristino di CPSR e PC; ciò può essere attuato:
- utilizzando un’istruzione di elaborazione dati con destinazione PC e bit S impostato (si ricordi che le istruzioni ADDS
R15, Rn, SUBS R15, Rn, MOVS R15, Rn, oltre a caricare in R15 (PC) il valore di Rn, caricano nel CPSR il valore di
SPSR_<modo>;
- utilizzando l'istruzione di caricamento multiplo (LDM), specificando nella lista dei registri destinazione anche R15 (nel
qual caso viene anche caricato il valore di SPSR_<modo> nel CPSR).

Viene ora fornita una breve descrizione delle eccezioni e, per ciascuna, un esempio di istruzione di ritorno.

1.0.0 Tipi d’eccezione

Reset
Eccezione generata dal fronte di discesa del segnale di reset: consente di inizializzare il processore (non è previsto un ritorno).

Undefined Instruction
Eccezione generata internamente alla CPU quando è stato eseguito il fetch di una codifica di istruzione non valida. Viene
talvolta utilizzata per emulare, con codifiche non valide, istruzioni aggiuntive realizzate via software
Es. istruzione di ritorno (all’istruzione emulata): MOVS PC, R14

Software Interrupt
Eccezione generata, come effetto principale, dall’apposita istruzione SWI (vedi descrizione dell’istruzione). La routine di
servizio assume di norma il ruolo di attivatore di una chiamata a sistema (operativo): il relativo codice viene pertanto eseguito
in modalità privilegiata.
Es. istruzione di ritorno: MOVS PC, R14

Prefetch Abort
Eccezione generata dal segnale di ingresso alla CPU "abort" nella fase di (pre)fetch di un’istruzione. Il segnale “abort”,
generalmente controllato dalla MMU (Memory Management Unit), viene generato nel tentativo di accedere ad un indirizzo di
memoria non valido. La RSI può essere utilizzata per l'implementazione della memoria virtuale.
Es. istruzione di ritorno (all’istruzione non caricata): SUBS PC, R14, #4

Data Abort
Come per ‘Prefetch Abort’ ma con segnale “abort” generato nella fase di esecuzione un’istruzione.
Es. istruzione di ritorno (all’istruzione non eseguita): SUBS PC, R14, #8
istruzione di ritorno (senza riesecuzione dell’istruzione): SUBS PC, R14, #4

IRQ (Interrupt Request)


Eccezione generata dal segnale d’ingresso alla CPU “IRQ”.
Es. istruzione di ritorno: SUBS PC, R14, #4

FIQ (Fast Interrupt Request)


Eccezione generata dal segnale d’ingresso alla CPU “FIQ”.
Es. istruzione di ritorno: SUBS PC, R14, #4

5
2.0.0 Gestione delle priorità dei dispositivi
Essendo le linee d’ingresso IRQ e FIQ uniche, i dispositivi di ciascuna delle due classi di interruzioni (normali e fast) devono
essere identificati in una fase iniziale della rispettiva routine di servizio (che inizia al corrispondente vettore d’interruzione
0x18 e 0x1c). Al fine di velocizzare tale fase di identificazione, e gestire correttamente le priorità tra i dispositivi, il sistema
può includere hardware aggiuntivo (interrupt controller). La sua presenza evita una lunga fase di polling dei dispositivi
presenti: attraverso la lettura di appositi registri del/i dispositivo/i di controllo, la routine di servizio può immediatamente
identificare qual è, tra i dispositivi che hanno una richiesta pendente, quello più prioritario e passare il controllo alla
corrispondente RSI specifica.

3.0.0 Priorità delle eccezioni


Nel caso che più eccezioni siano contemporaneamente pendenti (alcune combinazioni non sono peraltro possibili), il
processore ARM utilizza una priorità prefissata per decidere l'ordine nel quale esse devono essere servite; descritta in Tabella
6.

Eccezione Priorità
Reset 1 (maggiore)
Data abort 2
FIQ 3
IRQ 4
Prefetch abort 5
Undef. Instr. SWI 6 (minore)
Tabella 6 - Priorità delle eccezioni

6
2. Modalità d’indirizzamento
Le modalità di indirizzamento, ovvero i diversi modi con cui gli operandi delle istruzioni possono essere specificati, sono
raggruppate in 5 sottoinsiemi detti ‘modi d’indirizzamento’ (addressing mode). Ciascuno dei modi si applica ad un certo
sottoinsieme di istruzioni. La classificazione aiuta ad associare a ciascuna istruzione le modalità di indirizzamento ammesse
per i suoi operandi.

1.0 Modo 1: “Shifter operands for data-processing instructions”


Questo modo viene utilizzato nelle istruzioni d’elaborazione dei dati. Uno "shifter operand", che rappresenta il o uno degli
operandi sorgente, può assumere una delle di seguenti forme:

Immediate #<immediate>
L’operando è un valore immediato (costante). Il valore <immediate> è un valore costante da 8-bit ruotato a destra di un
numero pari di posizioni (0,2,4,..,28,30) in una parola da 32 bit. Nella codifica si usano, pertanto, 8 bit per memorizzare il
valore da ruotare e 4 bit per memorizzare la metà del numero di posizioni di rotazione da applicare. Ne consegue che non tutti i
valori rappresentabili con 32 bit sono riconducibili ad un valore da 8 bit ruotato; in particolare non sono costruibili in questo
modo valori rappresentati in binario con più di 8 bit pari a 1.
Esempio di valore valido: 0xf000000f che equivale a 0xff ruotato a destra di 4 bit (in una parola da 32 bit).
Esempio di valore non valido: 0xfff non è valido in quanto composto da più di 8 bit pari 1.
Es.:
MOV R0, #0 ; carica in R0 il valore immediato 0x0

Register Rm
L’operando Rm è un registro di uso comune (da R0 a R15)
Es.:
MOV R0, R1 ; carica in R0 il contenuto di R1
MOV PC, LR ; carica nel PC il contenuto di LR (equivalente a RETURN)

Logical shift left by immediate Rm, LSL #<immediate>


L’operando è rappresentato dal valore ottenuto dallo scorrimento logico a sinistra del contenuto del registro Rm di un numero
di posizioni indicato dalla costante da cinque bit <immediate> (quindi si possono applicare scorrimenti da 0 a 31 bit). Il
carry di uscita dallo shifter è pari al contenuto del bit C se la quantità di scorrimento è 0, altrimenti è pari all’ultimo bit uscito
nello scorrimento.
Es.:
MOV R0, R1, LSL #1 ; R0 <- R1*2

Logical shift left by register Rm, LSL Rs


L’operando è rappresentato dal valore ottenuto dallo scorrimento logico a sinistra del contenuto del registro Rm di un numero
di posizioni indicato dal byte meno significativo contenuto in Rs. Il carry di uscita dallo shifter è pari al contenuto del bit C se
la quantità di scorrimento è 0, altrimenti è pari all’ultimo bit uscito nello scorrimento.
Es.:
MOV R0, R1, LSL R2 ; R0 <- R1 * 2^R2

Logical shift right by immediate Rm, LSR #<immediate>


L’operando è rappresentato dal valore ottenuto dallo scorrimento logico a destra del contenuto del registro Rm di un numero di
posizioni indicato dalla costante da cinque bit <immediate> (quindi si possono applicare scorrimenti da 0 a 31 bit). Il carry
di uscita dallo shifter è pari al contenuto del bit C se la quantità di scorrimento è 0, altrimenti è pari all’ultimo bit uscito nello
scorrimento.
Es.:
MOV R0, R1, LSR #1 ; R0 <- R1/2 (unsigned)

Logical shift right by register Rm, LSR Rs


L’operando è rappresentato dal valore ottenuto dallo scorrimento logico a destra del contenuto del registro Rm di un numero di
posizioni indicato dal byte meno significativo contenuto in Rs. Il carry di uscita dallo shifter è pari al contenuto del bit C se la
quantità di scorrimento è 0, altrimenti è pari all’ultimo bit uscito nello scorrimento.

7
Es.:
MOV R0, R1, LSR R2 ; R0 <- R1 / 2^R2 (unsigned)

Arithmetic shift right by immediate Rm, ASR #<immediate>


L’operando è rappresentato dal valore ottenuto dallo scorrimento aritmetico a destra del contenuto del registro Rm di un
numero di posizioni indicato dalla costante da cinque bit <immediate> (quindi si possono compiere scorrimenti da 1 a 32
bit, essendo lo shift di 32 bit codificato con il valore immediato 0). Il carry di uscita dallo shifter è pari all’ultimo bit uscito
nello scorrimento.
Es.:
MOV R0, R0 ASR #2 ; R0 <- R2 / 4 (signed)

Arithmetic shift right by register Rm, ASR Rs


L’operando è rappresentato dal valore ottenuto dallo scorrimento aritmetico a destra del contenuto del registro Rm di un
numero di posizioni indicato dal byte meno significativo contenuto in Rs. Il carry di uscita dallo shifter è pari al contenuto del
bit C se la quantità di scorrimento è 0, altrimenti è pari all’ultimo bit uscito nello scorrimento.
Es.:
MOV R0, R1 ASR R2 ; R0 <- R1 / 2^R2 (signed)

Rotate right by immediate Rm, ROR #<immediate>


L’operando è rappresentato dal valore ottenuto dalla rotazione a destra del contenuto del registro Rm di un numero di posizioni
indicato dalla costante da cinque bit <immediate> (quindi si possono compiere rotazioni da 1 a 31 bit; il valore imemdiato 0
è riservato alla codifica ‘Rotate right with extend’, vedi sotto). Il carry di uscita dallo shifter è pari all’ultimo bit uscito nella
rotazione.
Es.:
MOV R0, R1 ROR #1 ; R0 <- R1 ruotato a destra di un bit

Rotate right by register Rm, ROR Rs


L’operando è rappresentato dal valore ottenuto dalla rotazione a destra del contenuto del registro Rm di un numero di posizioni
indicato dal byte meno significativo contenuto in Rs. Il carry di uscita dallo shifter è pari al contenuto del bit C se la quantità di
rotazione è 0, altrimenti è pari all’ultimo bit uscito nella rotazione.
Es.:
MOV R0, R1 ROR R2 ; R0 <- R1 ruotato a destra di R2 bit

Rotate right with extend Rm, RRX


L’operando è rappresentato dal valore ottenuto dalla rotazione a destra di una posizione su 33 bit del contenuto del registro Rm
e del bit C, utilizzando quest’ultimo come 33-esimo bit. Il carry di uscita dallo shifter è pari al bit meno significativo
originariamente contenuto in Rm.
Es.:
MOV R0, R1 RRX ; R0 <- R1 ruotato a destra con il carry di un bit

2.0 Modo 2: “Load and store word or unsigned byte”


Questo modo viene utilizzato per specificare l’indirizzo di memoria nelle istruzioni di load e store da/verso memoria di word
da 32 bit oppure di byte (8 bit) intesi come naturali (unsigned). La distinzione tra signed e unsigned nel caso di dati da 8 bit è
significativa nell’operazione di load su registro perché, nel caso unsigned, viene operata sul registro un’estensione a 32 bit con
bit pari a 0. Le modalità inserite in questa classe sono 9 e sono qui brevemente descritte.

Immediate offset [Rn, #+/-<offset di 12 bit>]

L’indirizzo dell’operando di memoria viene calcolato, a seconda del segno specificato dopo il simbolo #, come
somma/sottrazione tra il contenuto di Rn (registro base) ed un <offset di 12 bit>. Se viene specificato un offset nullo,
l'indirizzo prodotto è pari al contenuto del registro Rn.
Es.:
LDR R0, [R1, #CAMPO] ; R0 <- W[R1 + CAMPO]
LDRB R0, [R1] ; R0 <- B[R1] offset nullo

8
Immediate pre-indexed [Rn, #+/-<offset di 12 bit>]!

L’indirizzo dell’operando di memoria viene calcolato, a seconda del segno specificato dopo il simbolo #, come
somma/sottrazione tra il contenuto di Rn (registro base) ed un <offset di 12 bit>. Se viene specificato un offset nullo,
l'indirizzo prodotto è pari al contenuto del registro Rn. L’indirizzo calcolato viene anche caricato come nuovo valore di Rn.
Es.:
LDR R0, [R1, #4]! ; R1 <- R1+4; R0 <- W[R1]

Immediate post-indexed [Rn], #+/-<offset di 12 bit>

L’indirizzo dell’operando di memoria è rappresentato dal contenuto del registro base Rn. Successivamente viene calcolata, a
seconda del segno specificato dopo il simbolo #, la somma/sottrazione tra il contenuto di Rn ed un <offset di 12 bit> e caricata
come nuovo valore di Rn.
Es.:
LDR R0, [R1], #4 ; R0 <- W[R1]; R1 <- R1+4

Register offset [Rn, +/- Rm]

L’indirizzo dell’operando di memoria viene calcolato, a seconda del segno specificato, come somma/sottrazione tra il
contenuto di Rn (registro base) ed di Rm (registro indice), che esprime un offset (non costante).
Es.:
LDR R0, [R1, R2] ; R0 <- W[R1+R2]

Register pre-indexed [Rn, +/- Rm]!

L’indirizzo dell’operando di memoria viene calcolato, a seconda del segno specificato, come somma/sottrazione tra il
contenuto di Rn (registro base) ed di Rm (registro indice), che esprime un offset (non costante). L’indirizzo calcolato viene
anche caricato come nuovo valore di Rn.
Es.:
LDR R0, [R1, R2]! ; R1 <- R1+R2; R0 <- W[R1]

Register post-indexed [Rn], +/- Rm

L’indirizzo dell’operando di memoria è rappresentato dal contenuto del registro base Rn. Successivamente viene calcolata, a
seconda del segno specificato, la somma/sottrazione tra il contenuto di Rn ed di Rm (registro indice), che esprime un offset
(non costante), e caricata come nuovo valore di Rn.
Es.:
LDR R0, [R1], -R2 ; R0 <- W[R1]; R1 <- R1-R2

Scaled register offsets [Rn, +/-Rm, LSL #<immediate>]


[Rn, +/-Rm, LSR #<immediate>]
[Rn, +/-Rm, ASR #<immediate>]
[Rn, +/-Rm, ROR #<immediate>]
[Rn, +/-Rm, RRX]

L’indirizzo dell’operando di memoria viene calcolato, a seconda del segno specificato, come somma/sottrazione tra il
contenuto di Rn (registro base) ed di Rm (registro indice), che esprime un offset (non costante), dopo aver operato su
quest’ultimo uno/a scorrimento/rotazione così come specificato dall’istruzione (per una descrizione di queste operazioni di
scorrimento/rotazione si veda il modo 1).
Es.:
LDR R0, [R1, -R2, LSL #1] ; R0 <- W[R1-R2*2]

Scaled register pre-indexed [Rn, +/-Rm, LSL #<immediate>]!


[Rn, +/-Rm, LSR #<immediate>]!
[Rn, +/-Rm, ASR #<immediate>]!
[Rn, +/-Rm, ROR #<immediate>]!
[Rn, +/-Rm, RRX]!

L’indirizzo dell’operando di memoria viene calcolato, a seconda del segno specificato, come somma/sottrazione tra il
contenuto di Rn (registro base) ed di Rm (registro indice), che esprime un offset (non costante), dopo aver operato su
quest’ultimo uno/a scorrimento/rotazione così come specificato dall’istruzione (per una descrizione di queste operazioni di
9
scorrimento/rotazione si veda il modo 1). L’indirizzo calcolato viene anche caricato come nuovo valore di Rn.
Es.:
LDR R0, [R1, R2, LSL #1]! ; R1 <- R1+R2*2; R0 <- W[R1]

Scaled register post-indexed [Rn], +/-Rm, LSL #<immediate>


[Rn], +/-Rm, LSR #<immediate>
[Rn], +/-Rm, ASR #<immediate>
[Rn], +/-Rm, ROR #<immediate>
[Rn], +/-Rm, RRX

L’indirizzo dell’operando di memoria è rappresentato dal contenuto del registro base Rn. Successivamente viene calcolata, a
seconda del segno specificato, la somma/sottrazione tra il contenuto di Rn ed di Rm (registro indice), che esprime un offset
(non costante), dopo aver operato su quest’ultimo uno/a scorrimento/rotazione così come specificato dall’istruzione (per una
descrizione di queste operazioni di scorrimento/rotazione si veda il modo 1); il risultato di questo calcolo viene caricato come
nuovo valore di Rn.
Es.:
LDR R0, [R1], -R2, ASR #2 ; R0 <- W[R1]; R1 <- R1-R2/4

3.0 Modo 3: “Load and Store halfword or load signed byte”

Questo modo viene utilizzato per specificare l’indirizzo di memoria nelle istruzioni di load e store da/verso memoria di
halfword da 16 bit (signed e unsigned) oppure di byte (8 bit) intesi come interi (signed). La distinzione tra signed e unsigned
nel caso di dati da 8 o da 16 bit è significativa nell’operazione di load su registro perché, nel caso signed, viene operata sul
valore da caricare un’estensione a 32 bit con segno, mentre nel caso unsigned l’estensione è operata con bit pari a 0. Le
modalità inserite in questa classe sono 6 e sono grossomodo le stesse del modo 2, ad esclusione delle versioni scaled, in questa
classe non incluse, e del valore di offset immediato che è codificato con 8 bit e non con 12. Per la descrizione delle modalità di
questa classe si faccia pertanto riferimento alle descrizioni del modo 2.
Es.:
LDRH R0, [R1, #0xF0] ; R0 <- H[R1+0xF0]

STRB R0, [R1, -R2] ; B[R1-R2] <- R0

LDRSH R0, [R1, #4]! ; R1 <- R1+4; R0 <- ext32(H[R1])

STRH R0, [R1, R2]! ; R1 <- R1+R2; H[R1] <- R0

LDRSB R0, [R1], #4 ; R0 <- ext32(B[R1]); R1 <- R1+4

LDRB R0, [R1], R2 ; R0 <- B[R1]; R1 <- R1+R2

4.0 Modo 4: “Load and store multiple”

Questo modo viene utilizzato per specificare un sottoinsieme di registri sottoposti al caricamento/copia da/in memoria
mediante istruzioni di load/store multipli (LDM/STM). La convenzione adottata fissa l’ordine di copia in memoria:
procedendo per indirizzi crescenti, i registri vengono copiati in memoria per indice crescente (ad esempio, per il set R1, R4,
R5, R6, il registro R1 viene ad occupare l’indirizzo più basso, R6 quello più alto).

La sintassi per queste istruzioni è:

<istruzione><opzioni> <registro base>{!}, {lista di registri}{^}

La lista dei registri può essere specificata in vari modi: si possono elencare uno ad uno i registri separati da virgole (es.: R0,
R1, R5), si può specificare un intervallo di registri (es.: R0-R4) oppure si possono combinare i due modi. L'ordine con cui
vengono specificati i registri è ininfluente: nella codifica e negli effetti prodotti viene comunque utilizzato un ordine
predefinito. Il contenuto del registro base definisce l’indirizzo di memoria rispetto al quale avviene il caricamento; il registro
viene modificato se è presente l’opzione ‘!’. Se nell’istruzione è presente l’opzione ‘^’, nella sua codifica viene impostato a 1 il
bit S: nel caso LDM e qualora nella lista di registri sia presente PC, questo provoca il caricamento di CPSR dal SPSR del modo
corrente; nel caso LDM che non coinvolga PC e in tutti i casi STM, l’impostazione del bit provoca, anche se in modo
privilegiato, il coinvolgimento dei registri del banco user nelle operazioni di caricamento/copia (non pertanto quelli del banco
relativo al modo privilegiato corrente).

10
Nelle ‘opzioni’ è possibile specificare se il caricamento o il salvataggio devono essere ascendenti (incremento a partire
dall'indirizzo base) o discendenti (decremento a partire dall'indirizzo base); è possibile specificare pure se
l’incremento/decremento dell’indirizzo debba avvenire prima o dopo che esso viene utilizzato per accedere alla locazione
corrente di memoria.

Increment after LDM|STM{<cond>}IA Rn{!}, <registri>{^}

In questa modalità la successione di indirizzi di memoria è ottenuta partendo dal contenuto iniziale di Rn compreso
(corrisponde all’indirizzo più basso); gli indirizzi successivi al primo sono ottenuti con successivi incrementi di 4. Se è
presente l’opzione ‘!’, alla fine nel registro base Rn viene caricato l’ultimo indirizzo della successione + 4.
Es.:
STMIA R13, {R0-R7} ; W[R13] <- R0; W[R13+4] <- R1; ... W[R13+7*4] <- R7

LDMIA R13!, {R1, R4-R5} ; R1<-W[R13]; R4<-W[R13+4]; R5<-W[R13+8]; R13<-R13+12

Increment before LDM|STM{<cond>}IB Rn{!}, <registri>{^}

In questa modalità la successione di indirizzi di memoria è ottenuta partendo dal contenuto iniziale di Rn+4 (corrisponde
all’indirizzo più basso); gli indirizzi successivi al primo sono ottenuti con successivi incrementi di 4. Se è presente l’opzione
‘!’, alla fine nel registro base Rn viene caricato l’ultimo indirizzo della successione.
Es.:
STMIB R13, {R0, R3} ; W[R13+4] <- R0; W[R13+8] <- R3

LDMIB R13!, {R2-R5} ; R2<-W[R13+4]; ... R5<-W[R13+4*4]; R13<-R13+4*4

Decrement after LDM|STM{<cond>}DA Rd{!}, <registri>{^}

In questa modalità la successione di indirizzi di memoria è ottenuta partendo dal contenuto iniziale di Rn compreso
(corrisponde all’indirizzo più alto); gli indirizzi successivi al primo sono ottenuti con successivi decrementi di 4. Se è presente
l’opzione ‘!’, alla fine nel registro base Rn viene caricato il primo indirizzo (quello più basso) della successione - 4.
Es.:
LDMDA R13, {R4-R6} ; R4<-W[R13-8]; R5<-W[R13-4]; R6<-W[R13]

STMDA R13!, {R0, R3} ; W[R13-4]<-R0; W[R13]<-R3; R13<-R13-8

Decrement before LDM|STM{<cond>}DB Rd{!}, <registri>{^}

In questa modalità la successione di indirizzi di memoria è ottenuta partendo dal contenuto iniziale di Rn-4 (corrisponde
all’indirizzo più alto); gli indirizzi successivi al primo sono ottenuti con successivi decrementi di 4. Se è presente l’opzione ‘!’,
alla fine nel registro base Rn viene caricato il primo indirizzo (quello più basso) della successione.
Es.:
LDMDB R13, {R4, R6, R8} ; R4<-W[R13-12]; R6<-W[R13-8]; R8<-W[R13-4]

STMDB R13!, {R0-R1} ; W[R13-8]<-R0; W[R13-4]<-R1; R13<-R13-8

Per facilitare il trattamento di stack utilizzati per il salvataggio e ripristino dei registri macchina, possono essere utilizzati per il
modo 4 suffissi alternativi più vicini al significato delle operazioni su stack. I suffissi e le relative equivalenze sono illustrati in
tab. 7.

Tipo stack Commento Suffisso Istruzione Modalità


Full descending Lo SP si decrementa in inserimento e punta all’ultimo inserito FD LDM IA
(il più comune)
STM DB
Full ascending Lo SP si incrementa in inserimento e punta all’ultimo inserito FA LDM DA
STM IB
Empty descending Lo SP si decrementa in inserimento e punta al primo libero ED LDM IB
STM DA
Empty ascending Lo SP si incrementa in inserimento e punta al primo libero EA LDM DB
STM IA
Tabella 7 - Suffissi alternativi per le istruzioni LDM/STM
11
Es.:
STMFD R13!, {R0-R4} ; salva con push sullo stack i registri da R0 a R4
; equivale a: STMDB R13!, {R0-R4}

LDMFD R13!, {R0-R4} ; ripristina con pop sullo stack i registri da R0 a R4


; equivale a: LDMIA R13!, {R0-R4}

5.0 Modo 5: “Load and store coprocessor”

Questo modo viene utilizzato nelle istruzioni d’accesso ad un coprocessore (caricamento/salvataggio). Le 3 modalità incluse
nella classe producono una sequenza di indirizzi che consente al coprocessore di caricare/salvare da/in memoria dati di
ampiezza stabilita dal coprocessore stesso. La sequenza è ottenuta con incrementi successivi di 4 a partire dall’indirizzo
iniziale, calcolato in base alla modalità, e termina quando il coprocessore invia, durante il trasferimento, il segnale di fine. La
sequenza non può comunque essere composta da più di 16 word.

Immediate offset [Rn, #+/-(<offset di 8 bit>*4)]

In questa modalità la successione di indirizzi di memoria è ottenuta partendo dall’indirizzo calcolato, a seconda del segno
specificato dopo il simbolo #, come somma/sottrazione tra il contenuto di Rn (registro base) ed un offset pari a <offset di 8
bit>*4.
Es.:
STC p8, CR9, [R2, #4] ; W[R2+4+4*i]<-p8[CR9] 0<=i<=max<16
; p8 identifica il coprocessore,
; CR9 un suo registro

Immediate pre-indexed [Rn, #+/-(<offset di 8 bit>*4)]!

In questa modalità la successione di indirizzi di memoria è ottenuta partendo dall’indirizzo calcolato, a seconda del segno
specificato dopo il simbolo #, come somma/sottrazione tra il contenuto di Rn (registro base) ed un offset pari a <offset di 8
bit>*4. Il primo indirizzo viene anche caricato come nuovo valore nel registro base Rn.
Es.:
STC p8, CR9, [R2,#4]! ; R2<-R2+4; W[R2+4*i]<-p8[CR9] 0<=i<=max<16
; p8 identifica il coprocessore,
; CR9 un suo registro

Immediate post-indexed [Rn], #+/-(<offset di 8 bit>*4)

In questa modalità la successione di indirizzi di memoria è ottenuta partendo dall’indirizzo contenuto in Rn (registro base).
Successivamente viene calcolata, a seconda del segno specificato dopo il simbolo #, la somma/sottrazione tra il contenuto di
Rn ed un offset pari a <offset di 8 bit>*4, e caricata come nuovo valore del registro base Rn.

Es.:
STC p8, CR9, [R2], #4 ; W[R2+4*i]<-p8[CR9] 0<=i<=max<16; R2<-R2+4;
; p8 identifica il coprocessore,
; CR9 un suo registro

12
3. Le istruzioni
In questa sezione vengono illustrate le istruzioni dei processori ARM, corredate da sintassi e breve descrizione, divise in
categorie funzionali. Il suffisso di condizione (<cond>), che può essere aggiunto in talune istruzioni, esprime la condizione
booleana che deve essere verificata perché l’istruzione cui si applica venga effettivamente eseguita (vedi sez. 1.4). I bit di
condizione (contenuti nel registro di stato) per default non vengono alterati dalle istruzioni, a meno che il bit S (Set Condition
Codes) dell'istruzione non sia impostato ad 1. Questo si ottiene posponendo il suffisso S al simbolo operativo dell’istruzione
(ADDS, SUBEQS, RSCS, ecc.). Per le istruzioni CMP, CMN, TEQ e TST, il bit S è sempre attivo.

1.0 Istruzioni per l’elaborazione dei dati


In questa classe vi sono le istruzioni che effettuano una elaborazione che coinvolge dati immediati e/o dati contenuti in registri
generali, producendo un risultato che può essere caricato in un registro e può modificare i bit di condizione. Se il registro di
destinazione è PC (R15) e il bit S è impostato a 1, il contenuto del registro SPSR relativo al modo di funzionamento corrente
del processore viene copiato in CPSR.

ADC Add with Carry: ADC{<cond>}{S} Rd, Rn, <shifter_operand>


Se S=1 modifica i bit N,Z,C,V
<shifter_operand> espresso con Modo 1

Somma il contenuto di Rn con <shifter_operand> e il valore del bit carry (C), e carica il risultato in Rd. Viene utilizzata di
solito per eseguire somme in precisione estesa (> 32 bit).
Es.:
; somma su 64 bit, R0-R1 primo operando, R2-R3 secondo operando
; in R4-R5 il risultato
ADDS R4, R0, R2 ; somma i bit meno significativi
ADC R5, R1, R3 ; somma i bit più significativi

ADD Add: ADD{<cond>}{S} Rd, Rn, <shifter_operand>


Se S=1 modifica i bit N,Z,C,V
<shifter_operand> espresso con Modo 1

Somma il contenuto di Rn con <shifter_operand> e carica il risultato in Rd.


Es.:
ADD R0, R0, #1 ; R0 <- R0 + 1

AND Bitwise logical AND: AND{<cond>}{S} Rd, Rn, <shifter_operand>


Se S=1 modifica i bit N,Z,C
<shifter_operand> espresso con Modo 1

Effettua un’operazione di and bit a bit tra il contenuto di Rn e lo <shifter_operand>, e carica il risultato in Rd.
Es.:
AND R0, R1, #0xff000000 ; ‘estrae’ i primi 8 bit da
; R1 e li memorizza in R0

BIC Bit Clear: BIC{<cond>}{S} Rd, Rn, <shifter_operand>


Se S=1 modifica i bit N,Z,C
<shifter_operand> espresso con Modo 1

Effettua un’operazione di and bit a bit tra il contenuto di Rn e il complemento a uno dello <shifter_operand>, e carica il
risultato in Rd. Interpretando lo <shifter_operand> come maschera, consente di azzerare singoli bit del contenuto di Rn.
Es.:
BIC R0, R0, #0xff000000 ; azzera i primi 8 bit di R0

CMN Compare Negative: CMN{<cond>} Rn, <shifter_operand>


Modifica i bit N,Z,C,V
<shifter_operand> espresso con Modo 1

Confronta aritmeticamente Rn con il complemento a due di <shifter_operand>, eseguendo la somma Rn+<shifter_operand> =

13
Rn - ( -<shifter_operand> ) e impostando i bit di condizione in base al risultato.
Es.:
CMN R0, R1, LSL #1 ; imposta i bit cond. in base a R0+R1*2

CMP Compare: CMP{<cond>} Rn, <shifter_operand>


Modifica i bit N,Z,C,V
<shifter_operand> espresso con Modo 1

Confronta aritmeticamente Rn con <shifter_operand>, eseguendo la differenza Rn-<shifter_operand> e impostando i bit di


condizione in base al risultato.
Es.:
CMP R0, R1, ASR #2 ; imposta i bit cond. in base a R0-R1/4

EOR Exclusive OR: EOR{<cond>}{S} Rd, Rn, <shifter_operand>


Se S=1 modifica i bit N,Z,C
<shifter_operand> espresso con Modo 1

Effettua un’operazione di or esclusivo bit a bit tra il contenuto di Rn e lo <shifter_operand>, e carica il risultato in Rd.
Interpretando lo <shifter_operand> come maschera, consente di invertire (negare) singoli bit del contenuto di Rn.
Es.:
EOR R0, R1, #6 ; R0 <- R1 con i bit di indice 1 e 2 negati

MLA Multiply Accumulate: MLA{<cond>}{S} Rd, Rm, Rs, Rn


Se S=1 modifica i bit N,Z,C (non prevedibile)

Moltiplica il contenuto del registro Rm col contenuto del registro Rs, somma il risultato al contenuto del registro Rn e carica il
risultato finale in Rd.
Es.:
MLA R3, R1, R2, R3 ; R3 <- R1 * R2 + R3

MOV Move: MOV{<cond>}{S} Rd, <shifter_operand>


Se S=1 modifica i bit N,Z,C
<shifter_operand> espresso con Modo 1

Carica nel registro Rd il contenuto di <shifter_operand>. Se modificati, i bit di condizioni vengono impostati in base al valore
caricato in Rd e al carry dello shifter.
Es.:
MOV R3, #0 ; R3 <- 0

MOVVSS R2, #0xf0000000 ; se V=1 allora R2<-0xf0000000, N<-1, Z<-0, C<-0

MOVS R0, R1, LSL #1 ; R0<-R1*2


; N<-sign(R1*2), Z<-(R1*2==0), C<-MSB(R1)

MOVMI R0, R0, LSR #8 ; se N=1 allora R0 <- R0>>8

MOV R0, R1, ROR #3 ; R0 <- R1 ruotato a destra di tre posizioni

MOVS PC, LR ; PC<-LR , CPSR=SPSR_<modo>


; ritorno da RSI

MUL Multiply: MUL{<cond>}{S} Rd, Rm, Rs


Se S=1 modifica i bit N,Z,C (non prevedibile)

Moltiplica il contenuto del registro Rm col quello del registro Rs e carica il risultato in Rd. Viene utilizzata per effettuare una
moltiplicazione di valori con o senza segno con risultato da 32 bit.
Es.:
MULEQ R0, R1, R2 ; se Z=1 allora R0 <- R1*R2

MVN Move Negative (Negated): MVN{<cond>}{S} Rd, <shifter_operand>


Se S=1 modifica i bit N,Z,C
14
<shifter_operand> espresso con Modo 1

Carica nel registro Rd il negato (complemento a uno) del contenuto di <shifter_operand>. Se modificati, i bit di condizioni
vengono impostati in base al valore caricato in Rd e al carry dello shifter.
Es.:
MVN R3, #0 ; R3 <- NOT(0) = 0xffffffff = -1

ORR Bitwise logical OR: ORR{<cond>}{S} Rd, Rn, <shifter_operand>


Se S=1 modifica i bit N,Z,C
<shifter_operand> espresso con Modo 1

Effettua un’operazione di or bit a bit tra il contenuto di Rn e lo <shifter_operand>, e carica il risultato in Rd. Interpretando lo
<shifter_operand> come maschera, consente di impostare a 1 singoli bit del contenuto di Rn.
Es.:
ORR R0, R0, 0x1 ; imposta a 1 il bit meno significativo di R0

RSB Reverse Subtract: RSB{<cond>}{S} Rd, Rn, <shifter_operand>


Se S=1 modifica i bit N,Z,C,V
<shifter_operand> espresso con Modo 1

Sottrae il contenuto di Rn allo <shifter_operand> e carica il risultato in Rd.


Es.:
RSB Rd, Rx, #0 ; Rd <- -Rx

RSB Rd, Rx, Rx LSL #3 ; Rd <- Rx*7

RSC Reverse Subtract with Carry: RSC{<cond>}{S} Rd, Rn, <shifter_operand>


Se S=1 modifica i bit N,Z,C,V
<shifter_operand> espresso con Modo 1

Sottrae il contenuto di Rn allo <shifter_operand> e al risultato il negato del bit C, e carica il risultato finale in Rd. Viene
utilizzata di solito per eseguire differenze in precisione estesa (> 32 bit).
Es.:
; complemento a due su 64 bit
; R0 bit meno significativi, R1 bit più significativi
RSBS R2, R0, #0 ; R2 <- -R0, C <- ! prestito
RSC R3, R1, #0 ; R3 <- -R1 - !C

SBC Subtract with Carry: SBC{<cond>}{S} Rd, Rn, <shifter_operand>


Se S=1 modifica i bit N,Z,C,V
<shifter_operand> espresso con Modo 1

Sottrae ad Rn il contenuto di <shifter_operand> e, al risultato, il valore negato del bit carry (C); carica poi il risultato in Rd.
Viene utilizzata di solito per eseguire differenze in precisione estesa (> 32 bit).
Es.:
; differenza su 64 bit, R0-R1 primo operando, R2-R3 secondo operando
; in R4-R5 il risultato
SUBS R4, R0, R2 ; sottrae i bit meno significativi
SBC R5, R1, R3 ; sottrae i bit più significativi

SMLAL Signed Multiply Accumulate Long: SMLAL{<cond>}{S} RdLo, RdHi, Rm, Rs


Se S=1 modifica i bit N,Z,C (non prevedibile), V (non prevedibile)

Moltiplica il contenuto del registro Rm con quello del registro Rs e somma il risultato su 64 bit con segno al contenuto di
RdLo (32 bit meno significativi) e RdHi (32 bit più significativi), tenendo presente un eventuale riporto dalla somma della
parte meno significativa a quella più significativa. Viene utilizzata per effettuare una moltiplicazione di valori con segno con
risultato da 64 bit.
Es.:
SMLAL R0, R1, R3, R4 ; [R1 R0] <- [R1 R0] + R3*R4 con segno

15
SMULL Signed Multiply Long: SMULL{<cond>}{S} RdLo, RdHi, Rm, Rs
Se S=1 modifica i bit N,Z,C (non prevedibile), V (non prevedibile)

Moltiplica il contenuto del registro Rm col quello del registro Rs e carica il risultato su 64 bit con segno in RdLo (32 bit meno
significativi) e RdHi (32 bit più significativi). Viene utilizzata per effettuare una moltiplicazione di valori con segno con
risultato da 64 bit.
Es.:
SMULL R0, R1, R3, R4 ; [R1 R0] <- R3*R4 con segno

SUB Subtract: SUB{<cond>}{S} Rd, Rn, <shifter_operand>


Se S=1 modifica i bit N,Z,C,V
<shifter_operand> espresso con Modo 1

Sottrae ad Rn il contenuto di <shifter_operand> e carica il risultato in Rd.


Es.:
SUB R0, R0, #8 ; R0 <- R0-8

TEQ Test Equivalence: TEQ{<cond>} Rn, <shifter_operand>


Modifica i bit N,Z,C
<shifter_operand> espresso con Modo 1

Confronta Rn con <shifter_operand>, eseguendo l’OR esclusivo bit a bit tra il contenuto di Rn e lo <shifter_operand>, e
impostando i bit di condizione in base al risultato. L’istruzione è adatta in particolare a verificare se i due operandi sono eguali
oppure se sono concordi.
Es.:
TEQ R0, R1, ROR #8 ; imposta i bit cond. in base a R0 XOR rotright(R1, 8)

TST Test: TST{<cond>} Rn, <shifter_operand>


Modifica i bit N,Z,C
<shifter_operand> espresso con Modo 1

Valuta alcuni bit di Rn, eseguendo l’AND bit a bit tra il contenuto di Rn e lo <shifter_operand>, e impostando i bit di
condizione in base al risultato. Interpretando lo <shifter_operand> come maschera, consente in particolare di valutare se i bit
selezionati dalla maschera sono tutti nulli o meno.
Es.:
TST R0, #3 ; imposta i bit cond. in base ai due bit meno significativi di R0

UMLAL Unsigned Multiply Accumulate Long: UMLAL{<cond>}{S} RdLo, RdHi, Rm, Rs


Se S=1 modifica i bit N,Z,C (non prevedibile), V (non prevedibile)

Moltiplica il contenuto del registro Rm col quello del registro Rs e somma il risultato su 64 bit senza segno al contenuto di
RdLo (32 bit meno significativi) e RdHi (32 bit più significativi), tenendo presente un eventuale riporto dalla somma della
parte meno significativa a quella più significativa. Viene utilizzata per effettuare una moltiplicazione di valori senza segno con
risultato da 64 bit..
Es.:
UMLAL R0, R1, R3, R4 ; [R1 R0] <- [R1 R0] + R3*R4 senza segno

UMULL Unsigned Multiply Long: SMULL{<cond>}{S} RdLo, RdHi, Rm, Rs


Se S=1 modifica i bit N,Z,C (non prevedibile), V (non prevedibile)

Moltiplica il contenuto del registro Rm col quello del registro Rs e carica il risultato su 64 bit senza segno in RdLo (32 bit
meno significativi) e RdHi (32 bit più significativi). Viene utilizzata per effettuare una moltiplicazione di valori senza segno
con risultato da 64 bit..
Es.:
SMULL R0, R1, R3, R4 ; [R1 R0] <- R3*R4 senza segno

2.0 Istruzioni per l’accesso alla memoria


In questa classe vi sono le istruzioni che effettuano il movimento di dati da memoria a registro (load) e viceversa (store). Come
si è già visto nella descrizione del modo di indirizzamento 2, vi sono alcune varianti per il caricamento di dati da 8 e 16 bit con
16
e senza segno, e per il movimento multiplo che coinvolge più registri.

LDM Load Multiple: LDM{<cond>}<addressing_mode> Rn{!}, <registers> {^}


Modo 4

Carica nei registri indicati da <registers> il contenuto di successivi word di memoria. Per la trattazione dettagliata si veda la
sezione 2.4.
Es.:
LDMEQIA R1!, {R2-R4, R6} ; se Z=1 allora carica in R2, R3, R4 e R6
; il contenuto delle locazioni
; W[R1], W[R1+4], W[R1+8], W[R1+12], e
; R1 <- R1+16

LDR Load Register: LDR{<cond>} Rd, <addressing_mode>


Modo 2
Carica nel registro Rd il contenuto del word di memoria il cui indirizzo è specificato con <addressing_mode>. Per la
trattazione dettagliata si veda la sezione 2.2.
Es.:
LDRPL R0, [R1], -R2 ; se N=0 allora R0 <- W[R1]; R1 <- R1-R2

LDRB Load Register Byte: LDR{<cond>}B Rd, <addressing_mode>


Modo 2

Carica nel registro Rd il contenuto del byte di memoria il cui indirizzo è specificato con <addressing_mode>, interpretato
come valore da 8 bit unsigned, pertanto esteso su 32 bit con bit 0 prima di essere caricato in Rd. Per la trattazione dettagliata si
veda la sezione 2.2.
Es.:
LDRMIB R0, [R1] ; se N=1 allora R0 <- B[R1]

LDRH Load Register Halfword: LDR{<cond>}H Rd, <addressing_mode>


Modo 3

Carica nel registro Rd il contenuto dello halfword di memoria il cui indirizzo è specificato con <addressing_mode>,
interpretato come valore da 16 bit unsigned, pertanto esteso su 32 bit con bit 0 prima di essere caricato in Rd. Per la trattazione
dettagliata si veda la sezione 2.3.
Es.:
LDRCSH R0, [R1, #20] ; se C=1 allora R0 <- H[R1+20]

LDRSB Load Register Signed Byte: LDR{<cond>}SB Rd, <addressing_mode>


Modo 3

Carica nel registro Rd il contenuto del byte di memoria il cui indirizzo è specificato con <addressing_mode>, interpretato
come valore da 8 bit signed, pertanto esteso su 32 bit con segno prima di essere caricato in Rd. Per la trattazione dettagliata si
veda la sezione 2.3.
Es.:
LDRVCSB R0, [R1, #-10] ; se V=0 allora R0 <- ext32(B[R1-10])

LDRSH Load Register Sign Halfword: LDR{<cond>}SH Rd, <addressing_mode>


Modo 3

Carica nel registro Rd il contenuto dello halfword di memoria il cui indirizzo è specificato con <addressing_mode>,
interpretato come valore da 16 bit signed, pertanto esteso su 32 bit con segno prima di essere caricato in Rd. Per la trattazione
dettagliata si veda la sezione 2.3.
Es.:
LDREQSH R0, [R1, R2]! ; se Z=1 allora R0 <- ext32(H[R1+R2]); R1 <- R1+R2

STM Store Multiple: STM{<cond>}<addressing_mode> Rn{!}, <registers> {^}


Modo 4

Copia il contenuto dei registri indicati da <registers> in successivi word di memoria. Per la trattazione dettagliata si veda la
sezione 2.4.
17
Es.:
STMNEDA R1, {R2-R4, R6} ; se Z=0 allora copia R2, R3, R4 e R6
; nelle locazioni
; W[R1], W[R1-4], W[R1-8], W[R1-12]

STR Store Register: STR{<cond>} Rd, <addressing_mode>


Modo 2
Copia il contenuto di Rd nel word di memoria il cui indirizzo è specificato con <addressing_mode>. Per la trattazione
dettagliata si veda la sezione 2.2.
Es.:
STR R0, [R1, R2, RRX]! ; W[R1+RotRightWithCarry(R2)] <- R0;
; R1 <- R1+RotRightWithCarry(R2)

STRB Store Register Byte: STR{<cond>}B Rd, <addressing_mode>


Modo 2

Copia il byte meno significativo contenuto in Rd nel byte di memoria il cui indirizzo è specificato con <addressing_mode>.
Per la trattazione dettagliata si veda la sezione 2.2.
Es.:
STRB R0, [R1, R2, LSL #1] ; B[R1+R2*2] <- R0B

STRH Store Register Halfword: STR{<cond>}H Rd, <addressing_mode>


Modo 3

Copia lo halfword meno significativo contenuto in Rd nello halfword di memoria il cui indirizzo è specificato con
<addressing_mode>. Per la trattazione dettagliata si veda la sezione 2.3.
Es.:
STRNEH R0, [R1], -R2 ; se Z=0 allora H[R1] <- R0H ; R1 <- R1-R2

3.0 Istruzioni di salto


Oltre a qualsiasi istruzione che abbia PC come registro destinazione, e che consente in generale di specificare un indirizzo di
salto nell’intero spazio di indirizzamento da 4Gbyte, i salti possono essere ottenuti eseguendo una delle due apposite istruzioni
di salto relativo. Esse sono B (Branch) e BL (Branch and Link): hanno l'effetto di caricare un nuovo valore nel registro PC
(R15), valore che viene calcolato come somma del PC corrente e dell’offset relativo specificato nella codifica dell’istruzione. È
compito dell’assemblatore calcolare tale offset dall’istruzione assembly che fa uso di solito di label: l’offset è riferito
all’indirizzo di caricamento dell’istruzione di salto+8. Il suo valore, diviso per 4, viene codificato in un campo da 24 bit con
segno, consentendo pertanto un salto relativo rispetto alla posizione dell’istruzione di salto di circa +/- 32 Mbyte.
BL preliminarmente copia il contenuto del PC nel registro LR (R14): tale contenuto è pari all’indirizzo dell’istruzione
successiva a BL. L’istruzione corrisponde quindi ad un salto a subroutine con salvataggio (in LR) dell’indirizzo di ritorno.

B Branch: B{<cond>} <target_address>

Carica nel registro PC l’indirizzo ricavato dalla somma del PC corrente (indirizzo dell’istruzione Branch + 8) e del valore
dell’offset codificato nell’istruzione, premoltiplicato per 4.
Es.:
B LAB1 ; salta al label "LAB1"

BEQ LAB2 ; se Z=1 allora salta al label “LAB”, altrimenti


; prosegue con l’istruzione successiva

BL Branch and Link: BL{<cond>} <target_address>

Copia nel registro LR (R14) l’indirizzo di ritorno (indirizzo dell’istruzione BL + 4) e carica nel registro PC l’indirizzo ricavato
dalla somma del PC corrente (indirizzo dell’istruzione BL + 8) e del valore dell’offset codificato nell’istruzione,
premoltiplicato per 4.
Es.:
BLVC SUBR1 ; se V=0 chiama la subroutine “SUBR1”

18
4.0 Interruzione software ed altre istruzioni speciali

MRS Move Register (Current) Status: MRS{<cond>} Rd, CPSR

Copia in Rd il contenuto del registro di stato corrente (CPSR).

MRS Move Register (Saved) Status: MRS{<cond>} Rd, SPSR

Copia in Rd il contenuto della copia attiva (quella relativa al modo di processore corrente) del registro di stato
(SPSR_<modo>). L’istruzione viene correttamente eseguita solo se il processore NON è in modo User o System.

MSR Move (Current) Status from Immediate: MSR{<cond>} CPSR_f, #32 bit immediate

Carica nel registro di stato corrente (CPSR) il valore immediato, codificato con una costante da 8 bit e una rotazione
(similmente alla modalità immediate del modo 1, vedi sez. 2.1). L’istruzione può essere usata solo per impostare i bit di
condizione in CPSR (31..24).

MSR Move (Current) Status from Register: MSR{<cond>} CPSR_<fields>, Rm

Carica nei campi specificati del registro di stato corrente (CPSR) i corrispondenti bit contenuti in Rm. I campi specificabili
<fields> sono: _c (control field, 7..0), _x (extension field, 15..8), _s (status field, 23..16), _f (flag field, 31..24). In modo User è
possibile modificare solo il campo _f (solo i bit di condizione; i bit 23..0 sono modificabili solo in modo privilegiato).

MSR Move (Saved) Status from Immediate: MSR{<cond>} SPSR_f, #32 bit immediate

Carica nella copia attiva nel modo corrente del registro di stato (SPSR_<modo>) il valore immediato, codificato con una
costante da 8 bit e una rotazione (similmente alla modalità immediate del modo 1, vedi sez. 2.1). L’istruzione può essere usata
solo in modalità diversa da User e System, e solo per impostare i bit di condizione in SPSR_<modo> (31..24).

MSR Move (Saved) Status from Register: MSR{<cond>} SPSR_<fields>, Rm

Carica nei campi specificati della copia attiva nel modo corrente del registro di stato (SPSR_<modo>) i corrispondenti bit
contenuti in Rm. I campi specificabili <fields> sono: _c (control field, 7..0), _x (extension field, 15..8), _s (status field, 23..16),
_f (flag field, 31..24). L’istruzione può essere usata solo in modalità diversa da User e System.

SWI Software Interrupt: SWI{<cond>} <24_bit_immediate>

Solleva l’eccezione SWI. È l’unico modo per passare esplicitamente da modo User a modo SVC. Consente di realizzare, nella
forma di routine di servizio dell’eccezione, una chiamata a sistema operativo. La selezione della chiamata può avvenire in base
al valore immediato codificato nell’istruzione o passando un parametro in altro modo. Per altri dettagli vedi sez. 1.6.

SWP Swap: SWP{<cond>} Rd, Rm, [Rn]

In un’unica operazione atomica, carica un word dalla locazione di memoria il cui indirizzo è contenuto in Rn, copia il
contenuto di Rm in quella locazione di memoria e carica in Rd il valore inizialmente letto dalla locazione. Se Rd == Rm,
l’istruzione effettua lo scambio dei contenuti del registro e della locazione di memoria. L’atomicità dell’operazione consente la
realizzazione di meccanismi di controllo (semafori) in architetture multiprocessore.

SWPB Swap Byte: SWP{<cond>}B Rd, Rm, [Rn]

In un’unica operazione atomica, carica un byte dalla locazione di memoria il cui indirizzo è contenuto in Rn, copia il byte
meno significativo contenuto in Rm in quella locazione di memoria e carica in Rd l’estensione su 32 bit operata con bit 0 del
valore inizialmente letto dalla locazione. Se Rd == Rm, l’istruzione effettua lo scambio tra il byte meno significativo del
registro e il contenuto della locazione di memoria. L’atomicità dell’operazione consente la realizzazione di meccanismi di
controllo (semafori) in architetture multiprocessore.

5.0 Altre istruzioni


Il set di istruzioni di ARM si completa con alcune altre istruzioni la cui descrizione va oltre lo scopo di queste brevi note. Per
un approfondimento si rimanda alla documentazione ufficiale ARM.

Istruzioni di coprocessore
19
Consentono la comunicazione tra CPU ed altri PU (coprocessori) presenti nel sistema. Per load/store le modalità di
indirizzamento utilizzabili sono quelle del modo 5.

CDP Coprocessor Data Processing:


CDP{<cond>} p<cp#>, <opcode_1>, CRd, CRn, CRm, <opcode_2>
LDC Load Coprocessor:
LDC{<cond>} p<cp#>, CRd, <addressing_mode>
MCR Move to Coprocessor from ARM Register:
MCR{<cond>} p<cp#>, <opcode_1>, Rd, CRn, CRm, <opcode_2>
MRC Move to ARM Register from Coprocessor:
MRC{<cond>} p<cp#>, <opcode_1>, Rd, CRn, CRm, <opcode_2>
STC Store Coprocessor:
STC{<cond>} p<cp#>, CRd, <addressing_mode>

Istruzioni con traduzione di modo

Vengono di norma eseguite in modo privilegiato in una routine di servizio di eccezione che emula una istruzione
inesistente. Dovendo emulare accessi in memoria che, se l’istruzione fosse effettivamente valida, avverrebero in modo
utente, il sistema di memoria viene notificato come se l’accesso avvenisse in modo utente e non nel modo corrente (che è
privilegiato).

LDRBT Load Register Byte with Translation:


LDR{<cond>}BT Rd, <post_indexed_addressing_mode>
LDRT Load Register with Translation:
LDR{<cond>}T Rd, <post_indexed_addressing_mode>
STRB Store Register Byte with Translation:
STR{<cond>}BT Rd, <post_indexed_addressing_mode>
STRT Store Register with Translation:
STR{<cond>}T Rd, <post_indexed_addressing_mode>

Istruzione con cambio di set di istruzioni

BX Branch and Exchange instruction set: BX{<cond>} Rm


Definita solo nella versione estesa 4T dell’ARM, il codice a partire dall’indirizzo contenuto in Rm verrà decodificato
utilizzando il set di istruzioni alternativo. In quella versione infatti esistono il set ARM e il set (ridotto) THUMB.

6.0 Alcuni esempi di codice

1.0.0 Salto a subroutine


. . .
BL SUBR1
. . .
. . .
SUBR1: . . .
. . .
MOV PC, LR ; return

2.0.0 Esecuzione condizionale


Si consideri un segmento di codice che calcola, con l’algoritmo di Euclide, il massimo comun divisore tra due naturali a e b.

Codice C
while(a != b)
if (a>b)
a -= b;
else
b -= a;
// in a il MCD

Codice assembly
20
@ a in R0, b in R1
LOOP: CMP R0, R1
SUBGT R0, R0, R1
SUBLT R1, R1, R0
BNE LOOP
@ in R0 il MCD

3.0.0 Espressioni con operatori di relazione


Codice C
if (a==1 || b == 2)
a++;

Codice assembly
@ a in R0, b in R1
CMP R0, #1
CMPNE R1, #2
ADDEQ R0, R0, #1
4.0.0 Jump table
Si debba saltare ad un punto di codice che dipende da un indice contenuto in R0. Gli indici validi vanno da 0 a MAX_INDEX-
1, CODESIZELOG2 rappresenta il massimo tra gli interi >= del logaritmo in base 2 della dimensione di ciascun segmento
relativo ai vari valori dell’indice. Si assume quindi questi segmenti siano collocati in successione ad una distanza in byte l’uno
dall’altro pari a CODESIZELOG2.

CMP R0, #MAX_INDEX


ADDLT PC, PC, R0, LSL # CODESIZELOG2
B INDEX_OUT_RANGE
CODE0: @ qui inizia il segmento di codice di indice 0
. . .
. . .
CODE1: @ qui inizia il segmento di codice di indice 1
. . .
. . .
. . .
. . .
CODE<MAX_INDEX-1>: @ qui inizia l’ultimo segmento di codice
. . .
. . .
INDEX_OUT_RANGE
. . .

Una versione alternativa fa uso di una ‘tabella di salto’ (jump table) che contiene i singoli indirizzi nell’ordine dato dall’indice.

CMP R0, #MAX_INDEX


LDRLT PC, [PC, R0, LSL #2] @ sizeof(indirizzo)=4
B INDEX_OUT_RANGE
@ qui inizia la tabella di salto
.WORD CODE0
.WORD CODE1
. . .
.WORD CODE<MAX_INDEX-1>

5.0.0 Semaforo
Una regione critica di codice può essere definita imponendo che, prima di iniziare la sua esecuzione, si acquisisca un ‘lock’
esclusivo rappresentato dal valore di un semaforo. Per consentire l’acquisizione indivisibile del lock da parte dei singoli
processi, ciò è realizzato utilizzando la speciale istruzione SWP.

@ R0 contiene l’indirizzo del semaforo


@ R1 contiene l’identificatore del processo
@ lock libero = 0
@ lock in acquisizione = -1
@ lock acquisito dal processo ID = ID > 0

21
INIZIO_SEZ_CRITICA:
MVN R2, #0 @ imposta lock in osservazione
WAIT1: SWP R3, R2, [R0] @ valuta ed eventualmente acquisisce lock
CMN R3, #1 @ attende se lock in osservazione da altri
BEQ WAIT1
@ lock acquisito da questo processo
CMP R3, #0 @ lock libero?
STRNE R3, [R0] @ no: riassegna il lock
@ al processo possessore e attende
BNE WAIT1
STR R1, [R0] @ lock libero, acquisisce
. . . @ sezione critica
. . .
FINE_SEZ_CRITICA:
WAIT2: SWP R3, R2, [R0] @ valuta lock
CMN R3, #1 @ attende se lock in osservazione da altri
BEQ WAIT2
CMP R3, R1 @ lock correttamente posseduto?
BNE SEMAFORO_CORROTTO @ stranamente non possiede il lock
MOV R2, #0 @ libera il lock
STR R2, [R0]

6.0.0 Chiamata a sistema


Il campo immediato da 24 bit nell’istruzione SWI viene utilizzato per indicare un indice che seleziona la specifica chiamata a
sistema. Con una tecnica simile alla jump table è possibili attivare la chiamata con il seguente codice iniziale della RSI
dell’eccezione SWI.

SWI_RSI:
STMFD SP!, {R12, ...} @ salva alcuni registri
LDR R12, [R14, #-4] @ carica la codifica di SWI
BIC R12, R12, 0xff000000 @ estrae campo immediato
CMP R12, #MAXSVC @ controllo range
LDRLE PC, [PC, R12, LSL #2] @ salta attraverso la tabella
B SVC_SCONOSCIUTO
.WORD SVC0
.WORD SVC1
. . .
.WORD SVC<MAXSVC-1>

22
ARM® and Thumb®-2 Instruction Set
Quick Reference Card

Key to Tables
Rm {, <opsh>} See Table Register, optionally shifted by constant <reglist> A comma-separated list of registers, enclosed in braces { and }.
<Operand2> See Table Flexible Operand 2. Shift and rotate are only available as part of Operand2. <reglist-PC> As <reglist>, must not include the PC.
<fields> See Table PSR fields. <reglist+PC> As <reglist>, including the PC.
<PSR> APSR (Application Program Status Register), CPSR (Current Processor Status Register), or SPSR <flags> Either nzcvq (ALU flags PSR[31:27]) or g (SIMD GE flags
(Saved Processor Status Register) PSR[19:16])
C*, V* Flag is unpredictable in Architecture v4 and earlier, unchanged in Architecture v5 and later. § See Table ARM architecture versions.
<Rs|sh> Can be Rs or an immediate shift value. The values allowed for each shift type are the same as those +/- + or –. (+ may be omitted.)
shown in Table Register, optionally shifted by constant. <iflags> Interrupt flags. One or more of a, i, f (abort, interrupt, fast interrupt).
x,y B meaning half-register [15:0], or T meaning [31:16]. <p_mode> See Table Processor Modes
<imm8m> ARM: a 32-bit constant, formed by right-rotating an 8-bit value by an even number of bits. SPm SP for the processor mode specified by <p_mode>
Thumb: a 32-bit constant, formed by left-shifting an 8-bit value by any number of bits, or a bit <lsb> Least significant bit of bitfield.
pattern of one of the forms 0xXYXYXYXY, 0x00XY00XY or 0xXY00XY00. <width> Width of bitfield. <width> + <lsb> must be <= 32.
<prefix> See Table Prefixes for Parallel instructions {X} RsX is Rs rotated 16 bits if X present. Otherwise, RsX is Rs.
{IA|IB|DA|DB} Increment After, Increment Before, Decrement After, or Decrement Before. {!} Updates base register after data transfer if ! present (pre-indexed).
IB and DA are not available in Thumb state. If omitted, defaults to IA. {S} Updates condition flags if S present.
<size> B, SB, H, or SH, meaning Byte, Signed Byte, Halfword, and Signed Halfword respectively. {T} User mode privilege if T present.
SB and SH are not available in STR instructions. {R} Rounds result to nearest if R present, otherwise truncates result.

Operation § Assembler S updates Action Notes


Add Add ADD{S} Rd, Rn, <Operand2> N Z C V Rd := Rn + Operand2 N
with carry ADC{S} Rd, Rn, <Operand2> N Z C V Rd := Rn + Operand2 + Carry N
wide T2 ADD Rd, Rn, #<imm12> Rd := Rn + imm12, imm12 range 0-4095 T, P
saturating {doubled} 5E Q{D}ADD Rd, Rm, Rn Rd := SAT(Rm + Rn) doubled: Rd := SAT(Rm + SAT(Rn * 2)) Q
Address Form PC-relative address ADR Rd, <label> Rd := <label>, for <label> range from current instruction see Note L N, L
Subtract Subtract SUB{S} Rd, Rn, <Operand2> N Z C V Rd := Rn – Operand2 N
with carry SBC{S} Rd, Rn, <Operand2> N Z C V Rd := Rn – Operand2 – NOT(Carry) N
wide T2 SUB Rd, Rn, #<imm12> Rd := Rn – imm12, imm12 range 0-4095 T, P
reverse subtract RSB{S} Rd, Rn, <Operand2> N Z C V Rd := Operand2 – Rn N
reverse subtract with carry RSC{S} Rd, Rn, <Operand2> N Z C V Rd := Operand2 – Rn – NOT(Carry) A
saturating {doubled} 5E Q{D}SUB Rd, Rm, Rn Rd := SAT(Rm – Rn) doubled: Rd := SAT(Rm – SAT(Rn * 2)) Q
Exception return without stack SUBS PC, LR, #<imm8> N Z C V PC = LR – imm8, CPSR = SPSR(current mode), imm8 range 0-255.
Parallel Halfword-wise addition 6 <prefix>ADD16 Rd, Rn, Rm Rd[31:16] := Rn[31:16] + Rm[31:16], Rd[15:0] := Rn[15:0] + Rm[15:0] G
arithmetic Halfword-wise subtraction 6 <prefix>SUB16 Rd, Rn, Rm Rd[31:16] := Rn[31:16] – Rm[31:16], Rd[15:0] := Rn[15:0] – Rm[15:0] G
Byte-wise addition 6 <prefix>ADD8 Rd, Rn, Rm Rd[31:24] := Rn[31:24] + Rm[31:24], Rd[23:16] := Rn[23:16] + Rm[23:16], G
Rd[15:8] := Rn[15:8] + Rm[15:8], Rd[7:0] := Rn[7:0] + Rm[7:0]
Byte-wise subtraction 6 <prefix>SUB8 Rd, Rn, Rm Rd[31:24] := Rn[31:24] – Rm[31:24], Rd[23:16] := Rn[23:16] – Rm[23:16], G
Rd[15:8] := Rn[15:8] – Rm[15:8], Rd[7:0] := Rn[7:0] – Rm[7:0]
Halfword-wise exchange, add, subtract 6 <prefix>ASX Rd, Rn, Rm Rd[31:16] := Rn[31:16] + Rm[15:0], Rd[15:0] := Rn[15:0] – Rm[31:16] G
Halfword-wise exchange, subtract, add 6 <prefix>SAX Rd, Rn, Rm Rd[31:16] := Rn[31:16] – Rm[15:0], Rd[15:0] := Rn[15:0] + Rm[31:16] G
Unsigned sum of absolute differences 6 USAD8 Rd, Rm, Rs Rd := Abs(Rm[31:24] – Rs[31:24]) + Abs(Rm[23:16] – Rs[23:16])
+ Abs(Rm[15:8] – Rs[15:8]) + Abs(Rm[7:0] – Rs[7:0])
and accumulate 6 USADA8 Rd, Rm, Rs, Rn Rd := Rn + Abs(Rm[31:24] – Rs[31:24]) + Abs(Rm[23:16] – Rs[23:16])
+ Abs(Rm[15:8] – Rs[15:8]) + Abs(Rm[7:0] – Rs[7:0])
Saturate Signed saturate word, right shift 6 SSAT Rd, #<sat>, Rm{, ASR <sh>} Rd := SignedSat((Rm ASR sh), sat). <sat> range 1-32, <sh> range 1-31. Q, R
Signed saturate word, left shift 6 SSAT Rd, #<sat>, Rm{, LSL <sh>} Rd := SignedSat((Rm LSL sh), sat). <sat> range 1-32, <sh> range 0-31. Q
Signed saturate two halfwords 6 SSAT16 Rd, #<sat>, Rm Rd[31:16] := SignedSat(Rm[31:16], sat), Q
Rd[15:0] := SignedSat(Rm[15:0], sat). <sat> range 1-16.
Unsigned saturate word, right shift 6 USAT Rd, #<sat>, Rm{, ASR <sh>} Rd := UnsignedSat((Rm ASR sh), sat). <sat> range 0-31, <sh> range 1-31. Q, R
Unsigned saturate word, left shift 6 USAT Rd, #<sat>, Rm{, LSL <sh>} Rd := UnsignedSat((Rm LSL sh), sat). <sat> range 0-31, <sh> range 0-31. Q
Unsigned saturate two halfwords 6 USAT16 Rd, #<sat>, Rm Rd[31:16] := UnsignedSat(Rm[31:16], sat), Q
Rd[15:0] := UnsignedSat(Rm[15:0], sat). <sat> range 0-15.
ARM and Thumb-2 Instruction Set
Quick Reference Card
Operation § Assembler S updates Action Notes
Multiply Multiply MUL{S} Rd, Rm, Rs N Z C* Rd := (Rm * Rs)[31:0] (If Rs is Rd, S can be used in Thumb-2) N, S
and accumulate MLA{S} Rd, Rm, Rs, Rn N Z C* Rd := (Rn + (Rm * Rs))[31:0] S
and subtract T2 MLS Rd, Rm, Rs, Rn Rd := (Rn – (Rm * Rs))[31:0]
unsigned long UMULL{S} RdLo, RdHi, Rm, Rs N Z C* V* RdHi,RdLo := unsigned(Rm * Rs) S
unsigned accumulate long UMLAL{S} RdLo, RdHi, Rm, Rs N Z C* V* RdHi,RdLo := unsigned(RdHi,RdLo + Rm * Rs) S
unsigned double accumulate long 6 UMAAL RdLo, RdHi, Rm, Rs RdHi,RdLo := unsigned(RdHi + RdLo + Rm * Rs)
Signed multiply long SMULL{S} RdLo, RdHi, Rm, Rs N Z C* V* RdHi,RdLo := signed(Rm * Rs) S
and accumulate long SMLAL{S} RdLo, RdHi, Rm, Rs N Z C* V* RdHi,RdLo := signed(RdHi,RdLo + Rm * Rs) S
16 * 16 bit 5E SMULxy Rd, Rm, Rs Rd := Rm[x] * Rs[y]
32 * 16 bit 5E SMULWy Rd, Rm, Rs Rd := (Rm * Rs[y])[47:16]
16 * 16 bit and accumulate 5E SMLAxy Rd, Rm, Rs, Rn Rd := Rn + Rm[x] * Rs[y] Q
32 * 16 bit and accumulate 5E SMLAWy Rd, Rm, Rs, Rn Rd := Rn + (Rm * Rs[y])[47:16] Q
16 * 16 bit and accumulate long 5E SMLALxy RdLo, RdHi, Rm, Rs RdHi,RdLo := RdHi,RdLo + Rm[x] * Rs[y]
Dual signed multiply, add 6 SMUAD{X} Rd, Rm, Rs Rd := Rm[15:0] * RsX[15:0] + Rm[31:16] * RsX[31:16] Q
and accumulate 6 SMLAD{X} Rd, Rm, Rs, Rn Rd := Rn + Rm[15:0] * RsX[15:0] + Rm[31:16] * RsX[31:16] Q
and accumulate long 6 SMLALD{X} RdLo, RdHi, Rm, Rs RdHi,RdLo := RdHi,RdLo + Rm[15:0] * RsX[15:0] + Rm[31:16] * RsX[31:16]
Dual signed multiply, subtract 6 SMUSD{X} Rd, Rm, Rs Rd := Rm[15:0] * RsX[15:0] – Rm[31:16] * RsX[31:16] Q
and accumulate 6 SMLSD{X} Rd, Rm, Rs, Rn Rd := Rn + Rm[15:0] * RsX[15:0] – Rm[31:16] * RsX[31:16] Q
and accumulate long 6 SMLSLD{X} RdLo, RdHi, Rm, Rs RdHi,RdLo := RdHi,RdLo + Rm[15:0] * RsX[15:0] – Rm[31:16] * RsX[31:16]
Signed top word multiply 6 SMMUL{R} Rd, Rm, Rs Rd := (Rm * Rs)[63:32]
and accumulate 6 SMMLA{R} Rd, Rm, Rs, Rn Rd := Rn + (Rm * Rs)[63:32]
and subtract 6 SMMLS{R} Rd, Rm, Rs, Rn Rd := Rn – (Rm * Rs)[63:32]
with internal 40-bit accumulate XS MIA Ac, Rm, Rs Ac := Ac + Rm * Rs
packed halfword XS MIAPH Ac, Rm, Rs Ac := Ac + Rm[15:0] * Rs[15:0] + Rm[31:16] * Rs[31:16]
halfword XS MIAxy Ac, Rm, Rs Ac := Ac + Rm[x] * Rs[y]
Divide Signed or Unsigned RM <op> Rd, Rn, Rm Rd := Rn / Rm <op> is SDIV (signed) or UDIV (unsigned) T
Move Move MOV{S} Rd, <Operand2> N Z C Rd := Operand2 See also Shift instructions N
data not MVN{S} Rd, <Operand2> N Z C Rd := 0xFFFFFFFF EOR Operand2 N
top T2 MOVT Rd, #<imm16> Rd[31:16] := imm16, Rd[15:0] unaffected, imm16 range 0-65535
wide T2 MOV Rd, #<imm16> Rd[15:0] := imm16, Rd[31:16] = 0, imm16 range 0-65535
40-bit accumulator to register XS MRA RdLo, RdHi, Ac RdLo := Ac[31:0], RdHi := Ac[39:32]
register to 40-bit accumulator XS MAR Ac, RdLo, RdHi Ac[31:0] := RdLo, Ac[39:32] := RdHi[7:0]
Shift Arithmetic shift right ASR{S} Rd, Rm, <Rs|sh> N Z C Rd := ASR(Rm, Rs|sh) Same as MOV{S} Rd, Rm, ASR <Rs|sh> N
Logical shift left LSL{S} Rd, Rm, <Rs|sh> N Z C Rd := LSL(Rm, Rs|sh) Same as MOV{S} Rd, Rm, LSL <Rs|sh> N
Logical shift right LSR{S} Rd, Rm, <Rs|sh> N Z C Rd := LSR(Rm, Rs|sh) Same as MOV{S} Rd, Rm, LSR <Rs|sh> N
Rotate right ROR{S} Rd, Rm, <Rs|sh> N Z C Rd := ROR(Rm, Rs|sh) Same as MOV{S} Rd, Rm, ROR <Rs|sh> N
Rotate right with extend RRX{S} Rd, Rm N Z C Rd := RRX(Rm) Same as MOV{S} Rd, Rm, RRX
Count leading zeros 5 CLZ Rd, Rm Rd := number of leading zeros in Rm
Compare Compare CMP Rn, <Operand2> N Z C V Update CPSR flags on Rn – Operand2 N
negative CMN Rn, <Operand2> N Z C V Update CPSR flags on Rn + Operand2 N
Logical Test TST Rn, <Operand2> N Z C Update CPSR flags on Rn AND Operand2 N
Test equivalence TEQ Rn, <Operand2> N Z C Update CPSR flags on Rn EOR Operand2
AND AND{S} Rd, Rn, <Operand2> N Z C Rd := Rn AND Operand2 N
EOR EOR{S} Rd, Rn, <Operand2> N Z C Rd := Rn EOR Operand2 N
ORR ORR{S} Rd, Rn, <Operand2> N Z C Rd := Rn OR Operand2 N
ORN T2 ORN{S} Rd, Rn, <Operand2> N Z C Rd := Rn OR NOT Operand2 T
Bit Clear BIC{S} Rd, Rn, <Operand2> N Z C Rd := Rn AND NOT Operand2 N
ARM and Thumb-2 Instruction Set
Quick Reference Card
Operation § Assembler Action Notes
Bit field Bit Field Clear T2 BFC Rd, #<lsb>, #<width> Rd[(width+lsb–1):lsb] := 0, other bits of Rd unaffected
Bit Field Insert T2 BFI Rd, Rn, #<lsb>, #<width> Rd[(width+lsb–1):lsb] := Rn[(width-1):0], other bits of Rd unaffected
Signed Bit Field Extract T2 SBFX Rd, Rn, #<lsb>, #<width> Rd[(width–1):0] = Rn[(width+lsb–1):lsb], Rd[31:width] = Replicate( Rn[width+lsb–1] )
Unsigned Bit Field Extract T2 UBFX Rd, Rn, #<lsb>, #<width> Rd[(width–1):0] = Rn[(width+lsb–1):lsb], Rd[31:width] = Replicate( 0 )
Pack Pack halfword bottom + top 6 PKHBT Rd, Rn, Rm{, LSL #<sh>} Rd[15:0] := Rn[15:0], Rd[31:16] := (Rm LSL sh)[31:16]. sh 0-31.
Pack halfword top + bottom 6 PKHTB Rd, Rn, Rm{, ASR #<sh>} Rd[31:16] := Rn[31:16], Rd[15:0] := (Rm ASR sh)[15:0]. sh 1-32.
Signed Halfword to word 6 SXTH Rd, Rm{, ROR #<sh>} Rd[31:0] := SignExtend((Rm ROR (8 * sh))[15:0]). sh 0-3. N
extend Two bytes to halfwords 6 SXTB16 Rd, Rm{, ROR #<sh>} Rd[31:16] := SignExtend((Rm ROR (8 * sh))[23:16]),
Rd[15:0] := SignExtend((Rm ROR (8 * sh))[7:0]). sh 0-3.
Byte to word 6 SXTB Rd, Rm{, ROR #<sh>} Rd[31:0] := SignExtend((Rm ROR (8 * sh))[7:0]). sh 0-3. N
Unsigned Halfword to word 6 UXTH Rd, Rm{, ROR #<sh>} Rd[31:0] := ZeroExtend((Rm ROR (8 * sh))[15:0]). sh 0-3. N
extend Two bytes to halfwords 6 UXTB16 Rd, Rm{, ROR #<sh>} Rd[31:16] := ZeroExtend((Rm ROR (8 * sh))[23:16]),
Rd[15:0] := ZeroExtend((Rm ROR (8 * sh))[7:0]). sh 0-3.
Byte to word 6 UXTB Rd, Rm{, ROR #<sh>} Rd[31:0] := ZeroExtend((Rm ROR (8 * sh))[7:0]). sh 0-3. N
Signed Halfword to word, add 6 SXTAH Rd, Rn, Rm{, ROR #<sh>} Rd[31:0] := Rn[31:0] + SignExtend((Rm ROR (8 * sh))[15:0]). sh 0-3.
extend Two bytes to halfwords, add 6 SXTAB16 Rd, Rn, Rm{, ROR #<sh>} Rd[31:16] := Rn[31:16] + SignExtend((Rm ROR (8 * sh))[23:16]),
with add Rd[15:0] := Rn[15:0] + SignExtend((Rm ROR (8 * sh))[7:0]). sh 0-3.
Byte to word, add 6 SXTAB Rd, Rn, Rm{, ROR #<sh>} Rd[31:0] := Rn[31:0] + SignExtend((Rm ROR (8 * sh))[7:0]). sh 0-3.
Unsigned Halfword to word, add 6 UXTAH Rd, Rn, Rm{, ROR #<sh>} Rd[31:0] := Rn[31:0] + ZeroExtend((Rm ROR (8 * sh))[15:0]). sh 0-3.
extend Two bytes to halfwords, add 6 UXTAB16 Rd, Rn, Rm{, ROR #<sh>} Rd[31:16] := Rn[31:16] + ZeroExtend((Rm ROR (8 * sh))[23:16]),
with add Rd[15:0] := Rn[15:0] + ZeroExtend((Rm ROR (8 * sh))[7:0]). sh 0-3.
Byte to word, add 6 UXTAB Rd, Rn, Rm{, ROR #<sh>} Rd[31:0] := Rn[31:0] + ZeroExtend((Rm ROR (8 * sh))[7:0]). sh 0-3.
Reverse Bits in word T2 RBIT Rd, Rm For (i = 0; i < 32; i++) : Rd[i] = Rm[31– i]
Bytes in word 6 REV Rd, Rm Rd[31:24] := Rm[7:0], Rd[23:16] := Rm[15:8], Rd[15:8] := Rm[23:16], Rd[7:0] := Rm[31:24] N
Bytes in both halfwords 6 REV16 Rd, Rm Rd[15:8] := Rm[7:0], Rd[7:0] := Rm[15:8], Rd[31:24] := Rm[23:16], Rd[23:16] := Rm[31:24] N
Bytes in low halfword, 6 REVSH Rd, Rm Rd[15:8] := Rm[7:0], Rd[7:0] := Rm[15:8], Rd[31:16] := Rm[7] * &FFFF N
sign extend
Select Select bytes 6 SEL Rd, Rn, Rm Rd[7:0] := Rn[7:0] if GE[0] = 1, else Rd[7:0] := Rm[7:0]
Bits[15:8], [23:16], [31:24] selected similarly by GE[1], GE[2], GE[3]
If-Then If-Then T2 IT{pattern} {cond} Makes up to four following instructions conditional, according to pattern. pattern is a string of up to three T, U
letters. Each letter can be T (Then) or E (Else).
The first instruction after IT has condition cond. The following instructions have condition cond if the
corresponding letter is T, or the inverse of cond if the corresponding letter is E.
See Table Condition Field for available condition codes.
Branch Branch B <label> PC := label. label is this instruction ±32MB (T2: ±16MB, T: –252 - +256B) N, B
with link BL <label> LR := address of next instruction, PC := label. label is this instruction ±32MB (T2: ±16MB).
and exchange 4T BX Rm PC := Rm. Target is Thumb if Rm[0] is 1, ARM if Rm[0] is 0. N
with link and exchange (1) 5T BLX <label> LR := address of next instruction, PC := label, Change instruction set. C
label is this instruction ±32MB (T2: ±16MB).
with link and exchange (2) 5 BLX Rm LR := address of next instruction, PC := Rm[31:1]. Change to Thumb if Rm[0] is 1, to ARM if Rm[0] is 0. N
and change to Jazelle state 5J BXJ Rm Change to Jazelle state if available
Compare, branch if (non) zero T2 CB{N}Z Rn,<label> If Rn {== or !=} 0 then PC := label. label is (this instruction + 4-130). N,T,U
Table Branch Byte T2 TBB [Rn, Rm] PC = PC + ZeroExtend( Memory( Rn + Rm, 1) << 1). Branch range 4-512. Rn can be PC. T, U
Table Branch Halfword T2 TBH [Rn, Rm, LSL #1] PC = PC + ZeroExtend( Memory( Rn + Rm << 1, 2) << 1). Branch range 4-131072. Rn can be PC. T, U
Move to or PSR to register MRS Rd, <PSR> Rd := PSR
from PSR register flags to APSR flags MSR APSR_<flags>, Rm APSR_<flags> := Rm
immediate flags to APSR flags MSR APSR_<flags>, #<imm8m> APSR_<flags> := immed_8r
register to PSR MSR <PSR>_<fields>, Rm PSR := Rm (selected bytes only)
immediate to PSR MSR <PSR>_<fields>, #<imm8m> PSR := immed_8r (selected bytes only)
Processor Change processor state 6 CPSID <iflags> {, #<p_mode>} Disable specified interrupts, optional change mode. U, N
state 6 CPSIE <iflags> {, #<p_mode>} Enable specified interrupts, optional change mode. U, N
change
Change processor mode 6 CPS #<p_mode> U
Set endianness 6 SETEND <endianness> Sets endianness for loads and stores. <endianness> can be BE (Big Endian) or LE (Little Endian). U, N
ARM and Thumb-2 Instruction Set
Quick Reference Card
Single data item loads and stores § Assembler Action if <op> is LDR Action if <op> is STR Notes
Load Immediate offset <op>{size}{T} Rd, [Rn {, #<offset>}]{!} Rd := [address, size] [address, size] := Rd 1, N
or store Post-indexed, immediate <op>{size}{T} Rd, [Rn], #<offset> Rd := [address, size] [address, size] := Rd 2
word, byte Register offset <op>{size} Rd, [Rn, +/-Rm {, <opsh>}]{!} Rd := [address, size] [address, size] := Rd 3, N
or halfword
Post-indexed, register <op>{size}{T} Rd, [Rn], +/-Rm {, <opsh>} Rd := [address, size] [address, size] := Rd 4
PC-relative <op>{size} Rd, <label> Rd := [label, size] Not available 5, N
Load or store Immediate offset 5E <op>D Rd1, Rd2, [Rn {, #<offset>}]{!} Rd1 := [address], Rd2 := [address + 4] [address] := Rd1, [address + 4] := Rd2 6, 9
doubleword Post-indexed, immediate 5E <op>D Rd1, Rd2, [Rn], #<offset> Rd1 := [address], Rd2 := [address + 4] [address] := Rd1, [address + 4] := Rd2 6, 9
Register offset 5E <op>D Rd1, Rd2, [Rn, +/-Rm {, <opsh>}]{!} Rd1 := [address], Rd2 := [address + 4] [address] := Rd1, [address + 4] := Rd2 7, 9
Post-indexed, register 5E <op>D Rd1, Rd2, [Rn], +/-Rm {, <opsh>} Rd1 := [address], Rd2 := [address + 4] [address] := Rd1, [address + 4] := Rd2 7, 9
PC-relative 5E <op>D Rd1, Rd2, <label> Rd1 := [label], Rd2 := [label + 4] Not available 8, 9

Preload data or instruction §(PLD) §(PLI) §(PLDW) Assembler Action if <op> is PLD Action if <op> is PLI Action if <op> is PLDW Notes
Immediate offset 5E 7 7MP <op> [Rn {, #<offset>}] Preload [address, 32] (data) Preload [address, 32] (instruction) Preload to Write [address, 32] (data) 1, C
Register offset 5E 7 7MP <op> [Rn, +/-Rm {, <opsh>}] Preload [address, 32] (data) Preload [address, 32] (instruction) Preload to Write [address, 32] (data) 3, C
PC-relative 5E 7 <op> <label> Preload [label, 32] (data) Preload [label, 32] (instruction) 5, C

Other memory operations § Assembler Action Notes


Load multiple Block data load LDM{IA|IB|DA|DB} Rn{!}, <reglist-PC> Load list of registers from [Rn] N, I
return (and exchange) LDM{IA|IB|DA|DB} Rn{!}, <reglist+PC> Load registers, PC := [address][31:1] (§ 5T: Change to Thumb if [address][0] is 1) I
and restore CPSR LDM{IA|IB|DA|DB} Rn{!}, <reglist+PC>^ Load registers, branch (§ 5T: and exchange), CPSR := SPSR. Exception modes only. I
User mode registers LDM{IA|IB|DA|DB} Rn, <reglist-PC>^ Load list of User mode registers from [Rn]. Privileged modes only. I
Pop POP <reglist> Canonical form of LDM SP!, <reglist> N
Load Semaphore operation 6 LDREX Rd, [Rn] Rd := [Rn], tag address as exclusive access. Outstanding tag set if not shared address.
exclusive Rd, Rn not PC.
Halfword or Byte 6K LDREX{H|B} Rd, [Rn] Rd[15:0] := [Rn] or Rd[7:0] := [Rn], tag address as exclusive access.
Outstanding tag set if not shared address. Rd, Rn not PC.
Doubleword 6K LDREXD Rd1, Rd2, [Rn] Rd1 := [Rn], Rd2 := [Rn+4], tag addresses as exclusive access 9
Outstanding tags set if not shared addresses. Rd1, Rd2, Rn not PC.
Store multiple Push, or Block data store STM{IA|IB|DA|DB} Rn{!}, <reglist> Store list of registers to [Rn] N, I
User mode registers STM{IA|IB|DA|DB} Rn{!}, <reglist>^ Store list of User mode registers to [Rn]. Privileged modes only. I
Push PUSH <reglist> Canonical form of STMDB SP!, <reglist> N
Store Semaphore operation 6 STREX Rd, Rm, [Rn] If allowed, [Rn] := Rm, clear exclusive tag, Rd := 0. Else Rd := 1. Rd, Rm, Rn not PC.
exclusive Halfword or Byte 6K STREX{H|B} Rd, Rm, [Rn] If allowed, [Rn] := Rm[15:0] or [Rn] := Rm[7:0], clear exclusive tag, Rd := 0. Else Rd := 1
Rd, Rm, Rn not PC.
Doubleword 6K STREXD Rd, Rm1, Rm2, [Rn] If allowed, [Rn] := Rm1, [Rn+4] := Rm2, clear exclusive tags, Rd := 0. Else Rd := 1 10
Rd, Rm1, Rm2, Rn not PC.
Clear exclusive 6K CLREX Clear local processor exclusive tag C

Notes: availability and range of options for Load, Store, and Preload operations
Note ARM Word, B, D ARM SB, H, SH ARM T, BT Thumb-2 Word, B, SB, H, SH, D Thumb-2 T, BT, SBT, HT, SHT
1 offset: – 4095 to +4095 offset: –255 to +255 Not available offset: –255 to +255 if writeback, –255 to +4095 otherwise offset: 0 to +255, writeback not allowed
2 offset: – 4095 to +4095 offset: –255 to +255 offset: – 4095 to +4095 offset: –255 to +255 Not available
3 Full range of {, <opsh>} {, <opsh>} not allowed Not available <opsh> restricted to LSL #<sh>, <sh> range 0 to 3 Not available
4 Full range of {, <opsh>} {, <opsh>} not allowed Full range of {, <opsh>} Not available Not available
5 label within +/– 4092 of current instruction Not available Not available label within +/– 4092 of current instruction Not available
6 offset: –255 to +255 - - offset: –1020 to +1020, must be multiple of 4. -
7 {, <opsh>} not allowed - - Not available -
8 label within +/– 252 of current instruction - - Not available -
9 Rd1 even, and not r14, Rd2 == Rd1 + 1. - - Rd1 != PC, Rd2 != PC -
10 Rm1 even, and not r14, Rm2 == Rm1 + 1. - - Rm1 != PC, Rm2 != PC -
ARM and Thumb-2 Instruction Set
Quick Reference Card
Coprocessor operations § Assembler Action Notes
Data operations CDP{2} <copr>, <op1>, CRd, CRn, CRm{, <op2>} Coprocessor defined C2
Move to ARM register from coprocessor MRC{2} <copr>, <op1>, Rd, CRn, CRm{, <op2>} Coprocessor defined C2
Two ARM register move 5E MRRC <copr>, <op1>, Rd, Rn, CRm Coprocessor defined
Alternative two ARM register move 6 MRRC2 <copr>, <op1>, Rd, Rn, CRm Coprocessor defined C
Move to coproc from ARM reg MCR{2} <copr>, <op1>, Rd, CRn, CRm{, <op2>} Coprocessor defined C2
Two ARM register move 5E MCRR <copr>, <op1>, Rd, Rn, CRm Coprocessor defined
Alternative two ARM register move 6 MCRR2 <copr>, <op1>, Rd, Rn, CRm Coprocessor defined C
Loads and stores, pre-indexed <op>{2} <copr>, CRd, [Rn, #+/-<offset8*4>]{!} op: LDC or STC. offset: multiple of 4 in range 0 to 1020. Coprocessor defined C2
Loads and stores, zero offset <op>{2} <copr>, CRd, [Rn] {, 8-bit copro. option} op: LDC or STC. Coprocessor defined C2
Loads and stores, post-indexed <op>{2} <copr>, CRd, [Rn], #+/-<offset8*4> op: LDC or STC. offset: multiple of 4 in range 0 to 1020. Coprocessor defined C2

Miscellaneous operations § Assembler Action Notes


Swap word SWP Rd, Rm, [Rn] temp := [Rn], [Rn] := Rm, Rd := temp. A, D
Swap byte SWPB Rd, Rm, [Rn] temp := ZeroExtend([Rn][7:0]), [Rn][7:0] := Rm[7:0], Rd := temp A, D
Store return state 6 SRS{IA|IB|DA|DB} SP{!}, #<p_mode> [SPm] := LR, [SPm + 4] := CPSR C, I
Return from exception 6 RFE{IA|IB|DA|DB} Rn{!} PC := [Rn], CPSR := [Rn + 4] C, I
Breakpoint 5 BKPT <imm16> Prefetch abort or enter debug state. 16-bit bitfield encoded in instruction. C, N
Secure Monitor Call Z SMC <imm4> Secure Monitor Call exception. 4-bit bitfield encoded in instruction. Formerly SMI.
Supervisor Call SVC <imm24> Supervisor Call exception. 24-bit bitfield encoded in instruction. Formerly SWI. N
No operation 6K NOP None, might not even consume any time. N, V
Hints Debug Hint 7 DBG Provide hint to debug and related systems.
Data Memory Barrier 7 DMB Ensure the order of observation of memory accesses. C
Data Synchronization Barrier 7 DSB Ensure the completion of memory accesses, C
Instruction Synchronization Barrier 7 ISB Flush processor pipeline and branch prediction logic. C
Set event 6K SEV Signal event in multiprocessor system. NOP if not implemented. N
Wait for event 6K WFE Wait for event, IRQ, FIQ, Imprecise abort, or Debug entry request. NOP if not implemented. N
Wait for interrupt 6K WFI Wait for IRQ, FIQ, Imprecise abort, or Debug entry request. NOP if not implemented. N
Yield 6K YIELD Yield control to alternative thread. NOP if not implemented. N

Notes
A Not available in Thumb state. P Rn can be the PC in Thumb state in this instruction.
B Can be conditional in Thumb state without having to be in an IT block. Q Sets the Q flag if saturation (addition or substraction) or overflow (multiplication) occurs. Read and
reset the Q flag using MRS and MSR.
C Condition codes are not allowed in ARM state. R <sh> range is 1-32 in the ARM instruction.
C2 The optional 2 is available from ARMv5. It provides an alternative operation. Condition codes are not S The S modifier is not available in the Thumb-2 instruction.
allowed for the alternative form in ARM state.
D Deprecated. Use LDREX and STREX instead. T Not available in ARM state.
G Updates the four GE flags in the CPSR based on the results of the individual operations. U Not allowed in an IT block. Condition codes not allowed in either ARM or Thumb state.
I IA is the default, and is normally omitted. V The assembler inserts a suitable instruction if the NOP instruction is not available.
L ARM: <imm8m>. 16-bit Thumb: multiple of 4 in range 0-1020. 32-bit Thumb: 0-4095.
N Some or all forms of this instruction are 16-bit (Narrow) instructions in Thumb-2 code. For details
see the Thumb 16-bit Instruction Set (UAL) Quick Reference Card.
ARM and Thumb-2 Instruction Set
Quick Reference Card
ARM architecture versions Condition Field
n ARM architecture version n and above Mnemonic Description Description (VFP)
nT, nJ T or J variants of ARM architecture version n and above EQ Equal Equal
5E ARM v5E, and 6 and above NE Not equal Not equal, or unordered
T2 All Thumb-2 versions of ARM v6 and above CS / HS Carry Set / Unsigned higher or same Greater than or equal, or unordered
6K ARMv6K and above for ARM instructions, ARMv7 for Thumb CC / LO Carry Clear / Unsigned lower Less than
7MP ARMv7 architectures that implement Multiprocessing Extensions MI Negative Less than
Z All Security extension versions of ARMv6 and above PL Positive or zero Greater than or equal, or unordered
RM ARMv7-R and ARMv7-M only VS Overflow Unordered (at least one NaN operand)
XS XScale coprocessor instruction VC No overflow Not unordered
HI Unsigned higher Greater than, or unordered
Flexible Operand 2 LS Unsigned lower or same Less than or equal
Immediate value #<imm8m> GE Signed greater than or equal Greater than or equal
Register, optionally shifted by constant (see below) Rm {, <opsh>} LT Signed less than Less than, or unordered
Register, logical shift left by register Rm, LSL Rs GT Signed greater than Greater than
Register, logical shift right by register Rm, LSR Rs LE Signed less than or equal Less than or equal, or unordered
Register, arithmetic shift right by register Rm, ASR Rs AL Always (normally omitted) Always (normally omitted)
Register, rotate right by register Rm, ROR Rs All ARM instructions (except those with Note C or Note U) can have any one of these condition codes after the
instruction mnemonic (that is, before the first space in the instruction as shown on this card). This condition is
encoded in the instruction.
Register, optionally shifted by constant All Thumb-2 instructions (except those with Note U) can have any one of these condition codes after the
instruction mnemonic. This condition is encoded in a preceding IT instruction (except in the case of
(No shift) Rm Same as Rm, LSL #0 conditional Branch instructions). Condition codes in instructions must match those in the preceding IT
Logical shift left Rm, LSL #<shift> Allowed shifts 0-31 instruction.
On processors without Thumb-2, the only Thumb instruction that can have a condition code is B <label>.
Logical shift right Rm, LSR #<shift> Allowed shifts 1-32
Arithmetic shift right Rm, ASR #<shift> Allowed shifts 1-32
Rotate right Rm, ROR #<shift> Allowed shifts 1-31
Rotate right with extend Rm, RRX Processor Modes Prefixes for Parallel Instructions
16 User S Signed arithmetic modulo 28 or 216, sets CPSR GE bits
PSR fields (use at least one suffix) 17 FIQ Fast Interrupt Q Signed saturating arithmetic
Suffix Meaning 18 IRQ Interrupt SH Signed arithmetic, halving results
c Control field mask byte PSR[7:0] 19 Supervisor U Unsigned arithmetic modulo 28 or 216, sets CPSR GE bits
f Flags field mask byte PSR[31:24] 23 Abort UQ Unsigned saturating arithmetic
s Status field mask byte PSR[23:16] 27 Undefined UH Unsigned arithmetic, halving results
x Extension field mask byte PSR[15:8] 31 System

Proprietary Notice Document Number


Words and logos marked with ® or ™ are registered trademarks or trademarks of ARM Limited in the EU ARM QRC 0001M
and other countries, except as otherwise stated below in this proprietary notice. Other brands and names
mentioned herein may be the trademarks of their respective owners.
Change Log
Neither the whole nor any part of the information contained in, or the product described in, this document
may be adapted or reproduced in any material form except with the prior written permission of the Issue Date Change Issue Date Change
copyright holder. A June 1995 First Release B Sept 1996 Second Release
C Nov 1998 Third Release D Oct 1999 Fourth Release
The product described in this document is subject to continuous developments and improvements. All E Oct 2000 Fifth Release F Sept 2001 Sixth Release
particulars of the product and its use contained in this document are given by ARM in good faith. G Jan 2003 Seventh Release H Oct 2003 Eighth Release
However, all warranties implied or expressed, including but not limited to implied warranties of I Dec 2004 Ninth Release J May 2005 RVCT 2.2 SP1
merchantability, or fitness for purpose, are excluded. K March 2006 RVCT 3.0 L March 2007 RVCT 3.1
This reference card is intended only to assist the reader in the use of the product. ARM Ltd shall not be M Sept 2008 RVCT 4.0
liable for any loss or damage arising from the use of any information in this reference card, or any error
or omission in such information, or any incorrect use of the product.
Instruction set (user mode) Data processing instructions 2/3
In user mode esistono tre tipologie di istruzioni: Confronto (settano solo i flag):
- Data processing
Operazioni ALU, trasferimenti tra registri
CMP r1, r2 ; setta flag in base a r1 - r2
- Data transfer
CMPN r1, r2 ; setta flag in base a r1 + r2
Trasferimenti tra registri e memoria
TST r1, r2 ; setta flag in base a r1 and r2
- Control flow
Salti condizionati, incondizionati, interrupt TEQ r1, r2 ; setta flag in base a r1 xor r2
software

Operandi immediati:

ADD r1, r1, #1 ; r1 r1 + 1

Esiste anche la possibilità di indicare operandi


immediati nell’istruzione attraverso l’utilizzo di
shift (dell’immediato stesso).

Data processing instructions 1/3 Data processing instructions 3/3


Istruzioni aritmetiche: In qualsiasi istruzione di elaborazione si può decidere
se settare o meno i flag. Le istruzioni di confronto li
settano sempre, mentre per le altre operazioni di
ADD r0, r1, r2 ; r0 r1 + r2 elaborazione è necessario esplicitarlo.
Questo può essere fatto aggiungendo S (“set condition”).
Esempio, somma a 64 bit:
Istruzioni bit a bit (bitwise):

ADDS r2, r2, r0 ; r2 r2 + r0 e setta flag ...


AND r0, r1, r2 ; r0 r1 and r2
ADC r3, r3, r1 ; ... somma + carry

Spostamento tra registri:


Istruzioni condizionali:

MOV r0, r1 ; r0 r1
ADDNE r1, r1, r0 ; r1 r1 + r0 se flag Z è zero
MOVN r0, r1 ; r0 not(r1)
Condition codes Control flow instructions
Oltre all’esecuzione condizionale (vista in precedenza)
Op c o de Mn e mo ni c In t e rp re t at i o n S t at us f l ag s t at e f o r esistono istruzioni (B) di salto (sia incondizionato che
[3 1 :2 8 ] ex tens i on e x e c ut i o n
0000 EQ Equal / equals zero Z set
condizionato):
0001 NE Not equal Z clear
0010 CS/HS Carry set / unsigned higher or same C set
0011 CC/LO Carry clear / unsigned lower C clear B LABEL ; salta (incondizionato) a LABEL (24 bit)
0100 MI Minus / negative N set
0101 PL Plus / positive or zero N clear
BCOND ; salta (condizionato) a LABEL (24 bit)
0110 VS Overflow V set
0111 VC No overflow V clear
1000 HI Unsigned higher C set and Z clear Le condizioni valutabili dalle istruzioni di salto
1001 LS Unsigned lower or same C clear or Z set
1010 GE Signed greater than or equal N equals V condizionato sono mostrate nella pagina successiva.
1011 LT Signed less than N is not equal to V
1100 GT Signed greater than Z clear and N equals V Ovviamente è possibile anche la Branch and Link
1101 LE Signed less than or equal Z set or N is not equal to V
(indirizzo di ritorno in r14):
1110 AL Always any
1111 NV Never (do not use!) none

BL LABEL ; branch and link a LABEL (24 bit)

Ovviamente, per anndare BL è necessario salvare r14...


© Addison-Wesley

Data transfer instructions Branch conditiions


Esistono varie istruzioni per trasferimenti di dati verso B ran c h In t e rp re t at i o n No rma l us e s
la memoria (e ovviamente dispositivi di I/O mappati in B Unconditional Always take th is branch
memoria nell’ARM). BAL Always Always take th is branch
BEQ Equal Comparison equal or zero result
LDR r0, [r1] ; r0 mem[r1] BNE No t equal Comparison not equal or non-zero result
BPL Plus Result positive or zero
STR r0, [r1] ; mem[r1] r0 BMI Minus Result minus o r negative
LDR r0, [r1, #4] ; r0 mem[r1 + 4] BCC Carry clear Arithmetic operation did not give carry-out
BLO Lower Unsigned compariso n gave lower
BCS Carry set Arithmetic operation gave carry-out
BHS High er or same Unsigned comparison gave higher or same
E’ anche possibile l’auto-indexing: BVC Ov erflow clear Signed integer operation; no overflow occurred
BVS Ov erflow set Signed integer operation; overflow occurred
LDR r0, [r1, #4]! ; r0 mem[r1 + 4] BGT Greater than Signed integer comparison gave g reater than
; r1 r1 + 4 BGE Greater or equal Signed integer comparison gav e greater o r equal
BLT Less than Signed integer comp arison g ave less than
E il post-indexing: BLE Less or equal Signed integer comparison gave less than or equal
LDR r0, [r1], #4 ; r0 mem[r1] BHI Higher Unsigned compariso n gave higher
BLS Lower or same Unsigned comparison g ave lower or same
; r1 r1 + 4

Molte altre istruzioni (stack, etc) rispetto al DLX...


© Addison-Wesley

Potrebbero piacerti anche