Studi e sperimentazioni su processori ad architettura ARM: il set di

Transcript

Studi e sperimentazioni su processori ad architettura ARM: il set di
Università Politecnica delle Marche
Facoltà di Ingegneria
Corso di Laurea in Ingegneria Informatica e dell’Automazione
Studi e sperimentazioni su
processori ad architettura ARM:
il set di istruzioni Thumb
Relatore:
Tesi di Laurea di:
Prof. Aldo Franco Dragoni
Loredano Rapari
Anno Accademico 2010-2011
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
Sommario
1.
2.
3.
INTRODUZIONE ................................................................................................................................................. 6
1.1.
OBIETTIVI ............................................................................................................................................................ 6
1.2.
HARDWARE E SOFTWARE ....................................................................................................................................... 6
1.3.
STRUTTURA DELL’ELABORATO.................................................................................................................................. 6
SISTEMI EMBEDDED E ARM ............................................................................................................................... 7
2.1.
SISTEMI EMBEDDED............................................................................................................................................... 7
2.2.
EVOLUZIONE DI ARM ............................................................................................................................................ 9
2.3.
LA DIFFUSIONE DI ARM ....................................................................................................................................... 11
2.3.1.
I partners di ARM Ltd. ............................................................................................................................... 11
2.3.2.
I principali prodotti sul mercato ................................................................................................................ 13
ARCHITETTURA ARM ........................................................................................................................................15
3.1.
LA LOGICA RISC ................................................................................................................................................. 15
3.2.
LA PIPELINE ....................................................................................................................................................... 16
3.3.
ORGANIZZAZIONE DELLA CACHE ............................................................................................................................. 16
3.4.
GESTIONE DELLA MEMORIA................................................................................................................................... 18
3.4.1.
Organizzazione della memoria.................................................................................................................. 18
3.4.2.
Traduzione degli indirizzi di memoria virtuale .......................................................................................... 19
3.4.3.
Controllo dell’accesso ............................................................................................................................... 20
3.5.
TIPI DI DATI DI ARM ........................................................................................................................................... 20
3.6.
TIPI DI OPERAZIONI.............................................................................................................................................. 21
3.6.1.
3.7.
MODI DI INDIRIZZAMENTO DI ARM........................................................................................................................ 23
3.7.1.
Indirizzamento load/store ......................................................................................................................... 23
3.7.2.
Indirizzamento di istruzioni di processamento dati .................................................................................. 24
3.7.3.
Istruzioni di salto ....................................................................................................................................... 24
3.7.4.
Indirizzamento load/store multiplo........................................................................................................... 24
3.8.
IL PROCESSORE ARM .......................................................................................................................................... 25
3.8.1.
Organizzazione del processore .................................................................................................................. 25
3.8.2.
Modi del processore .................................................................................................................................. 27
3.8.3.
Organizzazione dei registri ........................................................................................................................ 27
3.8.3.1.
Registri a uso generale......................................................................................................................................28
3.8.3.2.
Registri di stato del programma .......................................................................................................................29
3.8.4.
4.
Codici di condizione ................................................................................................................................... 22
Gestione degli Interrupt ............................................................................................................................ 29
MARVELL KIRKWOOD 88F6281 .........................................................................................................................31
4.1.
CARATTERISTICHE DELLA SCHEDA ........................................................................................................................... 31
4.1.1.
Componenti di sistema.............................................................................................................................. 31
4.1.2.
Schema a blocchi dell’ hardware .............................................................................................................. 32
1
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
5.
SET DI ISTRUZIONI THUMB (MANUALE PARTE 1) ..............................................................................................33
5.1.
INTRODUZIONE AL SET DI ISTRUZIONI THUMB ........................................................................................................... 34
5.1.1.
Attivare lo stato Thumb ............................................................................................................................ 34
5.1.2.
ECCEZIONI ......................................................................................................................................................... 35
5.2.
CODIFICA DEL SET ISTRUZIONI ................................................................................................................................ 36
5.2.1.
5.3.
Istruzioni varie ........................................................................................................................................... 37
ISTRUZIONI DI SALTO............................................................................................................................................ 38
5.3.1.
Salto condizionato..................................................................................................................................... 38
5.3.2.
Salto incondizionato .................................................................................................................................. 38
5.3.3.
Salto con scambio ..................................................................................................................................... 38
5.4.
ISTRUZIONI DATA-PROCESSING.............................................................................................................................. 39
5.4.1.
Istruzioni che operano sui registri bassi .................................................................................................... 39
5.4.2.
Istruzioni che operano sui registri alti ....................................................................................................... 41
5.4.3.
Formati...................................................................................................................................................... 42
5.5.
ISTRUZIONI LOAD AND STORE REGISTER .................................................................................................................. 44
5.5.1.
5.6.
Formati...................................................................................................................................................... 44
ISTRUZIONI LOAD AND STORE MULTIPLE ................................................................................................................. 46
5.6.1.
Formati...................................................................................................................................................... 46
5.6.2.
Esempi ....................................................................................................................................................... 46
5.7.
ISTRUZIONI PER LA GENERAZIONE DI ECCEZIONI ......................................................................................................... 47
5.7.1.
5.8.
6.
Codifica delle istruzioni ............................................................................................................................. 47
SPAZIO INDEFINITO DELLE ISTRUZIONI...................................................................................................................... 48
ISTRUZIONI THUMB (MANUALE PARTE 2) ........................................................................................................49
6.1.
2
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
LISTA IN ORDINE ALFABETICO DELLE ISTRUZIONI THUMB.............................................................................................. 50
6.1.1.
Note generali ............................................................................................................................................ 50
6.1.2.
ADC ........................................................................................................................................................... 52
6.1.3.
ADD(1) ....................................................................................................................................................... 53
6.1.4.
ADD(2) ....................................................................................................................................................... 54
6.1.5.
ADD(3) ....................................................................................................................................................... 55
6.1.6.
ADD(4) ....................................................................................................................................................... 56
6.1.7.
ADD(5) ....................................................................................................................................................... 57
6.1.8.
ADD(6) ....................................................................................................................................................... 58
6.1.9.
ADD(7) ....................................................................................................................................................... 59
6.1.10.
AND ...................................................................................................................................................... 60
6.1.11.
ASR(1) ................................................................................................................................................... 61
6.1.12.
ASR(2) ................................................................................................................................................... 63
6.1.13.
B(1) ....................................................................................................................................................... 65
6.1.14.
B(2) ....................................................................................................................................................... 67
6.1.15.
BIC ........................................................................................................................................................ 69
6.1.16.
BKPT ..................................................................................................................................................... 70
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
6.1.17.
BL, BLX(1) ............................................................................................................................................. 72
6.1.18.
BLX(2) ................................................................................................................................................... 75
6.1.19.
BX ......................................................................................................................................................... 76
6.1.20.
CMN ..................................................................................................................................................... 78
6.1.21.
CMP(1).................................................................................................................................................. 79
6.1.22.
CMP(2).................................................................................................................................................. 80
6.1.23.
CMP(3).................................................................................................................................................. 81
6.1.24.
CPS........................................................................................................................................................ 83
6.1.25.
CPY ....................................................................................................................................................... 85
6.1.26.
EOR ....................................................................................................................................................... 87
6.1.27.
LDMIA ................................................................................................................................................... 88
6.1.28.
LDR(1) ................................................................................................................................................... 91
6.1.29.
LDR(2) ................................................................................................................................................... 93
6.1.30.
LDR(3) ................................................................................................................................................... 95
6.1.31.
LDR(4) ................................................................................................................................................... 97
6.1.32.
LDRB(1) ................................................................................................................................................. 99
6.1.33.
LDRB(2) ............................................................................................................................................... 100
6.1.34.
LDRH(1) .............................................................................................................................................. 101
6.1.35.
LDRH(2) .............................................................................................................................................. 103
6.1.36.
LDRSB ................................................................................................................................................. 105
6.1.37.
LDRSH ................................................................................................................................................. 106
6.1.38.
LSL(1) .................................................................................................................................................. 108
6.1.39.
LSL(2) .................................................................................................................................................. 109
6.1.40.
LSR(1) ................................................................................................................................................. 111
6.1.41.
LSR(2) ................................................................................................................................................. 112
6.1.42.
MOV(1) ............................................................................................................................................... 114
6.1.43.
MOV(2) ............................................................................................................................................... 115
6.1.44.
MOV(3) ............................................................................................................................................... 116
6.1.45.
MUL .................................................................................................................................................... 118
6.1.46.
MVN ................................................................................................................................................... 119
6.1.47.
NEG .................................................................................................................................................... 120
6.1.48.
ORR..................................................................................................................................................... 121
6.1.49.
POP ..................................................................................................................................................... 122
6.1.50.
PUSH................................................................................................................................................... 125
6.1.51.
REV ..................................................................................................................................................... 128
6.1.52.
REV16 ................................................................................................................................................. 129
6.1.53.
REVSH ................................................................................................................................................. 130
6.1.54.
ROR..................................................................................................................................................... 131
6.1.55.
SBC ..................................................................................................................................................... 133
6.1.56.
SETEND ............................................................................................................................................... 134
3
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
6.1.57.
STMIA ................................................................................................................................................. 135
6.1.58.
STR(1) ................................................................................................................................................. 138
6.1.59.
STR(2) ................................................................................................................................................. 140
6.1.60.
STR(3) ................................................................................................................................................. 142
6.1.61.
STRB(1) ............................................................................................................................................... 144
6.1.62.
STRB(2) ............................................................................................................................................... 146
6.1.63.
STRH(1) ............................................................................................................................................... 147
6.1.64.
STRH(2) ............................................................................................................................................... 149
6.1.65.
SUB(1)................................................................................................................................................. 151
6.1.66.
SUB(2)................................................................................................................................................. 152
6.1.67.
SUB(3)................................................................................................................................................. 153
6.1.68.
SUB(4)................................................................................................................................................. 154
6.1.69.
SWI ..................................................................................................................................................... 155
6.1.70.
SXTB.................................................................................................................................................... 156
6.1.71.
SXTH ................................................................................................................................................... 157
6.1.72.
TST ...................................................................................................................................................... 158
6.1.73.
UXTB ................................................................................................................................................... 159
6.1.74.
UXTH .................................................................................................................................................. 160
6.2.
7.
ISTRUZIONI THUMB E VERSIONE ARCHITETTURA ...................................................................................................... 161
TEST................................................................................................................................................................162
7.1.
IMPOSTAZIONI TEST........................................................................................................................................... 162
7.2.
PROGRAMMA TEST: FATTORIALE.......................................................................................................................... 163
7.2.1.
Codice C ................................................................................................................................................... 163
7.2.2.
Codice Assembler .................................................................................................................................... 164
7.2.2.1.
Arm .................................................................................................................................................................164
7.2.2.2.
Thumb.............................................................................................................................................................165
7.2.2.3.
Thumb con ottimizzazione –O1 ......................................................................................................................167
7.2.2.4.
Thumb con ottimizzazione –O2 ......................................................................................................................168
7.2.2.5.
Thumb con ottimizzazione –O3 ......................................................................................................................170
7.2.3.
7.3.
Tempi di esecuzione ................................................................................................................................ 176
PROGRAMMA TEST: FATTORI PRIMI ...................................................................................................................... 178
7.3.1.
Codice C ................................................................................................................................................... 178
7.3.2.
Codice Assembler .................................................................................................................................... 179
7.3.2.1.
Arm .................................................................................................................................................................179
7.3.2.2.
Thumb.............................................................................................................................................................180
7.3.2.3.
Thumb con ottimizzazione –O1 ......................................................................................................................182
7.3.2.4.
Thumb con ottimizzazione –O2 ......................................................................................................................183
7.3.2.5.
Thumb con ottimizzazione –O3 ......................................................................................................................184
7.3.3.
7.4.
4
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
Tempi di esecuzione ................................................................................................................................ 186
PROGRAMMA TEST: SERIE DI FIBONACCI................................................................................................................ 188
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
7.4.1.
Codice C ................................................................................................................................................... 188
7.4.2.
Codice Assembler .................................................................................................................................... 188
7.4.2.1.
Arm .................................................................................................................................................................188
7.4.2.2.
Thumb.............................................................................................................................................................189
7.4.2.3.
Thumb con ottimizzazione –O1 ......................................................................................................................190
7.4.2.4.
Thumb con ottimizzazione –O2 ......................................................................................................................191
7.4.2.5.
Thumb con ottimizzazione –O3 ......................................................................................................................192
7.4.3.
Tempi di esecuzione ................................................................................................................................ 194
8.
CONCLUSIONI .................................................................................................................................................196
9.
BIBLIOGRAFIA E SITOGRAFIA ..........................................................................................................................197
5
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
1. Introduzione
In questa tesi andrò a descrivere il funzionamento dell’architettura dei processori ARM,
soffermandomi soprattutto sulla parte che riguarda il set di istruzioni Thumb. La scelta di questo
argomento è dettata dalla grade espansione, negli ultimi tempi, di questa particolare architettura,
adatta per sistemi embedded e per dispositivi portatili, entrambi in grande crescita. Nella
stragrande maggioranza dei cellulari (smartphone), in molti televisori, nei dispositivi di rete, nelle
centraline delle automobili e in molti altri dispositivi sono presenti processori con questa
architettura.
1.1. Obiettivi
L’obiettivo principale è quello di creare un manuale completo, in italiano, sull’architettura
ARMv5TE, per poi poterlo sfruttare in futuro per sperimentazioni e studi sul processore disponibile
in laboratorio con questa architettura. Come è possibile dedurre dal titolo, mi sono occupato della
parte del manuale che parla del set di istruzioni Thumb.
Un altro obiettivo è sicuramente quello di studiare questo particolare tipo di architettura che
sfrutta set di istruzioni RISC (Reduced Instruction Set Computer).
Dopo aver completato la parte di manuale e studiato l’architettura, il terzo obiettivo è quello di
fare dei test con dei programmi compilati appositamente con istruzioni del set Thumb sul
processore disponibile in laboratorio e valutarne i risultati.
1.2. Hardware e Software
L’hardware utilizzato è un dispositivo embedded, uno Sheevaplug computer, nel quale sono
presenti alcune porte di I/O ed è dotato del processore Marvell Kirkwood 88F6281 basato
sull’architettura ARMv5TE.
Nel dispositivo gira un sistema operativo Linux Debian. Per fare i test ho scritto dei semplici
programmi in C e li ho compilati con il compilatore da linea di comando nella shell di Linux. Il
compilatore che ho scelto è Sourcery G++ Lite 2011.03-41 for ARM GNU/Linux.
1.3. Struttura dell’elaborato
Dopo questa introduzione, l’elaborato è costituito da una prima parte in cui si parla in generale dei
sistemi SoC (System on a Chip) e in particolare di quelli che utilizzano l’architettura ARM. Poi c’è
una descrizione dell’architettura ARM in generale, nella quale si parla della logica RISC, della
pipeline e dell’organizzazione e gestione delle risorse del processore. Nel quarto capitolo si parla
della scheda disponibile in laboratorio che monta il processore con architettura ARM (Marvell
Kirkwood 88F6281). Nel quinto capitolo vengono riportati i programmi di test e i risultati ottenuti.
Infine nel sesto capitolo ho allegato la parte di manuale sulle istruzioni Thumb.
6
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
2. Sistemi embedded e ARM
L’architettura ARM ha origine da principi di progetto di tipo RISC e viene utilizzata in sistemi
embedded. Vedremo più avanti in dettaglio l’architettura RISC dell’ARM. In questo paragrafo si
spiegherà il concetto di sistema embedded, per poi rivolgersi ai sistemi ARM.
2.1. Sistemi embedded
Quando parliamo di un sistema ebedded ci riferiamo all’utilizzo di elettronica e software
all’interno di un prodotto, in contrapposizione a sistemi a utilizzo generale (general-purpose),
come i desktop o i portatili. Una definizione di sistema embedded è la seguente:
Una combinazione di hardware e software, ed eventualmente di altre componenti
meccaniche, progettata per assolvere ad un compito specifico. In molti casi i sistemi
embedded sono parte di un sistema o di un prodotto più grande, come nel caso del
sistema ABS di un’automobile.
Tabella 2.1 Esempi di sistemi embedded e loro mercato
Mercato
Dispositivo
Automobilistico
Sistema di accensione
Controllo del motore
Sistema frenante
Elettronica di consumo
Televisione digitale e analogica
DVD, videoregistratori, decoder
Dispositivi palmari (PDA)
Elettrodomestici (frigoriferi, tostapane, microonde)
Giochi
Telefoni, cellulari, cercapersone
Macchine fotografiche
GPS
Controllo industriale
Robotica e sistemi di controllo per la produzione industriale
Sensori
Medicina
Pompe a infusione
Macchine per dialisi
Dispositivi protesici
Monitor cardiaci
Office automation
Fax
Fotocopiatrici
Stampanti
Monitor
Scanner
7
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
I sistemi embedded sono di gran lunga più diffusi dei computer general-purpose, perché vengono
utilizzati in una vastissima gamma di applicazioni (Tabella 2.1). Tali sistemi possono avere una
grande varietà di requisiti e vincoli, come nei casi seguenti:




sistemi piccoli e grandi implicano vincoli differenti in termini di costi di produzione, e quindi
necessità diverse per quanto riguarda ottimizzazione e riutilizzo;
sono soggetti a vincoli molto restrittivi e a combinazioni diverse di requisiti di qualità, ad
esempio in termini di sicurezza, affidabilità, risposta in tempo reale, flessibilità e rispetto
delle normative vigenti;
tempo di vita da breve a lungo;
diverse combinazioni ambientali in termini di radiazioni, vibrazioni e umidità, solo per
citare alcuni esempi;
Figura 2.1 Possibile organizzazione di un sistema embedded.


8
differenti caratteristiche delle applicazioni, che possono essere statiche o dinamiche, lente
o veloci, rivolte al calcolo o ad un utilizzo intensivo dell’interfaccia, e/o combinazioni di
queste;
diversi modelli di computazione (solitamente chiamati sistemi ibridi) che variano da sistemi
a eventi discreti a sistemi con dinamiche a tempo continuo.
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
Spesso i sistemi embedded sono strettamente relazionati al contesto di utilizzo. Questo può dare
origine a vincoli di real-time imposti dalla necessità di interagire con il contesto. I vincoli, come la
velocità di movimento, la precisione delle misurazioni e il periodo di tempo richiesti impongono
una precisa temporizzazione delle operazioni da eseguire. Se più attività devono essere svolte
simultaneamente, i vincoli real-time saranno più restrittivi.
La figura 2.1 mostra in termini generali l’organizzazione di un sistema embedded. Oltre a
processore e memoria vi è un certo numero di elementi che normalmente non sono utilizzati nei
computer desktop o portatili:





una varietà di interfacce che permette al sistema di misurare, manipolare e interagire con
l’ambiente esterno;
l’interfaccia con l’utente può essere molto semplice, come una spia lampeggiante, ma
anche molto complicata, come una vista robotica in tempo reale;
la porta per la diagnostica è utilizzabile per esaminare il sistema che viene controllato, non
solo per la diagnosi del computer;
dispositivi logici programmabili (FPGA, Field Programmable Gate Array), specifici per
applicazioni (ASIC, Application Specific Integrated Circuit) o hardware non digitale sono
utilizzabili per migliorare prestazioni e sicurezza;
il software ha spesso funzionalità prefissate ed è specifico per una data applicazione.
2.2. Evoluzione di ARM
ARM è una famiglia di microprocessori e microcontrollori di tipo RISC, progettati da ARM Inc. di
Cambridge (Inghilterra). ARM progetta processori e architetture multicore e da in licenza i progetti
ad aziende esterne che li producono. I chip ARM sono processori ad alta velocità famosi per le
piccole dimensioni e la bassa potenza richiesta. Gli ARM vengono usati in maniera massiccia in
computer palmari (PDA) e altri dispositivi portatili, inclusi videogiochi, telefoni e un’ampia varietà
di prodotti di consumo. Ad esempio i ben noti dispositivi Apple iPhone e iPod contengono dei chip
ARM. L’architettura ARM è probabilmente la più diffusa nei sistemi embedded e dunque i chip
ARM sono anche i processori più diffusi al mondo.
Le origini della tecnologia ARM vanno ricondotte alla inglese Acorn Computers. All’inizio degli anni
’80 Acorn stipulò un accordo con British Broadcasting Corporation (BBC) per lo sviluppo di un
nuovo microprocessore per il progetto BBC Computer Literacy. Il successo di questo accordo
permise alla Acorn di continuare nello sviluppo e progettare il primo processore RISC commerciale,
l’Acorn RISC Machine (ARM). La prima versione, ARM1, divenne operativa nel 1985 e fu utilizzata
per ricerche interne e sviluppo, oltre ad essere utilizzata come coprocessore nel progetto per la
BBC. Sempre nel 1985, Acorn rilasciò l’ARM2, un processore delle stesse dimensioni del
precedente, ma più veloce e con più funzioni. Ulteriori migliorie furono realizzate con il processore
ARM3 (1989).
Durante questo periodo Acorn affidò alla società VLSI Technology la fabbricazione dei suoi chip.
VLSI poteva commercializzare i chip, ed ebbe un grande successo nel convincere altre aziende a
montare processori ARM nei loro prodotti, in particolare come processori embedded.
Il progetto ARM andava incontro alla domanda commerciale di processori per applicazioni
embedded ad alte prestazioni, bassi consumi, piccole dimensioni e costi contenuti, ma ulteriori
sviluppi andavano oltre le capacità di Acorn. Fu così creata una nuova società, la ARM Ltd., che
vedeva la partecipazione di Acorn, VLSI e Apple Computer. Acorn RISC Machine fu rinominata
Advanced RISC Machine (La società abbandonò la denominazione Advanced RISC Machine alla fine
degli anni ’90. Al giorno d’oggi tale architettura è conosciuta semplicemente come ARM). Il primo
9
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
prodotto offerto dalla nuova società fu ARM6, una versione migliorata di ARM3. In seguito, la
società introdusse diverse nuova famiglie di processori, con sempre più numerose funzionalità e
migliori prestazioni. La Tabella 2.2 mostra alcune caratteristiche delle diverse famiglie di
architetture ARM. I numeri della tabella sono solamente indicativi; i valori reali variano a seconda
delle differenti implementazioni.
Tabella 2.2 Evoluzione di ARM
Famiglia
ARM1
ARM2
ARM3
ARM6
ARM7
ARM8
ARM9
ARM9E
ARM10E
ARM11
Cortex
XScale
Funzionalità rilevanti
32-bit RISC
Istruzioni di moltiplicazione e scambio; unità
di gestione della memoria, grafica e
processore I/O integrati
Primo utilizzo della cache del processore
Primo a supportare indirizzi a 32 bit; unità
floating point (virgola mobile)
SoC (System on a Chip) integrato
Pipeline a 5 stadi; predizione statica dei salti
Istruzioni DSP migliorate
Pipeline a 6 stadi
Pipeline a 9 stadi
Pipeline superscalare a 13 stadi
Processore per le applicazioni: pipeline a 7
stadi
Figura 2.2 Evoluzione delle famiglie di processori
10
Cache
No
No
MIPS tipico @ MHz
4 KB unificata
4 KB unificata
12 MIPS @ 25 MHz
28 MIPS @ 33 MHz
8 KB unificata
8 KB unificata
16 KB / 16 KB
16 KB / 16 KB
32 KB / 32 KB
Variabile
Variabile
32 KB / 32 KB L1
512 KB L2
60 MIPS @ 60 MHz
84 MIPS @ 72 MHz
300 MIPS @ 300 MHz
220 MIPS @ 200 MHz
7 MIPS @ 12 MHz
740 MIPS @ 665 MHz
2000 MIPS @ 1 GHz
1000 MIPS @ 1,25 GHz
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
Conformemente a quanto descritto sul sito web di ARM (arm.com), i processori ARM sono
progettati per soddisfare tre diverse categorie di sistemi:



sistemi embedded real-time: sistemi di memorizzazione, comparto automobilistico e
industriale, applicazioni di rete;
piattaforme applicative: dispositivi che utilizzano sistemi operativi come Linux, Palm OS,
Symbian OS, e Windows CE per applicazioni wireless e di intrattenimento digitale;
applicazioni per la sicurezza: smart card, SIM card e terminali Bancomat.
2.3. La diffusione di ARM
Come abbiamo già detto i processori con architettura ARM sono i più diffusi al mondo grazie al
rapporto qualità-costo davvero eccellente. Abbiamo anche detto che ARM realizza i progetti delle
varie architetture e poi le cede in licenza ai produttori, andiamo quindi a vedere i prteners di ARM
Ltd. e i principali prodotti sul mercato che utilizzano questi processori.
2.3.1.
I partners di ARM Ltd.
Di seguito la lista dei principali membri della ARM Connected Community.
Tabella 2.3 Licenze della famiglia di processori Cortex
Processor
Cortex-A15
Cortex-A9
Cortex-A8
Cortex-A5
Cortex-R4(F)
Cortex-M4
Cortex-M3
Cortex-M0
Selection of Public Licensees
Texas Instruments, ST-Ericsson, nVIDIA, Samsung Electronics
Broadcom Corporation, NEC Electronics, nVIDIA, STMicroelectronics, Texas
Instruments, Toshiba, Mindspeed Technologies
Broadcom Corporation, Freescale Semiconductor, Matsushita, Samsung
Electronics, STMicroelectronics, Texas Instruments, PMC-Sierra, 3Dlabs
Cambridge Silicon Radio
Broadcom Corporation, Texas Instruments, Toshiba, Infineon
NXP, STMicroelectronics, Texas Instruments, Freescale
Accent Srl, Actel Corporation, Broadcom Corporation, Cypress Semiconductor,
Ember, Energy Micro, Fujitsu, NXP, Fuzhou Rockchip Electronics CO.
Ltd., STMicroelectronics, Texas Instruments, Toshiba, Zilog,
Austriamicrosystems, Chungbuk Technopark, NXP, Triad Semiconductor, Melfas
11
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
Tabella 2.4 Licenze della famiglia di processori ARM11
Processor
ARM11 MPCore
ARM1176JZ(F)-S
ARM1156T2(F)S
ARM1136J(F)-S
Public Licensees
Intel Corporation, NEC Electronics, Netronome, NVIDIA, PMC
Sierra, Renesas, Sarnoff
Broadcom Corporation, Infineon Technologies AG, Matsushita, NEC
Electronics,NXP,Renesas, Sunplus, Texas Instruments , Toshiba
Comsys, LSI Logic, NEC Electronics
Accent, Broadcom Corporation, Ceroma, eSilicon Corporation, Freescale
Semiconductor,LSI Logic, Matsushita, Mindspeed, NEC Electronics,
Qualcomm, Renesas,STMicroelectronics, Texas Instruments , Toshiba
Tabella 2.5 Licenze della famiglia di processori ARM9
Accent
Alcatel
Alchip
All
Winner
Technology
(Holding) Ltd
Altera
Analog Devices Inc.
ARCA
Atheros Communications
Atmel Corporation
Austriamicrosystems
Avago Technologies
Avalink Incorporated
Beken Corporation
Broadcom Corporation
Cambridge Silicon Radio
Capital Semiconductor Ltd
Chongqing Chongyou IT
Cirrus Logic
Conexant Systems Inc.
Datang
Microelectronics
Technology
eSilicon Corporation
Faraday
TechFocus
Enhancements
Freescale Semiconductor
Fujitsu
GCT Semiconductor
12
Global
Unichip
Corporation
Huawei Technologies
ICP
Infineon Technologies AG
Ironkey Incorporated
Kawasaki Microelectronics
Key ASIC
Leadcore Technology Co
Ltd
LSI Logic
Marvell Semiconductor
Mediatek Inc
Micrel
Mindspeed Technologies
Inc.
Moschip Semiconductor
Mtekvision
NationZ Technologies Inc
NEC Electronics
Neo Magic Corporation
NXP
Nuvoton
Technology
Corporation
NVidia Corporation
OKI
Panasonic
Parrot
PulseLink
Qualcomm
Quanta Computer Inc
Renesas Technology
RF Micro Devices
Rohm
Samsung Electronics
Sandisk
Sanyo Electric Co Ltd
Shanghai
Jade
Technologies
Sharp Corporation
Sierra Wireless SA
Skyworks Solutions Inc.
Socle Technology Corp
Sony
STMicroelectronics
Standard Microsystems
Telechips
Texas Instruments
Toshiba
TSMC
Verisilicon
Wisair
Zoran Corporation
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
2.3.2.
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
I principali prodotti sul mercato
Motorola Atrix 4G
Nvidia Tegra2 (dual-core Cortex-A9)
LG Optimus Quantum
Qualcomm QSD8650 (ARMv7 instruction set)
GREE Water-Cooled Centrifugal Chiller (condizionatore indusatriale)
NXP LPC21xx MCU(ARM7TDMI)
Sony Ericsson Xperia Play
Qualcomm QSD8550 ARMv7
Motorola Xoom
Nvidia Tegra 2 (Cortex-A9)
Itron OpenWay CENTRON Smart Meter (misuratore consumo energetico)
Accent ASMgrid Platform - Integrated ARM® Cortex-M3
Web Tube (Samsung Smart TV)
Samsung (Cortex-A8)
Olivetti Olipad 100
Nvidia Tegra 2 (Cortex-A9)
13
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Apple iPod Nano
Dual ARM7TDMI
HP Deskjet 5940
ARM946E-S
14
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
3. Architettura ARM
L’architettura ARM si è evoluta a un punto tale che supporta implementazioni su un ampio spettro
di punti di prestazioni. Sono stati prodotti più di due miliardi di pezzi, il che stabilisce l’architettura
come quella dominante in vari segmenti di mercato. La semplicità dell’architettura dei processori
ARM ha portato nel corso del tempo a implementazioni sempre più piccole, queste
implementazioni permettono ai dispositivi un consumo energetico molto basso. Dimensioni,
prestazioni e consumi molto bassi rimangono punti chiave nello sviluppo dell’architettura ARM.
La maggior parte delle versioni dell’architettura supporta due tipi di set di istruzioni: un set
codificato a 32 bit che viene chiamato ARM instructions set e un set codificato a 16 bit chiamato
Thumb instructions set. Entrambi sono Reduced Instruction Set Computer (RISC) e comprendo le
caratteristiche tipiche delle architetture RISC.
3.1. La logica RISC
A differenza di come è specificato nella definizione (Reduced Instruction Set Computer), RISC non
significa tanto avere a che fare con meno istruzioni, ma bensì con una architettura circuitale che
sia molto semplice nel consentire di ottenere maggiore compattezza, velocità di operazione ed
esecuzione delle istruzioni in un singolo colpo di clock. La lunghezza delle istruzioni viene
mantenuta costante in modo da garantire una prevedibilità nei tempi di esecuzione delle
istruzioni.
La semplice filosofia che sta dietro
l’architettura RISC è riassunta dalla figura
3.1.
Abbiamo una unità centrale, il processore,
che è la parte intelligente del sistema. Un
insieme di registri consente di movimentare
i dati all’interno della CPU.
I dati e le istruzioni vengono caricati dalla
memoria.
Non si possono eseguire dunque operazioni
dirette sui dati in memoria, ma solo tra
registri interni.
Figura 3.1 Filosofia architettura RISC
Le principali caratteristiche delle architetture RISC sono:




un file di registro grande e uniforme;
un’architettura load/store, poiché le operazioni sui dati avvengono nei registri interni al
processore e non direttamente in memoria;
modalità di indirizzamento semplice, con tutti gli indirizzi determinati solamente dal
contenuto dei registri e dei campi delle istruzioni;
campi delle istruzioni uniformi e di lunghezza fissa, per semplificare la decodifica
dell’istruzione.
In più l’architettura ARM, fornisce:


modalità di indirizzamento con auto-incremento e auto-decremento per ottimizzare i cicli;
istruzioni di load e store multiplo per massimizzare il throughput dei dati;
15
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb

Tesi di Laurea di:
Loredano Rapari
matr. 1029262
esecuzione condizionata per quasi tutte le istruzioni per massimizzare il throughput di
esecuzione.
I miglioramenti all’architettura RISC di base, permettono ai processori ARM di raggiungere un
buon bilanciamento tra alte prestazioni, dimensioni del codice, basso consumo e grandezza del
chip.
3.2. La pipeline
Nei RISC ogni istruzione è organizzata in modo che le azioni vengano svolte seguendo sempre una
medesima successione, eventualmente lasciano un buco, o NOP, se quel particolare passo non
serve.
Questo fa si che si possa evitare di aspettare che un’istruzione sia completamente eseguita, prima
di iniziare la successiva. Mentre un’istruzione è in corso di esecuzione, se ne potrebbe iniziare
un’altra. Questo approccio si dice organizzazione a pipeline.
Nell’ARM7 classicamente si adotta una pipeline a 3 livelli:
Figura 3.2 Organizzazione pipeline
L’organizzazione a pipeline deve essere realizzata all’atto della realizzazione hardware del
dispositivo.
Può dare buoni benefici, occorre però fare attenzione perché l’organizzazione a pipeline può
portare a colli di bottiglia, se non accuratamente progettata.
3.3. Organizzazione della cache
L’organizzazione della cache nei processori ARM ha seguito l’evoluzione dell’architettura della
famiglia ARM, rispecchiando la continua ricerca di prestazioni che è la forza motrice dei progettisti
di processori.
La Tabella 3.1 mostra questa evoluzione. Il modello ARM7 utilizzava una cache unificata, mentre
tutti i modelli seguenti utilizzano una cache per le istruzioni e una per i dati. Tutti i progetti ARM
utilizzano cache set-associative, con diversi gradi di associatività e dimensioni di linea. Gli ARM con
cache dotati di MMU (Memory Management Unit) utilizzano una cache logica nelle famiglie da
ARM7 a ARM10, inclusi i processori Intel StrongARM e Intel Xscale. La famiglia ARM11 utilizza una
cache fisica. La differenza tra cache logica e cache fisica è illustrata in figura 3.3.
16
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
Tabella 3.1 Caratteristiche della cache di ARM
Core
Tipo di
cache
Dimensione
della cache (KB)
Dimensione
della linea di
cache (parole)
Associatività
Locazione
ARM720T
ARM920T
ARM926EJ-S
ARM1022E
ARM1026EJ-S
Intel
StrongARM
Intel Xscale
ARM1136JF-S
Unificata
Separata
Separata
Separata
Separata
Separata
8
16/16 D/I
4-128/4-128 D/I
16/16 D/I
4-128/4-128 D/I
16/16 D/I
4
8
8
8
8
4
4 vie
64 vie
4 vie
64 vie
4 vie
32 vie
Logica
Logica
Logica
Logica
Logica
Logica
Dimensione
del buffer
di scrittura
(parole)
8
16
16
16
8
32
Separata
Separata
32/32 D/I
4-64/4-64 D/I
8
8
32 vie
4 vie
Logica
Fisica
32
32
Un’interessante
funzionalità
dell’architettura ARM è l’utilizzo di un
piccolo buffer di scrittura FIFO (First In
First Out) per migliorare le prestazioni
di scrittura in memoria. Il buffer di
scrittura è interposto tra la cache e la
memoria principale e consiste in un
insieme di indirizzi e un insieme di dati.
Il buffer è piccolo rispetto alla cache e
può immagazzinare fino a quattro
indirizzi. Tipicamente il buffer di
scrittura è abilitato per tutta la
memoria principale, anche se può
essere selettivamente disabilitato a
livello di pagina. La figura 3.4 mostra le
relazioni tra buffer di scrittura, cache e
memoria principale.
Figura 3.4 Organizzazione della cache di ARM e del buffer di scrittura
Figura 3.3 Cache fisica e logica
Vediamo come funziona il buffer
di scrittura. Quando il processore
scrive in una zona abilitata
all’utilizzo del buffer, il dato è
posto nel buffer ad una velocità
pari a quella del processore e il
processore continua la sua
esecuzione. La scrittura ha luogo
quando il dato presente nella cache è ricopiato nella memoria principale. Il dato da scrivere viene
trasferito dalla cache al buffer di scrittura. Il buffer di scrittura realizza quindi la scrittura esterna in
parallelo. Se il buffer di scrittura è pieno (sia perché è stato raggiunto il massimo numero di parole
nel buffer, sia perché non ci sono più posizioni per nuovi indirizzi) il processore viene bloccato
finché non c’è spazio sufficiente nel buffer. Mentre vengono eseguite operazioni che non
17
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
coinvolgono scritture, il buffer di scrittura continua a scrivere sulla memoria principale fino a
quando si svuota completamente.
I dati scritti nel buffer di scrittura non sono disponibili per la lettura nella cache fino a quando non
sono stati trasferiti dal buffer alla memoria centrale. Questa è la ragione principale per cui il buffer
è così piccolo. Anche in questo modo, a meno che una grande porzione di programma esegua
operazioni di scrittura, il buffer di scrittura riesce a migliorare le prestazioni.
3.4. Gestione della memoria
ARM offre un’architettura di memoria virtuale versatile adattabile alle esigenze dei progettisti di
sistemi embedded.
3.4.1.
Organizzazione della memoria
La figura 3.5 fornisce una visione d’insieme dell’hardware di gestione della memoria in ARM. Il
dispositivo di traduzione della memoria virtuale utilizza uno o due livelli di tabelle per la
traduzione da indirizzi virtuali a indirizzi fisici. Il buffer TLB (Translation Lookaside Buffer) è una
cache di voci della tabella delle pagine recenti. Se una voce è disponibile nel buffer TLB l’indirizzo
fisico per un’operazione di lettura o scrittura è mandato alla memoria principale direttamente dal
TLB. I dati vengono scambiati tra la memoria principale e il processore attraverso la cache. Se si
utilizza una organizzazione logica della cache (Figura 3.3a) il processore ARM, in caso di miss, passa
l’indirizzo alla cache ma anche al TLB. Se si utilizza un’organizzazione fisica della cache (Figura
3.3b) tocca al TLB passare l’indirizzo fisico alla cache.
Figura 3.5 Il sistema di memoria ARM.
Le voci della tabella di traduzione includono anche i bit di controllo di accesso, che determinano se
un dato processo può accadere a una data porzione di memoria. Se l’accesso viene negato, il
dispositivo di controllo di accesso invia un segnale di insuccesso al processore ARM.
18
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
3.4.2.
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
Traduzione degli indirizzi di memoria virtuale
Il processore ARM supporta l’accesso alla memoria basto su sezioni o su pagine:




Supersezioni (opzionale): consistono in blocchi di memoria principale da 16 MB
Sezioni: consistono in blocchi di memoria principale da 1 MB
Pagine grandi: consistono in blocchi di memoria principale da 64 KB
Pagine piccole: consistono in blocchi di memoria principale da 4 KB
Il supporto di sezioni e supersezioni permette di indirizzare una grande porzione di memoria
utilizzando un’unica voce nel TLB. Meccanismi aggiuntivi di controllo di accesso vengono estesi alle
pagine piccole e sottopagine di 1 KB e dalle pagine grandi a sottopagine di 16 KB. La tabella di
traduzione presente nella memoria principale ha due livelli:


Tabella di primo livello: mantiene le traduzioni di sezioni e sottosezioni e i puntatori alla
tabella di secondo livello
Tabella di secondo livello: mantiene la traduzione di pagine piccole e grandi
L’unità di gestione della memoria (MMU) traduce indirizzi virtuali generati dal processore in
indirizzi fisici per l’accesso alla memoria principale; inoltre, ricava e controlla i permessi di accesso.
La traduzione viene effettuata in seguito ad un miss di TLB e inizia da un fetch di primo livello. Un
indirizzamento a sezione richiede soltanto fetch di primo livello, mentre un indirizzamento a
pagine richiede anche fetch di secondo livello.
Figura 3.6 Traduzione di indirizzi di memoria virtuale per pagine piccole in ARM.
La figura 3.6 mostra il processo di traduzione di indirizzi di secondo livello per pagine piccole. È
presente una tabella delle pagine di livello 1 (L1) con 4K entry di 32 bit. Ogni entry di L1 punta a
19
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
una tabella delle pagine di livello 2 (L2) con 255 entry di 32 bit. Ogni entry di L2 punta ad una
pagina di 4 KB nella memoria principale. L’indirizzo virtuale di 32 bit è interpretato come segue. I
12 bit più significativi sono un indice nella tabella L1. I successivi 8 bit sono un indice nella tabella
L2 appropriata. I primi 12 bit meno significativi indicano un byte della pagina appropriata in
memoria centrale. Per le pagine grandi viene utilizzata una procedura di lookup a due pagine
simile a questa. Per le sezioni e le supersezioni è richiesta la ricerca nella sola tabella di pagina L1.
3.4.3.
Controllo dell’accesso
In ogni entry sono presenti due bit chiamati AP che controllano l’accesso di un dato processo ad
una regione di memoria. Un’area di memoria può essere marcata come non accessibile, accessibile
in sola lettura o in lettura e scrittura. Inoltre l’area di memoria può essere designata per soli
accessi privilegiati, riservata al sistema operativo e non disponibile per le applicazioni.
ARM utilizza anche il concetto di dominio, una collezione di sezioni e/o pagine con permessi
particolari di accesso. L’architettura ARM prevede 16 domini. L’impiego di domini permette a più
processori di utilizzare la stessa tabella di traduzione e contemporaneamente mantenere alcune
protezioni gli uni dagli altri.
Ogni entry di tabella delle pagine e ogni entry TLB contengono un campo che specifica a quale
dominio appartiene un entry. Un campo di 2 bit nel registro Domain Access Control controlla
l’accesso a ogni dominio. Ogni campo permette di abilitare o disabilitare molto rapidamente
l’accesso a un intero dominio in modo che intere aree di memoria possano essere trasferite dentro
e fuori la memoria virtuale in maniera molto efficiente. Ci sono due tipi di accesso al dominio:


Client: utenti dei domini (che eseguono programmi e accedono ai dati) che devono
osservare i permessi di accesso alle singole sezioni e/o pagine che compongono il dominio
Manager: controllano il comportamento del dominio (le pagine e le sezioni correnti nel
dominio e l’accesso al dominio) ed evitano i permessi di accesso per le entry in tale
dominio
Un programma può essere un client di certi domini, un manager di altri e non avere accesso ai
rimanenti. Ciò permette una protezione molto difficile della memoria per programmi che
accedono a diverse risorse di memoria.
3.5. Tipi di dati di ARM
L’ARM può trattare tipi di dato da 8 bit (byte), da 16 bit (mezza parola) e da 32 bit (parola). In
genere, l’accesso alla mezza parola deve essere allineato alla mezza parola, mentre gli accessi di
parola devono essere allineati alla parola. In caso di accesso non allineato, l’architettura prevede
tre alternative:


20
Caso di deault:
- L’indirizzo viene considerato troncato, i bit di indirizzo *1:0+ corrispondono a zero per gli
accessi di parola e il bit di indirizzo [0] corrisponde a zero per gli accessi di mezza
parola.
- Le istruzioni ARM di caricamento della singola parola prevedono, dal punto di vista
dell’architettura, di traslare a destra dei dati allineati alla parola uno, due o tre byte a
seconda del valore dei due bit di indirizzo meno significativi, trasferiti da un indirizzo
non allineato.
Controllo di allineamento: se è definito un bit di controllo appropriato, un segnale indica
un errore di allineamento dovuto a un tentativo di accesso non allineato.
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb

Tesi di Laurea di:
Loredano Rapari
matr. 1029262
Accesso non allineato: in questo caso il processore utilizza uno o più accessi di memoria
per generare il trasferimento richiesto di byte adiacenti, in modo trasparente al
programmatore.
Per tutti e tre i tipi di dati (byte, mezza parola e parola) è possibile un’interpretazione senza segno,
in cui il valore rappresenta un intero senza segno, non negativo. I tre tipi di dato possono essere
utilizzati per interi con segno in complemento a due.
La maggior parte delle implementazioni per ARM non fornisce hardware in virgola mobile, a
vantaggio di spazio e potenza. Se in tali processori dovesse rendersi necessaria un’aritmetica in
virgola mobile, questa dovrà essere realizzata dal software. L’ARM può prevedere un coprocessore opzionale in virgola mobile per i tipi di dato in virgola mobile a precisione singola e
doppia definiti nello standard IEEE 754.
3.6. Tipi di operazioni
L’architettura ARM mette a disposizione un ampio repertorio di tipi di operazioni:







Istruzioni di load e store: nell’architettura ARM unicamente le istruzioni di load e store
accedono alle locazioni di memoria. Le istruzioni aritmetiche e logiche vengono eseguite
sui registri e i valori immediati sono codificati nell’istruzione. Questa è una caratteristica
della progettazione RISC. L’architettura ARM ha due tipi generici di istruzione che spostano
il valore di un registro, o di due, da e verso la memoria: (1) carica o registra una parola di
32 bit oppure un byte a 8 bit senza segno e (2) carica o registra una mezza parola di 16 bit
senza segno e carica ed estende il segno di una mezza parola a 16 bit oppure di un byte ad
8 bit.
Istruzioni di salto: ARM supporta un’istruzione di salto condizionato in avanti o indietro
fino a 32 MB. Dal momento che il program counter è uno dei registri generici (R15), si può
ottenere un salto anche scrivendo un valore in R15. È possibile eseguire una chiamata di
procedura tramite una variante dell’istruzione di salto standard. Oltre a eseguire un salto,
l’istruzione BL, di salto con link (Branch with Link), scrive l’indirizzo dell’istruzione
successiva al salto (indirizzo di ritorno) nel registro LR (R14). I salti vengono determinati da
un campo di condizione a 4 bit nell’istruzione.
Istruzioni di processamento dati: tale categoria include istruzioni logiche (AND, OR, XOR),
la somma e la sottrazione, e istruzioni di verifica e di confronto.
Istruzioni di moltiplicazione: le istruzioni di moltiplicazione di interi operano su parole e
mezze parole e possono produrre risultati normali o lunghi: ad esempio, un’istruzione di
moltiplicazione che utilizza due operandi a 32 bit e produce un risultato a 64 bit.
Istruzioni parallele di somma e sottrazione: oltre alle normali istruzioni dei due tipi
precedenti, c’è un insieme di istruzioni parallele di somma e sottrazione nelle quali parti
degli operandi vengono elaborate in parallelo. Ad esempio, ADD16 somma le parti alte
delle mezze parole di due registri per formare la parte alta della mezza parola del risultato
e somma le parti basse delle mezze parole degli stessi due registri per formare la parte
bassa della mezza parola del risultato. Queste istruzioni sono utili nelle applicazioni
grafiche, come le istruzioni MMX della famiglia x86.
Istruzioni di estensione: ci sono varie istruzioni per spacchettare i dati, che grazie al segno
oppure allo zero possono estendere i byte in mezze parole o parole e le mezze parole in
parole.
Istruzioni di accesso al registro di stato: ARM offre la capacità di leggere, oltre che di
scrivere, porzioni del registro di stato.
21
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
3.6.1.
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
Codici di condizione
L’architettura ARM definisce quattro flag di condizione memorizzati nel registro di stato del
programma: N, Z, C e V (Negative, Zero, Carry e oVerflow). I quattro flag citati costituiscono un
codice di condizione in ARM. La tabella 3.2 mostra le combinazioni delle condizioni, previste per
l’esecuzione condizionale. Due inconsueti aspetti dell’utilizzo dei codici di condizione in ARM sono:
1. Tutte le istruzioni, non solo quelle di salto condizionato, includono un campo codice di
condizione. Quindi, virtualmente, tutte le istruzioni potrebbero essere eseguite in modalità
condizionale. Ogni combinazione delle impostazioni di flag, fatta eccezione per 1110 e
1111, in un campo del codice di condizione dell’istruzione significa che quell’istruzione sarà
eseguita solo se si verifica la condizione richiesta.
2. Tutte le istruzioni di elaborazione dati (aritmetiche e logiche) includono un bit S, quindi in
caso di aggiornamento dell’istruzione la condizione genera un segnale.
Tabella 3.2 Condizioni di ARM per l’esecuzione condizionale delle istruzioni
Codice
0000
0001
0010
Simbolo
EQ
NE
CS/HS
Condizione da verificare
Z=1
Z=0
C=1
0011
CC/LO
C=0
0100
0101
0110
0111
1000
1001
1010
1011
1100
1101
1110
1111
MI
PL
VS
VC
HI
LS
GE
LT
GT
LE
AL
-
N=1
N=0
V=1
V=0
C = 1 AND Z = 0
C = 0 OR Z = 1
N = V [(N = 1 AND V = 1) OR (N = 0 AND V = 0)]
N ≠ V [(N = 1 AND V = 0) OR (N = 0 AND V = 1)]
(Z = 0) AND (N = V)
(Z = 1) OR (N ≠ V)
-
Commenti
Uguale
Diverso
Imposta riporto/senza segno più alto
o uguale
Cancella riporto/senza segno più
basso
Meno/negativo
Più/positivo oppure zero
Overflow
No overflow
Senza segno più alto
Senza segno più basso oppure uguale
Con segno maggiore o uguale
Con segno minore
Con segno maggiore
Con segno minore o uguale
Sempre (non condizionato)
Questa istruzione può essere
eseguita solo in modalità non
condizionata
L’utilizzo dell’esecuzione condizionale e dell’impostazione condizionale per i flag di condizione è di
aiuto alla progettazione di programmi più corti, che utilizzano meno memoria. D’altro canto, tutte
le istruzioni includono 4 bit per il codice condizionale. Si ha quindi un compromesso con il fatto
che non tutti i bit delle istruzioni a 32 bit sono utilizzabili per codice operativo e operandi. Tale
compromesso può essere considerato ragionevole, proprio perché ARM è un’architettura RISC che
si affida pesantemente all’indirizzamento dei registri.
22
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
3.7. Modi di indirizzamento di ARM
A differenza delle CISC, le macchine RISC utilizzano in genere modi di indirizzamento semplici e
relativamente diretti. L’architettura ARM si discosta un po’ da questa tradizione, offrendo un
insieme piuttosto ricco di modi di indirizzamento. Tali modi vengono classificati in maniera più
conveniente in relazione al tipo di istruzione.
3.7.1.
Indirizzamento load/store
Le istruzioni di load e store sono le uniche che fanno riferimento alla memoria, in modo indiretto,
tramite un registro base sommato a uno spiazzamento.
Figura 3.7 Metodi di indicizzazione di ARM
23
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
Le alternative di indicizzazione sono le seguenti tre (Figura 3.7):



Spiazzamento (offset). Questo indirizzamento non prevede indicizzazione. Lo spiazzamento
viene sommato o sottratto al valore del registro base per formare l’indirizzo di memoria. La
figura 3.7° mostra un esempio di questo metodo con l’istruzione STRB r0, *r1, #12+, che è
l’istruzione di memorizzazione di un byte. In questo caso l’indirizzo di base è nel registro r1
e lo spiazzamento è il valore immediato 12. L’indirizzo risultante (base più spiazzamento) è
la locazione di memoria in cui registrare il byte meno significativo di r0.
Preindicizzazione (preindex). L’indirizzo di memoria è formato come nel caso precedente,
ma viene riscritto anche nel registro base. In altre parole, il valore del registro base viene
incrementato o decrementato del valore dello spiazzamento. La figura 3.7b illustra questo
metodo con l’istruzione STRB r0, *r1, #12+!. Il punto esclamativo sta proprio a indicare la
preindicizzazione.
Postindicizzazione (postindex). L’indirizzo di memoria è il valore del registro base. Uno
spiazzamento viene aggiunto o sottratto al valore del registro base. La figura 3.7c illustra
questo metodo con l’istruzione STRB r0, *r1+, #12.
Si noti come ciò a cui ARM fa riferimento come registro base si comporta poi da registro indice per
la preindicizzazione e la postindicizzazione. Il valore di spiazzamento può essere sia un valore
immediato contenuto nell’istruzione sia il valore di un altro registro. Se il valore di spiazzamento è
un registro, è disponibile un’altra caratteristica utile: l’indirizzamento di registro scalare. Il valore
nel registro di spiazzamento viene scalato da uno degli operatori di shift: shift logico a sinistra,
shift logico a destra, shift aritmetico a destra, rotazione verso destra oppure rotazione estesa
verso destra (che include il bit di riporto nella rotazione). L’entità di uno shift è specificata come
valore immediato nell’istruzione.
3.7.2.
Indirizzamento di istruzioni di processamento dati
Queste istruzioni possono utilizzare l’indirizzamento con registro o quello immediato. Nel primo
caso, il valore di uno degli operandi può essere scalato utilizzando uno degli operatori di shift
definiti nel paragrafo precedente.
3.7.3.
Istruzioni di salto
Per queste istruzioni esiste solo l’indirizzamento immediato. L’istruzione di salto contiene un
valore a 24 bit. Per il calcolo degli indirizzi il valore viene spostato a sinistra di 2 bit, in modo che
l’indirizzo sia allineato come una parola. In questo modo, la gamma degli indirizzi effettivi
raggiungibili si estende a ±32 MB dal program counter.
3.7.4.
Indirizzamento load/store multiplo
Le istruzioni di caricamento multiplo portano dati dalla memoria a un sottoinsieme dei registri a
uso generale (o a tutti). Le istruzioni di store multiplo memorizzano i dati di un sottoinsieme dei
registri a uso generale (o di tutti). La lista dei registri da caricare e salvare viene specificata in un
campo a 16 bit dell’istruzione dove ogni bit corrisponde a uno dei 16 registri. Queste modalità di
indirizzamento producono una sequenza di indirizzi di memoria. Il registro numericamente più
basso viene salvato all’indirizzo di memoria più basso, mentre il registro numericamente più alto
verrà salvato all’indirizzo più alto. I quattro tipi di indirizzamento utilizzati, rappresentati nella
figura 3.8, sono: incremento successivo, incremento antecedente, decremento successivo e
decremento antecedente. Un registro base specifica un indirizzo di memoria principale da dove i
valori vengono prelevati oppure nei quali vengono salvati, in locazioni di parola ascendenti
24
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
(incremento) oppure discendenti (decremento). Tale incremento, o decremento, ha inizio prima
oppure dopo il primo accesso alla memoria.
Figura 3.8 Indirizzamento load/store multiplo in ARM
Queste istruzioni sono utili per caricamenti o salvataggi in blocco, per le operazioni sulla pila e per
le sequenze di uscita dalle procedure.
3.8. Il processore ARM
ARM è essenzialmente un sistema RISC con le seguenti caratteristiche degne di nota.







Una piccola schiera di registri uniformi, più di quelli che ci sono in alcuni sistemi RISC, ma
meno di quelli che si trovano in molti sistemi CISC.
Un modello load/store di elaborazione dati nel quale le istruzioni lavorano sugli operandi
nei registri e non direttamente in memoria. Tutti i dati devono essere caricati nei registri
prima di poter essere elaborati. Il risultato può essere utilizzato per ulteriori operazioni
oppure essere salvato in memoria.
Un set standard di istruzioni a 32 bit e un set di istruzioni Thumb a 16 bit.
Per rendere ogni istruzione di elaborazione dati più flessibile è possibile preprocessare uno
dei registri sorgente con uno shift o una rotazione. Per utilizzare in maniera più efficiente
questa funzionalità esiste un’unità aritmetico logica (ALU) separata e un’unità shifter.
Pochi modi di indirizzamento, determinati dai registri e dai campi dell’istruzione. Non sono
utilizzati indirizzamenti indiretti o indicizzati che coinvolgono valori in memoria.
Per migliorare l’esecuzione dei cicli nei programmi sono utilizzate modalità di auto
incremento e auto decremento dell’indirizzo.
L’esecuzione condizionale delle istruzioni riduce il numero delle istruzioni di salto
condizionato, migliorando quindi l’efficienza della pipeline, perché gli svuotamenti della
pipeline vengono ridotti.
3.8.1.
Organizzazione del processore
L’organizzazione del processore ARM varia notevolmente da un’implementazione all’altra, in
particolare quando è basata su diverse versioni dell’architettura ARM. È tuttavia utile presentare
una versione generica e semplificata dell’organizzazione, illustrata nella figura 3.9. Le frecce
indicano il flusso dei dati. Ogni riquadro rappresenta un’unità funzionale hardware o un’unità di
memorizzazione.
25
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
I dati vengono scambiati tra il processore e la memoria esterna attraverso il bus dati. Il valore
trasferito può essere sia un dato (istruzione di load/store) sia il fetch di un’istruzione. Le istruzioni
prelevate passano attraverso un decodificatore prima di essere eseguite, sotto il controllo di
un’unità apposita. Quest’ultima include la pipeline logica e fornisce i segnali di controllo (non
mostrati nella figura) a tutte le unità hardware del processore. I dati vengono messi nel banco dei
registri (a 32 bit). I byte e le mezze parole trattate come numeri in complemento a due sono estesi
a 32 bit.
Le istruzioni di elaborazione dei dati di ARM hanno tipicamente due registri sorgente, Rn e Rm, e
un registro destinazione (o risultato), Rd. I valori dei registri sorgente vengono dati in pasto alla
ALU o a un’unità separata per le moltiplicazioni che usa registri aggiuntivi per l’accumulo di
risultati parziali. Il processore ARM incorpora anche un’unità hardware che può shiftare o ruotare
il valore di Rm prima che venga immesso nella ALU. Quest’ultima operazione viene eseguita nei
limiti del tempo di esecuzione dell’istruzione e aumenta la potenza e la flessibilità di molte
operazioni di processamento dati.
Figura 3.9 Organizzazione semplificata di ARM
26
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
3.8.2.
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
Modi del processore
È abbastanza comune che un processore supporti un numero ridotto di modi di utilizzo. Ad
esempio, molti sistemi operativi utilizzano soltanto due modi: un modo utente e un modo kernel,
dove quest’ultimo è usato per l’esecuzione di software di sistema dotato di privilegi.
Contrariamente a quanto detto, la flessibilità dell’architettura ARM permette ai sistemi operativi
di utilizzare varie politiche di protezione.
L’architettura ARM supporta sette modi di esecuzione. La maggior parte dei programmi applicativi
viene eseguita in modo utente (user mode). In questa modalità il programma in esecuzione non
può accedere alle risorse protette del sistema e non può cambiare il modo, se non sollevando
un’eccezione.
I restanti sei modi di utilizzo sono detti privilegiati. Questi modi sono utilizzati per eseguire
software di sistema. I principali vantaggi nel definire così tanti modi privilegiati differenti sono due:
1. il sistema operativo può adattare l’utilizzo del software di sistema a svariate circostanze;
2. alcuni registri vengono dedicati all’utilizzo in ogni modo privilegiato, permettendo così
rapidi cambi di contesto.
I modi eccezione hanno accesso completo alle risorse di sistema e possono cambiare modo
liberamente. Cinque dei sei modi privilegiati sono conosciuti come modi eccezione. È possibile
entrare in queste modalità d’uso quando si verifica una specifica eccezione. Ognuna di queste
modalità ha dei registri dedicati che sostituiscono alcuni dei registri del modo utente e che sono
utilizzati per evitare di compromettere informazioni di stato del modo utente quando si verifica
un’eccezione. I modi eccezione sono i seguenti.





Modo supervisore (supervisor mode): il modo in cui opera di solito il sistema operativo. Si
entra in questo modo quando il processore incontra un’istruzione di interruzione software.
Le interruzioni software sono un modo standard per invocare un servizio del sistema
operativo sui processori ARM.
Modo abort (abort mode): vi si entra in risposta a errori di memoria.
Modo indefinito (undefined mode): vi si entra quando il processore tenta di eseguire
un’istruzione che non è supportata né dall’unità principale intera né da uno dei
coprocessori.
Modo interrupt veloce (fast interrupt mode): vi si entra ogni volta che il processore riceve
un segnale di interrupt dalla sorgente designata di interrupt veloce. Un interrupt veloce
non può essere interrotto, ma può interrompere un normale interrupt.
Modo interrupt: vi si entra quando il processore riceve un segnale di interrupt da una
sorgente di interrupt (diversa dalla sorgente di interrupt veloce). Un interrupt può essere
interrotto soltanto da un interrupt veloce.
Il modo privilegiato che resta è il modo sistema (system mode). Questo modo utilizza gli stessi
registri del modo utente e non è accessibile tramite alcuna eccezione. Il modo sistema è utilizzato
per eseguire alcuni task privilegiati del sistema operativo. I task nel modo sistema possono essere
interrotti da ognuno dei cinque modi eccezione.
3.8.3.
Organizzazione dei registri
La figura 3.10 illustra i registri ARM visibili all’utente. Il processore ARM ha 37 registri da 32 bit in
torale, classificati come segue:

31 registri definiti nel manuale come registri a uso generale, anche se alcuni, come il
program counter, hanno compiti specifici;
27
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb

Tesi di Laurea di:
Loredano Rapari
matr. 1029262
sei registri di stato del programma.
I registri sono sistemati in banchi parzialmente sovrapposti. Il modo del processore determina
quale banco è disponibile. Sono sempre disponibili 16 registri numerati e uno o due registri di
stato del programma, per un totale di 17 o 18 registri visibili al software. La figura 3.10 va letta
come segue:




i registri da R0 a R7, il registro R15 (il program counter) e il registro di stato corrente del
programma (CPSR) sono visibili e condivisi da tutti i modi;
i registri da R8 a R12 sono condivisi da tutti i modi eccetto quello di interrupt veloce, che ha
i suoi registri dedicati da R8_fiq a R12_fiq;
tutti i modi eccezione hanno la propria versione dei registri R13 e R14;
tutti i modi eccezione hanno un registro di stato del programma salvato (CPSR).
Figura 3.10 Organizzazione dei registri in ARM
3.8.3.1.
Registri a uso generale
Il registro R13 è normalmente usato come Stack Pointer ed è anche chiamato SP. Poiché ogni
modo eccezione ha il suo registro R13, ogni modo eccezione può avere il suo stack dedicato. Il
registro R14 è noto come registro link (LR) e viene utilizzato per mantenere gli indirizzi di ritorno
da procedure e dal modo eccezione. Il registro R15 è il Program Counter (PC).
28
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
3.8.3.2.
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
Registri di stato del programma
Il registro CPSR è accessibile in tutti i modi del processore. Ogni modo del processore ha il suo
registro SPSR dedicato, utilizzato per preservare il valore di CPSR quando si verifica l’eccezione
associata. I 16 bit più significativi di CPSR contengono dei flag visibili in modo utente, utilizzabili
per condizionare il funzionamento del programma (Figura 3.11).
I flag sono i seguenti.




Flag di codice di condizione: i flag N, Z, C e V visti precedentemente.
Flag Q: usato per indicare il verificarsi di un overflow e/o la saturazione in alcune istruzioni
SIMD-oriented.
Bit J: indica l’utilizzo di speciali istruzioni a 8 bit, dette istruzioni Jazelle.
Bit GE [3:0]: le istruzioni SIMD utilizzano i bit [19:16] come flag di maggiore o uguale (GE)
per byte singoli o mezze parole del risultato.
I 16 bit meno significativi di CPSR contengono flag di controllo di sistema che possono essere
modificati soltanto quando il processore è in modo privilegiato.
I campi sono i seguenti.




Bit E: controlla il tipo di endian per i dati di load e store; viene ignorato per il fetch delle
istruzioni.
Bit di disabilitazione degli interrupt: il bit A, quando vale 1, disabilita gli abort per dati
imprecisi; il bit I, quando vale 1, disabilita gli interrupt IRQ; il bit F, quando vale 1, disabilita
gli interrupt FIQ.
Bit T: indica se le istruzione devono essere interpretate come normali istruzioni o come
istruzioni Thumb.
Bit di modo: indicano il modo del processore.
3.8.4.
Gestione degli Interrupt
Come ogni processore il processore ARM possiede una funzione che gli permette di interrompere
il programma in esecuzione per gestire condizioni di eccezione. Le eccezioni vengono generate da
sorgenti interne o esterne per consentire al precessore la gestione di un evento. Lo stato del
processore un attimo prima che si occupi dell’eccezione viene di norma preservato in modo che
l’esecuzione del programma originale possa riprendere una volta che la routine di gestione
dell’eccezione è completata. È possibile che si presentino più eccezioni contemporaneamente.
L’architettura ARM ne supporta sette tipi. La tabella 3.3 elenca i tipi di eccezione e i modi di
processore che vengono utilizzati per affrontare questi tipi. Quando si verifica un’eccezione, viene
forzata l’esecuzione a partire da un indirizzo di memoria fissato dipendente dal tipo di eccezione.
Questi indirizzi fissi sono chiamati vettore di eccezione.
Se ci sono più interruzioni in attesa, queste vengono gestite in ordine di priorità. La tabella 3.3
elenca le eccezioni in ordine di priorità, dalla più alta alla più bassa.
Quando si verifica un’eccezione il processore blocca l’esecuzione dell’istruzione che segue quella
corrente. Lo stato del processore viene salvato nel registro SPSR corrispondente al tipo di
eccezione, in modo che l’esecuzione del programma originale possa riprendere una volta che la
routine di gestione dell’eccezione è completata. L’indirizzo dell’istruzione che il processore stava
per eseguire viene messo nel registro link del modo di processore appropriato. Per il ritorno dopo
la gestione dell’eccezione il registro SPSR viene spostato nel registro CPSR e il contenuto di R14
viene trasferito nel PC.
29
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
Tabella 3.3 Vettori di interrupt ARM
Tipo di eccezione
Reset
Abort di dati
Modo
Indirizzo normale
di entrata
Supervisore 0x00000000
Abort
0x00000010
FIQ (Interrupt
veloce)
FIQ
0x0000001C
IRQ (Interrupt)
IRQ
0x00000018
Abort di prefetch
Abort
0x0000000C
Istruzioni
indefinite
Indefinito
0x00000004
Interrupt software
Supervisore 0x00000008
30
Descrizione
Si verifica quando il sistema viene inizializzato.
Si verifica quando si accede ad un indirizzo di
memoria non valido, come nei casi in cui l’indirizzo
fisico di memoria non esiste o non si hanno i
necessari permessi per accedere all’indirizzo.
Si verifica quando un dispositivo esterno attiva il
pin FIQ del processore. Un interrupt non può
essere interrotto se non da un interrupt veloce.
FIQ è progettato per supportare trasferimento dati
e applicazioni su canali e ha un numero di registri
privati sufficiente a eliminare il bisogno di salvare i
registri, permettendo in questo modo di
minimizzare l’overhead del cambio di contesto.
L’interrupt veloce non può essere interrotto.
Si verifica quando un dispositivo esterno attiva il
pin IRQ del processore. Un interrupt può essere
interrotto soltanto da un interrupt veloce.
Si verifica quando un tentativo di fetch di un
istruzione genera un errore di memoria.
L’eccezione viene sollevata quando l’istruzione
entra nello stadio di esecuzione della pipeline.
Si verifica quando un’istruzione che non fa parte
del set di istruzioni raggiunge lo stadio di
esecuzione della pipeline.
È generalmente utilizzata per permettere a
programmi in modalità utente di invocare il
sistema operativo. Il programma utente esegue
un’interruzione SWI con un argomento che
identifica la funzione che l’utente vuole realizzare.
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
4. Marvell Kirkwood 88F6281
Come processore di test per provare i programmi compilati con le istruzioni Thumb, è stato usato
un dispositivo presente in laboratorio che monta un processore con architettura ARM. Il
dispositivo è uno Sheevaplug, cioè un plug computer progettato per consentire funzionalità di
calcolo standard nel minor spazio possibile.
Un plug computer è un piccolo server per l’utilizzo in casa o in ufficio. Comparati al PC, i plug
computer hanno costi minori, minori consumi, spesso non hanno la scheda video e sono pensati
per stare accesi continuamente. Infatti i plug computer sono spesso racchiusi nei trasformatori
stessi che convertono la corrente, il termine “plug” si riferisce al fatto che appaiono della stessa
forma dei dispositivi “plug and play”.
Il plug computer disponibile in laboratorio monta il processore Marvell Kirkwood aka Feroceon
88F6281 basato su architettura ARMv5TE
4.1. Caratteristiche della scheda
Nella tabella 4.1 sono elencate le caratteristiche della scheda.
Tabella 4.1 Caratteristiche del plug computer
Caratteristiche
Forma compatta del prodotto finale
Piattaforma Open Source
Alte prestazioni a bassi consumi
Processore di classe GHz
4.1.1.
Benefici
Adatto per test e prove iniziali
Riduzione dei tempi di produzione
Disponibile a basso costo per ogni sviluppatore
interessato
Disponibili diverse distribuzioni Linux
Supporto della Community
Ideale per applicazioni sempre attive
Facilità di porting del software senza modifiche
Esegue più applicazioni contemporaneamente
Risposte veloci alle applicazioni interattive
Accesso rapido ai dispositivi di memoria
connessi via USB 2.0
Componenti di sistema
Sheeva CPU Core
-
Velocità di clock 1.2 GHz
Cache L1: 16 KB istruzioni + 16 KB dati
Cache L2: 256 KB
Memoria
-
Ram: DDR2 400 MHz, bus 16 bit, 512 MB
Rom: NAND Flash Controller, bus 8 bit, 512 MB, boot diretto
Alimentazione
-
Input: 100-240 V AC/50-60 Hz 20 W Max.
Output: 5 V DC/3.0 A Max.
Interfaccia di sviluppo
31
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
-
Tavola di sviluppo del sistema
Interfacce JTAG e Console via USB
Espansione SDIO
Supporto JTAG OpenOCD via USB
Certificati UL/CE/FCC
I/O
-
1 x Gigabit Ethernet
1 x USB 2.0 collegamento dispositivi di memorizzazione
1 x USB 2.0 collegamento a PC per sviluppo
AC/DC 5 V In
4.1.2.
Schema a blocchi dell’ hardware
Figura 4.1 Schema a blocchi dell’hardware
32
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
5. Set di Istruzioni Thumb (Manuale Parte 1)
In questo capitolo si introduce il set di istruzioni Thumb e si descrive come il Thumb usa il Modello
Programmatori ARM. Il capitolo contiene le seguenti sezioni:








Introduzione al Thumb Instruction Set
Codifica del Set istruzioni
Istruzioni di salto
Istruzioni Data-processing
Istruzioni Load and Store Register
Istruzioni Load and Store Multiple
Istruzioni per la generazione di eccezioni
Spazio indefinito delle istruzioni
33
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
5.1. Introduzione al set di istruzioni Thumb
Il set delle istruzioni Thumb è un subset ricodificato del set di istruzioni ARM. Il Thumb è pensato
per aumentare le performance delle implementazioni ARM che usano un bus dati a 16-bit o anche
più piccolo e per permettere una densità di codice migliore di quella fornita dal set di istruzioni
ARM. La variante T dell’architettura ARMv5 incorpora entrambi i set di istruzioni, sia quello ARM a
32-bit che quello Thumb a 16-bit. Ogni istruzione Thumb è codificata in 16 bits. Il supporto al
Thumb è obbligatorio in ARMv6.
Il Thumb non altera il modello basilare della programmazione dell’architettura ARM. Presenta
solamente un accesso limitato a questo modello. Tutte le istruzioni data-processing del Thumb
operano su valori a 32-bit, e indirizzi a 32-bit sono prodotti sia dalle istruzioni data-processing sia
dal fetch dell’istruzione.
Quando il processore sta eseguendo le istruzioni Thumb, sono disponibili 8 registri generici, da R0
a R7, i quali sono gli stessi registri fisici da R0 a R7 di quando esegue le istruzioni ARM. Alcune
istruzioni Thumb accedono anche al Program Counter (in ARM è il registro 15), al Link Register (in
ARM è il registro 14) e allo Stack Pointer (in ARM è il registro 13). Le altre istruzioni permettono un
accesso limitato ai registri ARM da 8 a 15, i quali sono detti high registers.
Quando R15 viene letto, il bit[0] è zero e i bits[31:1] contengono il PC. Quando R15 viene scritto, il
bit[0] viene ignorato e i bits[31:1] vengono scritti nel PC. A seconda di come è usato, il valore del
PC o è l’indirizzo dell’istruzione più 4 oppure è sconosciuto.
L’esecuzione in Thumb è “flaggata” dal bit T (bit*5+) nel registro CSPR (Current State Program
Register):
T=0
Nella fase di fetch vengono prelevate istruzioni a 32-bit (il PC viene incrementato di
4) e sono eseguite come istruzioni ARM.
T=1
Nella fase di fetch vengono prelevate istruzioni a 16-bit (il PC viene incrementato di
2) e sono eseguite come istruzioni Thumb.
In ARMv6 le istruzioni Thumb forniscono un accesso limitato al CPSR con l’istruzione CPS. Non c’è
un accesso diretto ai registri SPRS. Versioni precedenti non forniscono un accesso diretto al CPSR
mentre nel set ARM le istruzioni MSR ed MRS lo permettono.
5.1.1.
Attivare lo stato Thumb
L’esecuzione Thumb è normalmente attivata dall’esecuzione dell’istruzione ARM BX (Branch and
Exchange). Questa istruzione salta ad un indirizzo memorizzato in un registro generico, e se il
bit*0+ di questo registro è 1, l’esecuzione Thumb parte dall’istruzione puntata dall’indirizzo
contenuto nel registro. Se il bit*0+ è 0, continua l’esecuzione ARM dall’istruzione puntata
dall’indirizzo contenuto nel registro. Dalla versione ARMv5T le istruzioni BLX e LDR/LDM che caricano
il PC possono essere usate in modo simile.
L’esecuzione Thumb può anche essere iniziata settando il bit T del registro SPSR ed eseguendo un
istruzione ARM che ripristina il CPSR dal SPSR. Questo permette al sistema operativo di rieseguire
un processo indipendentemente dal fatto che questo stia eseguendo un codice Thumb oppure
ARM.
Il risultato è imprevedibile se il bit T viene alterato direttamente scrivendo sul CPSR.
34
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
5.1.2. Eccezioni
Le eccezioni generate durante l’esecuzione Thumb passano all’esecuzione ARM prima di eseguire
il gestore delle eccezioni (la prima istruzione del quale si trova nel vettore hardware). Lo stato del
bit T è mantenuto nel SPSR, e il registro LR (Link Register, R14) della modalità eccezione è settato
in modo che l’istruzione di ritorno all’esecuzione normale funzioni correttamente, questo accade
sempre quando si verifica un’eccezione, non importa che l’esecuzione sia ARM o Thumb.
La tabella A6-1 elenca i valori del registro LR del modo Eccezione per le eccezioni generate durante
l’esecuzione Thumb.
Tabella 5.1 Istruzioni di ritorno dalle Eccezioni
Eccezione
Valore di LR del modo Eccezione
Istruzione di ritorno
Reset
Valore IMPREVEDIBILE
-
Undefined
Indirizzo dell’istruzione Undefined + 2
MOVS
PC, R14
SWI
Indirizzo dell’istruzione SWI + 2
MOVS
PC, R14
Prefetch Abort Indirizzo dell’istruzione Prefetch Abort + 4
SUBS
PC, R14, #4
Data Abort
Indirizzo dell’istruzione che ha generato l’errore
+8
SUBS
PC, R14, #8
IRQ
Indirizzo dell’istruzione successiva da eseguire
SUBS
PC, R14, #4
FIQ
Indirizzo dell’istruzione successiva da eseguire
SUBS
PC, R14, #4
--------------- Note ------------------------Per ogni eccezione, l’istruzione di ritorno indicate dalla tabella A6-1 è la stessa istruzione richiesta
se l’esecuzione avvenisse durante l’esecuzione ARM. Comunque i seguenti due tipi di eccezioni
hanno un metodo di ritorno secondario, per il quale sono necessarie diverse istruzioni di ritorno a
seconda che l’eccezione avvenga durante l’esecuzione ARM oppure Thumb:

Per l’eccezione Data Abort, il metodo di ritorno principale causa la ripresa dell’esecuzione
proprio dall’istruzione che ha generato l’eccezione, la quale viene rieseguita. È anche
possibile ritornare all’istruzione successiva a quella che ha generato l’eccezione, usando
l’istruzione SUBS PC, R14, #4. Se questo tipo di ritorno è richiesto per un Data Abort causato
da un’istruzione Thumb, si usa SUBS PC, R14, #6 come istruzione di ritorno.

Per l’eccezione Undefined, il metodo principale di ritorno causa la ripresa dell’esecuzione
dall’istruzione successiva a quella che ha generato l’eccezione. È anche possibile ritornare
all’istruzione stesa che ha generato l’eccezione usando SUBS PC, R14, #4. Se questo tipo di
ritorno è richiesto per un Undefined causato da un’istruzione Thumb si usa SUBS PC, R14,
#2. Comunque, l’uso principale di questo tipo di ritorno è per alcuni tipi di istruzioni
coprocessore, e siccome il set di istruzioni Thumb non contiene alcuna istruzione
coprocessore, è improbabile necessitare di questo metodo secondario di ritorno per
istruzioni Thumb.
Quando sono usati questi metodi secondari di ritorno, il codice che gestisce le eccezioni deve
testare il bit T del registro SPSR per determinare quale delle due istruzioni di ritorno deve usare.
----------------------------------------------35
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
5.2. Codifica del set istruzioni
Nella figura 5.1 è riportata la codifica del set di istruzioni Thumb.
Figura 5.1 Panorama della codifica del set di istruzioni Thumb
1. Il campo opc non può essere 11 in questa riga. Altre righe trattano il caso in cui il campo
opc è 11.
2. Il campo cond non può essere 1110 o 1111 in questa riga. Altre righe trattano il caso in cui
il campo cond è 1110 o 1111.
3. La forma con L = 1 è IMPREVEDIBILE prima della versione ARMv5T.
4. Questa è un’istruzione indefinita prima di ARMv5T.
36
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
5.2.1.
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
Istruzioni varie
La figura A6-2 elenca le istruzioni miste
Figura 5.2 Istruzioni varie Thumb
1. Era un’istruzione indefinita prima di ARMv5.
2. Erano istruzioni indefinite prima di ARMv6.
--------------- Note ------------------------Ogni istruzione con i bits[15:12] = 1011, e che non è illustrata in figura A6-2 è un’istruzione
indefinita.
-----------------------------------------------
37
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
5.3. Istruzioni di salto
Il Thumb supporta sei tipi di istruzioni di salto:






un salto condizionato che permette salti in avanti e all’indietro fino a 256 bytes
un salto incondizionato che permette salti in avanti o all’indietro fino a 2 KB
un salto con link (chiamata a una funzione) è supportato con una coppia di istruzioni che
permettono salti in avanti e all’indietro fino a 4 MB (-222 <= offset <= +222 - 2)
un salto con link e scambio usa una coppia di istruzioni, simili alle precedenti, ma in più
passa all’esecuzione di codice ARM
un’istruzione si salto e scambio salta ad un indirizzo in un registro e opzionalmente salta
all’esecuzione di codice ARM
una seconda forma di istruzione di salto con link e scambio esegue una chiamata ad una
subroutine il cui indirizzo è in un registro e opzionalmente passa all’esecuzione di codice
ARM
La codifica di queste istruzioni è illustrata di seguito.
5.3.1.
B
Salto condizionato
<condizione> <indirizzo di destinazione>
5.3.2.
Salto incondizionato
B
<indirizzo di destinazione>
BL
<indirizzo di destinazione>
; Produce due istruzioni da 16-bit
BLX
<indirizzo di destinazione>
; Produce due istruzioni da 16-bit
5.3.3.
BX
<Rm>
BLX
<Rm>
38
Salto con scambio
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
5.4. Istruzioni Data-Processing
Le istruzioni di processamento dei dati del set Thumb, sono un sottoinsieme di quelle del set ARM.
Sono divise in due gruppi: il primo gruppo può operare solo sui registri bassi, r0-r7, il secondo può
operare sui registri alti, r8-r15, oppure su entrambi.
5.4.1.
Istruzioni che operano sui registri bassi
Le istruzioni che operano sui registri bassi sono mostrate in Tabella A6-2. Alcune di queste
istruzioni appaiono anche nella lista di istruzioni che operano sui registri alti. Quando operano sui
registri bassi, tutte le istruzioni in questa tabella, eccetto CPY, modificano i flags di stato.
Tabella 5.2 Istruzioni Data-Processing che operano sui registri bassi
39
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
Tabella 5.2 Istruzioni Data-Processing che operano sui registri bassi (continua)
Per esempio:
ADD
SUB
ADD
ADD
NEG
AND
EOR
CMP
CMP
MOV
40
R0,
R6,
R0,
R1,
R3,
R2,
R1,
R2,
R7,
R0,
R4,
R7
R1,
R2
#255
R4,
#4
R1
R5
R6
R3
#100
#200
;
;
;
;
;
;
;
;
;
;
R0 = R4 + R7
R6 = R1 – R2
R0 = R0 + 255
R1 = R4 + 4
R3 = 0 – R1
R2 = R2 AND R5
R1 = R1 EOR R6
aggiorna il flag dopo R2 – R3
aggiorna il flag dopo R7 – 100
R0 = 200
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
5.4.2.
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
Istruzioni che operano sui registri alti
Ci sono otto tipi di istruzioni data-processing che operano sui registri ARM dall’8 al 14 e sul PC
come mostrato nella tabella A6-3. A parte cmp, le istruzioni nella tabella non cambiano i flag di
stato.
Tabella 5.3 Istruzioni Data-Processing che operano sui registri alti
Per esempio:
MOV
ADD
MOV
CMP
SUB
ADD
ADD
ADD
R0,
R10,
PC,
R10,
SP,
SP,
R2,
R0,
R12
R1
LR
R11
#12
#16
SP,
PC,
;
;
;
;
;
;
#20 ;
#500 ;
R0 = R12
R10 = R10 + R1
PC = R14
aggiorna i flag dopo R10 – R11
incrementa lo stack pointer di 12 bytes
decrementa lo stack pointer di 16 bytes
R2 = SP + 20
R0 = PC + 500
41
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
5.4.3.
Formati
Le istruzioni data-processing usano i seguenti otto formati:
Formato 1
Formato 2
Formato 3
Formato 4
Formato 5
Formato 6
42
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
Formato 7
Formato 8
43
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
5.5. Istruzioni Load and Store Register
Il Thumb supporta otto tipi di istruzioni di lettura e scrittura sui registri. Sono disponibili due modi
di indirizzamento di base. Questi permettono la lettura e la scrittura di parole (4 Bytes), mezze
parole (2 Bytes) e bytes (1 Byte), e anche di mezze parole e bytes con segno:


registro più registro
registro più 5-bit immediato (non disponibile per le mezze parole e i bytes con segno)
Se viene usato un offset immediato, viene scalato di 4 per l’accesso ad una parola e di 2 per
l’accesso ad una mezza parola.
In più, tre istruzioni speciali permettono:


alle parole di essere caricate usando il PC come base con un offset immediato di 1 KB
alle parole di essere caricate e salvate con lo stack pointer (R13) come base e un offset
immediato di 1 KB
5.5.1.
Formati
Le istruzioni di lettura e scrittura sui registri hanno i seguenti formati:
Formato 1
Formato 2
Formato 3
Formato 4
44
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
Per esempio:
LDR
LDR
STR
STRB
STRH
LDRH
LDRB
LDR
LDR
STR
R4,
R4,
R0,
R1,
R4,
R3,
R2,
R6,
R5,
R4,
[R2,
[R2,
[R7,
[R5,
[R2,
[R6,
[R1,
[PC,
[SP,
[SP,
#4]
R1]
#0x7C]
#31]
R3]
R5]
#5]
#0x3FC]
#64]
#0x260]
;
;
;
;
;
;
;
;
;
;
Carica la parola in R4 dall’indirizzo R2 + 4
Carica la parola in R4 dall’indirizzo R2 + R1
Scrive la parola da R0 all’indirizzo R7 + 124
Scrive il byte da R1 all’indirizzo R5 + 31
Scrive una mezza parola da R4 a R2 + R3
Carica una mezza parola in R3 da R6 + R5
Carica un byte in R2 da R1 + 5
Carica R6 da PC + 0x3FC
Carica R5 da SP + 64
Carica R5 da SP + 0x260
45
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
5.6. Istruzioni Load and Store Multiple
Il Thumb supporta quattro tipi di istruzioni di lettura e scrittura multipla:


Due istruzioni, LDMIA e STMIA, sono progettate per supportare la copia di blocchi. Hanno un
indirizzamento con post-incremento fisso da un registro di base.
Le altre due istruzioni, PUSH e POP, hanno anche loro un modo di indirizzamento fisso.
Implementano uno stack a cascata e lo stack pointer (R13) è usato come base.
Tutte e quattro le istruzioni aggiornano il registro base dopo il trasferimento e tutte possono
trasferire alcuni o tutti gli 8 registri. PUSH può anche impilare l’indirizzo di ritorno, e POP può
caricare il PC.
5.6.1.
Formati
Le istruzioni di lettura e scrittura multipla hanno I seguenti formati:
Formato 1
Formato 2
5.6.2.
LDMIA
STMIA
Esempi
R7!,
R0!,
{R0-R3,R5}
{R3, R4, R5}
;
;
Carica R0 in R3-R5 da R7, aggiunge 20 a R7
Scrive R3-R5 in R0, aggiunge 12 in R0
;
;
;
;
;
push nello stack (R13) R0-R7 e
l’indirizzo di ritorno al
codice del corpo della funzione
ricarica R0-R7 dallo stack
e il PC, e ritorna
function
PUSH
{R0-R7, LR}
POP
{R0-R7, PC}
…
…
46
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
5.7. Istruzioni per la generazione di eccezioni
Il set di istruzioni Thumb fornisce due tipi di istruzione il quale scopo principale è di far verificare
eccezione di processore:


L’istruzione Software Interrupt (SWI) è usata per causare un’eccezione SWI (vedere
Software Interrupt Exception). Questo è il meccanismo principale con il quale il codice
Utente può fare chiamate al codice privilegiato del Sistema Operativo.
L’istruzione Breakpoint (BKPT) è usata per punti di rottura (breakpoints) software in
ARMv5T e superiori. Il suo comportamento di default è quello di causare un’eccezione di
Prefetch Abort (vedere Prefetch Abort (fallimento di fetch dell’istruzione da memoria)). Un
programma monitor di debug che è stato preventivamente installato nel vettore Prefetch
Abort può gestire questa eccezione.
Se è presente nel sistema il debug hardware, è autorizzato a non tener conto del comportamento
di default.
5.7.1.
Codifica delle istruzioni
In entrambe swi e bkpt, il campo immed_8 dell’istruzione è ignorato dal processore ARM. I gestori
delle interruzioni possono essere opzionalmente scritti per caricare l’istruzione che ha causato
l’eccezione ed estrarre questi campi. Questo permette loro di essere usati per comunicare
informazioni extra riguardo le chiamate al Sistema Operativo.
47
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
5.8. Spazio indefinito delle istruzioni
Le seguenti istruzioni sono INDEFINITE nel set Thumb:
In generale, queste istruzioni possono essere usate per estendere il set Thumb in futuro. Tuttavia,
è sottointeso che un futuro gruppo di istruzioni non sarà usato in questa maniera:
Usare una di queste istruzioni se si vuole usare un’istruzione indefinita per scopi software, con il
minimo rischio che un futuro hardware le tratterà come istruzioni definite.
48
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
6. Istruzioni Thumb (Manuale parte 2)
Questo capitolo descrive la sintassi e l’uso di ogni istruzione Thumb, nelle sezioni:


Lista in ordine alfabetico delle istruzioni Thumb
Istruzioni Thumb e versioni dell’architettura
49
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
6.1. Lista in ordine alfabetico delle istruzioni Thumb
Tutte le istruzioni Thumb sono presenti nelle seguenti pagine. Ogni descrizione mostra:







la codifica dell’istruzione
la sintassi dell’istruzione
le versioni di ARM in cui l’istruzione è valida
le eccezioni che potrebbero verificarsi
uno pseudocodice su come opera l’istruzione
note sull’uso e casi speciali
l’equivalente codifica ARM
6.1.1.
Note generali
Queste note spiegano il tipo di informazioni e abbreviazioni usate nelle pagine successive.
Sintassi abbreviazioni
Sono usate le seguenti abbreviazioni:
immed_<n>
È un valore immediato a <n>-bit. Per esempio, un valore a 8-bit immediato è
rappresentato da: immed_8
signed_immed_<n> È un valore immediato con segno a <n>-bit. Per esempio, un valore con
segno a 8-bit immediato è rappresentato da: immed_signed_8
Versione architettura
Questa sezione descrive la versione dell’architettura ARM con cui è associata l’istruzione, non la
versione del set di istruzioni Thumb. Ci sono tre versioni del set Thumb:
THUMBv1 è usato nella variante T di ARMv4.
THUMBv2 è usato nella variante T di ARMv5.
THUMBv3 è usato in ARMv6 e superiori.
Le istruzioni che sono descritte come presenti in tutte le varianti T sono presenti in THUMBv1,
THUMBv2 e THUMBv3. Quelle che sono descritte come appartenenti alla variante T delle versioni
6 e superiori sono presenti solo nel THUMBv3.
Sintassi e codifica ARM equivalenti
Questa sezione mostra la sintassi e la codifica dell’istruzione ARM equivalente. Quando non è
disponibile un equivalente preciso, viene mostrata un’istruzione simile e vengono spiegate le
ragioni per cui non esiste l’equivalente preciso.
Una ragione comune per cui non ci sono istruzioni equivalenti è che queste leggono il valore del
PC. Questo produce l’indirizzo dell’istruzione più N, dove N è 8 per le istruzioni ARM e 4 per le
istruzioni Thumb. Questa differenza può essere spesso compensata con l’aggiustamento di una
costante immediata nell’equivalente istruzione ARM.
Nella codifica equivalente, i campi con nome e i vari bits devono essere riempiti con i
corrispondenti campi e bits dell’istruzione Thumb, o in alcuni casi con i valori derivati
dall’istruzione Thumb come descritto nel testo.
I campi dell’istruzione ARM sono normalmente della stessa lunghezza dei campi dell’istruzione
Thumb corrispondente, con una importante eccezione. I campi registro del Thumb sono lunghi
normalmente 3 bits, dove invece i campi registro dell’ARM sono di 4 bits. In questi casi, il campo
registro del Thumb deve essere esteso con uno 0 nel bit più significativo quando va a sostituire il
campo registro dell’ARM, così che l’istruzione ARM fa riferimento al registro corretto tra R0 e R7.
50
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
Informazioni sull’uso
L’informazione sull’uso è data per l’istruzione Thumb solo se questa differisce significativamente
dall’uso della corrispondente istruzione ARM. Se questa sezione non compare bisogna andare a
vedere la sezione informazioni sull’uso della corrispondente istruzione ARM.
51
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
6.1.2.
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
ADC
ADC (Add with Carry) somma due valori e il flag Carry.
Usare ADC per sintetizzare le addizioni multi-parola.
ADC aggiorna i flag di stato, a seconda del risultato.
Sintassi
ADC <Rd>, <Rm>
dove:
<Rd>
Memorizza il primo valore dell’addizione, ed è il registro di destinazione.
<Rm>
Specifica il registro che contiene il secondo operando dell’addizione.
Versione architettura
Tutte le varianti T
Eccezioni
Nessuna
Operazione
Rd = Rd + Rm + C Flag
N Flag = Rd[31]
// Flag Negative, se 1 è negativo, se 0 è positivo
Z Flag = if(Rd == 0) {1} else {0}
// Flag Zero
C Flag = CarryFrom(Rd + Rm + C Flag)
// Flag Carry
V Flag = OverflowFrom(Rd + Rm + C Flag)
// Flag Overflow
Sintassi e codifica equivalente ARM
ADCS <Rd>, <Rd>, <Rm>
52
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
6.1.3.
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
ADD(1)
ADD(1)
somma il valore di una piccola costante ad un registro e salva il risultato in un secondo
registro.
Aggiorna i flag di stato, a seconda del risultato.
Sintassi
ADD
<Rd>, <Rn>, #<immed_3>
dove:
<Rd>
Registro di destinazione.
<Rn>
Specifica il registro che contiene l’operando dell’addizione.
<immed_3>
Specifica un valore a 3-bit che viene aggiunto ad Rn.
Versione architettura
Tutte le varianti T
Eccezioni
Nessuna
Operazione
Rd = Rn + immed_3
N Flag = Rd[31]
Z Flag = if(Rd == 0) {1} else {0}
C Flag = CarryFrom(Rn + immed_3)
V Flag = OverflowFrom(Rn + immed_3)
Sintassi e codifica equivalente ARM
ADDS <Rd>, <Rn>, #<immed_3>
53
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
6.1.4.
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
ADD(2)
ADD(2) somma il valore di una grande costante ad un registro e salva il risultato nel registro stesso.
Aggiorna i flag di stato, a seconda del risultato.
Sintassi
ADD <Rd>, #<immed_8>
dove:
<Rd>
Contiene il primo operando dell’addizione ed è il registro di destinazione.
<immed_8>
Specifica un valore a 8-bit che viene aggiunto ad Rd.
Versione architettura
Tutte le varianti T
Eccezioni
Nessuna
Operazione
Rd = Rd + immed_8
N Flag = Rd[31]
Z Flag = if(Rd == 0) {1} else {0}
C Flag = CarryFrom(Rd + immed_8)
V Flag = OverflowFrom(Rd + immed_8)
Sintassi e codifica equivalente ARM
ADDS <Rd>, <Rd>, #<immed_8>
54
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
6.1.5.
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
ADD(3)
ADD(3)
somma il valore di un registro al valore di un secondo registro e salva il risultato in un terzo
registro.
Aggiorna i flag di stato, a seconda del risultato.
Sintassi
ADD <Rd>, <Rn>, <Rm>
dove:
<Rd>
È il registro di destinazione del risultato della somma.
<Rn>
È il registro che contiene il primo operando dell’ addizione.
<Rm>
È il registro che contiene il secondo operando dell’ addizione.
Versione architettura
Tutte le varianti T
Eccezioni
Nessuna
Operazione
Rd = Rn + Rm
N Flag = Rd[31]
Z Flag = if(Rd == 0) {1} else {0}
C Flag = CarryFrom(Rn + Rm)
V Flag = OverflowFrom(Rn + Rm)
Sintassi e codifica equivalente ARM
ADDS <Rd>, <Rn>, <Rm>
55
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
6.1.6.
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
ADD(4)
ADD(4) somma i valori di due registri, di cui uno o entrambi sono registri alti.
Diversamente dalle istruzioni add che agiscono solo sui registri bassi, questa istruzione non cambia
i flags.
Sintassi
ADD <Rd>, <Rm>
dove:
<Rd>
Specifica il registro contenente il primo valore, ed è anche il registro di destinazione.
Può essere uno qualunque tra R0 e R15. Il numero del registro è codificato
nell’istruzione in H1 (bit più significativo) e in Rd (i restanti 3 bit).
<Rm>
Specifica il registro contenente il secondo valore. Può essere uno qualunque tra R0
e R15. Il numero del registro è codificato nell’istruzione da H2 (bit più significativo) e
da Rm (restanti 3 bit).
Versione architettura
Tutte le varianti T
Eccezioni
Nessuna
Operazione
Rd = Rd + Rm
Note
Se vengono specificati due registry bassi in Rd e Rm, il risultato è IMPREVEDIBILE.
Sintassi e codifica equivalente ARM
Un equivalente simile è:
ADD
<Rd>, <Rd>, <Rm>
Ci sono lievi differenze quando l’istruzione accede al PC, a causa delle differenti definizioni di PC
durante l’esecuzione del codice ARM e Thumb.
56
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
6.1.7.
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
ADD(5)
ADD(5)
somma un valore immediato al PC e scrive l’indirizzo relativo risultante in un registro di
destinazione. Il valore immediato può essere un multiplo di 4 nel range tra 0 e 1020.
I flags di stato non vengono modificati.
Sintassi
ADD <Rd>, PC, #<immed_8> * 4
dove:
<Rd>
È il registro di destinazione.
PC
Indica il Program Counter.
<immed_8>
Specifica un valore immediato ad 8 bit che viene moltiplicato per 4 e aggiunto al PC.
Versione architettura
Tutte le varianti T
Eccezioni
Nessuna
Operazione
Rd = (PC AND 0xFFFFFFFC) + (immed_8 * 4)
Sintassi e codifica equivalente ARM
Un equivalente simile è:
ADD
<Rd>, PC, #<immed_8> * 4
Le definizioni di PC differiscono tra i codici ARM e Thumb. Questo implica una differenza tra i
risultati precisi delle istruzioni.
57
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
6.1.8.
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
ADD(6)
ADD(6)
somma un valore immediato allo SP e scrive l’indirizzo relativo risultante in un registro di
destinazione. Il valore immediato può essere un multiplo di 4 nel range tra 0 e 1020.
I flags di stato non vengono modificati.
Sintassi
ADD <Rd>, SP, #<immed_8> * 4
dove:
<Rd>
È il registro di destinazione.
SP
Indica lo Stack Pointer.
<immed_8>
Specifica un valore immediato ad 8 bit che viene moltiplicato per 4 e aggiunto al SP.
Versione architettura
Tutte le varianti T
Eccezioni
Nessuna
Operazione
Rd = SP + (immed_8 << 2) // l’operatore ‘<<’ indica lo shift aritmetico a sinistra di n bit, che
equivale a moltiplicare per 2n.
Sintassi e codifica equivalente ARM
ADD <Rd>, SP, #<immed_8> * 4
58
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
6.1.9.
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
ADD(7)
ADD(7) incrementa lo SP di un valore a 7 bit moltiplicato per 4 (range tra 0 e 508).
I flags di stato non vengono modificati.
Sintassi
ADD SP, #<immed_7> * 4
dove:
SP
Contiene il primo operando della somma ed è anche il registro di destinazione.
<immed_7>
Specifica un valore immediato a 7 bit che viene moltiplicato per 4 e aggiunto allo SP.
Versione architettura
Tutte le varianti T
Eccezioni
Nessuna
Operazione
SP = SP + (immed_7 << 2)
// l’operatore ‘<<’ indica lo shift aritmetico a sinistra di n bit, che
n
equivale a moltiplicare per 2 .
Uso
Per lo stack decrescente che usa il set Thumb, incrementare lo SP significa eliminare i dati all’inizio
dello stack.
Note
Questa istruzione può anche essere scritta in questo modo: add SP, SP, #<immed_7> * 4.
Sintassi e codifica equivalente ARM
ADD SP, SP, #<immed_7> * 4
59
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
6.1.10. AND
AND (AND logico) esegue un AND bit a bit tra
i valori dei due registri.
Aggiorna i flag di stato, a seconda del risultato.
Sintassi
AND <Rd>, <Rm>
dove:
<Rd> Specifica il registro contenente il primo operando ed è anche il registro di destinazione.
<Rm> Specifica il registro contenente il secondo operando.
Versione architettura
Tutte le varianti T
Eccezioni
Nessuna
Operazione
Rd = Rd AND Rm
N Flag = Rd[31]
Z Flag = if(Rd == 0) {1} else {0}
C Flag = non interessato
V Flag = non interessato
Sintassi e codifica equivalente ARM
ANDS <Rd>, <Rd>, <Rm>
60
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
6.1.11. ASR(1)
(Arithmetic Shift Right) fornisce il valore con segno del contenuto di un registro diviso per una
costante potenza del 2.
ASR
Aggiorna i flag di stato, a seconda del risultato.
Sintassi
ASR <Rd>, <Rm>, #<immed_5>
dove:
<Rd>
Specifica il registro di destinazione.
<Rm>
Specifica il registro contenente il valore che deve essere shiftato.
<immed_5>
Specifica il valore dello shift da 1 a 31. Lo shift da 1 a 31 è codificato direttamente in
immed_5. Uno shift di 32 è codificato come immed_5 = 0.
Versione architettura
Tutte le varianti T
Eccezioni
Nessuna
Operazione
if (immed_5 == 0)
C Flag = Rm[31]
if (Rm[31] == 0 then)
Rd = 0
else /* Rm[31] == 1 */
Rd = 0xFFFFFFFF
else /* immed_5 > 0 */
C Flag = Rm[immed_5 - 1]
Rd = Rm Arithmetic_Shift_Right immed_5
N Flag = Rd[31]
Z Flag = if (Rd == 0) {1} else {0}
V Flag = unaffected
61
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
Sintassi e codifica equivalente ARM
MOVS <Rd>, <Rm>, asr #<immed_5>
Shift Aritmetico destro
Ogni bit dell’operando è semplicemente spostato verso destra di un dato numero di bit, e le
posizioni che rimangono vuote vengono riempite. Invece di riempirle con tutti zeri, come nello
shift logico, il bit più significativo (MSB – di solito rappresenta il segno nella rappresentazione
binaria dei numeri) viene replicato per riempire tutte le posizioni rimaste vuote. Fare lo shift
destro di n bits in un numero binario con segno in complemento a due, equivale a dividerlo per 2 n,
con il risultato arrotondato per difetto.
62
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
6.1.12. ASR(2)
(Arithmetic Shift Right) fornisce il valore con segno del contenuto di un registro diviso per una
variabile potenza del 2.
ASR
Aggiorna i flag di stato, a seconda del risultato.
Sintassi
ASR <Rd>, <Rs>
dove:
<Rd> Contiene il valore da shiftare ed è il registro di destinazione.
<Rs>
Specifica il registro contenente il valore dello shift.
Versione architettura
Tutte le varianti T
Eccezioni
Nessuna
Operazione
if (Rs[7:0] == 0)
C Flag = unaffected
Rd = unaffected
else if (Rs[7:0] < 32)
C Flag = Rd[Rs[7:0] - 1]
Rd = Rd Arithmetic_Shift_Right Rs[7:0]
else /* Rs[7:0] >= 32 */
C Flag = Rd[31]
if (Rd[31] == 0)
Rd = 0
else /* Rd[31] == 1 */
Rd = 0xFFFFFFFF
N Flag = Rd[31]
Z Flag = if Rd == 0 then 1 else 0
V Flag = unaffected
63
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Sintassi e codifica equivalente ARM
MOVS <Rd>, <Rd>, asr <Rs>
64
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
6.1.13. B(1)
B (Branch) salto condizionato verso un indirizzo.
Sintassi
B <cond>, <target_address>
dove:
<cond>
È la condizione sotto la quale l’istruzione viene eseguita.
<target_address>
Specifica l’indirizzo a cui saltare. L’indirizzo è calcolato in questo modo:
1. Shiftando verso sinistra di un bit il campo signed_immed_8 dell’istruzione.
2. Estendendo il segno a 32 bits.
3. Aggiungendo il risultato al contenuto del PC (che contiene l’indirizzo
dell’istruzione di salto più 4).
Questa istruzione può quindi specificare un salto di -256 o + 254 bytes,
relativamente al valore corrente del PC (R15).
Versione architettura
Tutte le varianti T
Eccezioni
Nessuna
Operazione
if (ConditionPassed(cond))
PC = PC + (SignExtend(signed_immed_8) << 1)
// ‘<<’ indica lo shift aritmetico a sinistra
Uso
Per calcolare l’esatto valore di signed_immed_8, l’assembler deve:
1. Formare l’indirizzo base per il salto. Ossia l’indirizzo dell’istruzione di salto, più 4. In altre
parole, l’indirizzo base è uguale al valore del PC letto da questa istruzione.
2. Sottrarre l’indirizzo base dall’indirizzo di destinazione per formare l’offset. Questo offset è
sempre pari, perché tutte le istruzioni Thumb sono allineate a mezze parole (2 bytes).
3. Se l’offset è fuori dall’intervallo da -256 a +254, una strategia di generazione dell’indirizzo
alternativa oppure generare un errore appropriato.
4. Altrimenti, settare il campo signed_immed_8 dell’istruzione nel byte offset diviso 2.
65
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Note
Limiti di memoria
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
Saltare all’indietro prima dello zero o in avanti oltre la fine dello spazio
indirizzi a 32-bit porta risultati imprevedibili.
Condizione AL
Se nel campo condizione è presente la condizione AL (0b1110), l’istruzione è
indefinita. Quando è richiesto un salto incondizionato si usa l’istruzione
apposita descritta in seguito.
Condizione NV
Se nel campo condizione è indicato
(Software Interrupt).
NV
(0b1111), l’istruzione indica un
SWI
Sintassi e codifica equivalente ARM
B <cond>, <target_address>
Questa istruzione è diversa dall’istruzione Thumb, perché l’offset dell’istruzione ARM viene
shiftato a sinistra di sue bit prima di essere aggiunto al PC, invece l’offset dell’istruzione Thumb
viene shiftato verso sinistra di un bit. Così il valore del PC letto dalle istruzioni ARM e Thumb sono
diversi.
66
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
6.1.14. B(2)
B (2) salto incondizionato verso un indirizzo.
Sintassi
B <target_address>
dove:
<target_address>
Specifica l’indirizzo a cui saltare. L’indirizzo è calcolato in questo modo:
1. Shiftando verso sinistra di un bit il campo signed_immed_11 dell’istruzione.
2. Estendendo il segno a 32 bits.
3. Aggiungendo il risultato al contenuto del PC (che contiene l’indirizzo
dell’istruzione di salto più 4).
Questa istruzione può quindi specificare un salto di -2048 o + 2046 bytes,
relativamente al valore corrente del PC (R15).
Versione architettura
Tutte le varianti T
Eccezioni
Nessuna
Operazione
PC = PC + (SignExtend(signed_immed_11) << 1)
// ‘<<’ indica lo shift aritmetico a sinistra
Uso
Per calcolare l’esatto valore di signed_immed_11, l’assembler deve:
1. Formare l’indirizzo base per il salto. Ossia l’indirizzo dell’istruzione di salto, più 4. In altre
parole, l’indirizzo base è uguale al valore del PC letto da questa istruzione.
2. Sottrarre l’indirizzo base dall’indirizzo di destinazione per formare l’offset. Questo offset è
sempre pari, perché tutte le istruzioni Thumb sono allineate a mezze parole (2 bytes).
3. Se l’offset è fuori dall’intervallo da -2048 a +2046, una strategia di generazione
dell’indirizzo alternativa oppure generare un errore appropriato.
4. Altrimenti, settare il campo signed_immed_11 dell’istruzione nel byte offset diviso 2.
67
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Note
Limiti di memoria
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
Saltare all’indietro prima dello zero o in avanti oltre la fine dello spazio
indirizzi a 32-bit porta risultati imprevedibili.
Sintassi e codifica equivalente ARM
B <target_address>
Questa istruzione è diversa dall’istruzione Thumb, perché l’offset dell’istruzione ARM viene
shiftato a sinistra di sue bit prima di essere aggiunto al PC, invece l’offset dell’istruzione Thumb
viene shiftato verso sinistra di un bit. Così il valore del PC letto dalle istruzioni ARM e Thumb sono
diversi.
68
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
6.1.15. BIC
(Bit Clear) esegue un AND bit a bit tra il valore di un registro e il valore dell’altro registro
negato.
BIC
Aggiorna i flag di stato, a seconda del risultato.
Sintassi
BIC <Rd>, <Rm>
dove:
<Rd> Specifica il registro contenente il primo operando ed è anche il registro di destinazione.
<Rm> Specifica il registro contenente il secondo operando il quale verrà negato.
Versione architettura
Tutte le varianti T
Eccezioni
Nessuna
Operazione
Rd = Rd AND NOT Rm
N Flag = Rd[31]
Z Flag = if(Rd == 0) {1} else {0}
C Flag = non interessato
V Flag = non interessato
Sintassi e codifica equivalente ARM
BICS <Rd>, <Rd>, <Rm>
69
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
6.1.16. BKPT
(Breakpoint) causa il verificarsi di un’interruzione software. Questo breakpoint può essere
gestito da un gestore delle eccezioni installato nel vettore Prefetch Abort. Nelle implementazioni
che includono anche hardware di debug, l’hardware può anche scavalcare questo comportamento
di default e gestire il breakpoint.
BKPT
Sintassi
BKPT <immed_8>
dove:
<immed_8>
È un valore immediato di 8-bit, inserito nei bit*7:0+ dell’istruzione. Questo valore è
ignorato dall’hardware ARM, ma può essere usato da un debugger per memorizzare
delle informazioni riguardo il breakpoint.
Versione architettura
Varianti T di ARMv5 e superiori.
Eccezioni
Prefetch Abort.
Operazione
if (not overridden by debug hardware)
R14_abt = address of BKPT instruction + 4
SPSR_abt = CPSR
CPSR[4:0] = 0b10111
/* Enter Abort mode */
CPSR[5] = 0
/* Execute in ARM state */
/* CPSR[6] is unchanged */
CPSR[7] = 1
/* Disable normal interrupts */
CPSR[8] = 1
/* Disable imprecise aborts - v6 only*/
CPSR[9] = CP15_reg1_EEbit
if (high vectors configured)
PC = 0xFFFF000C
else
PC = 0x0000000C
70
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
Uso
L’uso esatto di BKPT dipende dal sistema di debug usato. Un sistema di debug può usare BKPT in
due modi:

L’hardware di debug (se presente) non scavalca la normale procedura di BKPT, e così si
entra nel vettore di Prefetch Abort. Se il sistema permette anche l’avvenimento di un
Prefetch Abort reale, il gestore delle interruzioni determina (in un modo dipendente dal
sistema) se l’elemento del vettore è il risultato di un’istruzione BKPT o il risultato di un
Prefetch Abort reale, e salta di conseguenza al codice di debug o al codice di Prefetch
Abort. Diversamente, il gestore di Prefetch Abort salta direttamente al codice di debug.
Quando è usato in questo modo, BKPT deve essere evitato nei gestori delle eccezioni,
poiché cambia i valori di R14_abt e SPSR_abt. Per la stessa ragione deve essere evitato nei
gestori FIQ, poiché un’interruzione FIQ può avveneire nel gestore degli abort.

Il debug hardware scavalca la normale procedura di BKPT e gestisce il breakpoint software
da solo. Quando finisce, tipicamente riprende l’esecuzione dall’istruzione seguente a BKPT,
oppure lo rimpiazza con un’altra istruzione e riprende l’esecuzione da quest’ultima.
Quando BKPT è usato in questo modo, R14_abt e SPSR_abt non vengono cambiati, e così le
restrizioni di prima riguardo l’uso di BKPT nei gestori di abort e FIQ non vengono applicate.
Note
Scavalcamento Hardware
Il debug hardware viene appositamente permesso per scavalcare la
normale procedura di BKPT. A causa di ciò, il software non deve usare
questa istruzione se non per gli scopi permessi dal sistema di debug
che si sta usando. In particolare, il software non può dipendere dal
verificarsi dell’eccezione di Prefetch Abort, a meno che sia garantito
che non ci sia un debug hardware nel sistema e che il sistema di
debug specifica che l’eccezione avviene.
Sintassi e codifica equivalente ARM
BKPT <immed_8>
71
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
6.1.17. BL, BLX(1)
(Branch with link) fa una chiamata incondizionata ad una subroutine Thumb. Il ritorno dalla
subroutine viene effettuato dai seguenti comandi:
BL

mov PC, LR

bx LR

un’istruzione di pop che carichi il PC.
(1) (Branch with Link and Exchange) fa una chiamata incondizionata ad una subroutine ARM. Il
ritorno dalla subroutine viene effettuato tramite l’istruzione bx LR, oppure da un’istruzione ldr o
ldm che carichi il PC.
BLX
Per permettere una grandezza dell’offset ragionevole, le istruzioni bl e blx sono automaticamente
tradotte dall’assembler in una sequenza di due istruzioni Thumb 16-bit:

La prima istruzione ha H = 10 e fornisce la parte alta dell’offset del salto. Questa istruzione
prepara per la chiamata alla subroutine ed è condivisa tra bl e blx.

La seconda istruzione ha H = 11 (per bl) o H = 01 (per blx). Fornisce la parte bassa
dell’offset del salto e fa prendere posto alla chiamata alla subroutine.
Sintassi
BL <target_addr>
BLX <target_addr>
dove:
<target_addr>
Specifica l’indirizzo a cui saltare. Questo indirizzo è calcolato in questo
modo:
1. Shiftando il campo offset_11 della prima istruzione a sinistra di 12 bits.
2. Estendendo il segno del risultato a 32-bit.
3. Aggiungendolo al contenuto del PC (che contiene l’indirizzo della prima
istruzione più 4).
4. Aggiungendo due volte il campo offset_11 della seconda istruzione.
L’istruzione può quindi compiere un salto di ±4MB.
Versione architettura
BL (H == 10 e H == 11) in tutte le variant T.
BLX (H == 01 form) nelle variant T di ARMv5 e superiori.
Eccezioni
Nessuna
72
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
Operazione
if (H == 10)
LR = PC + (SignExtend(offset_11) << 12)
else if (H == 11)
PC = LR + (offset_11 << 1)
LR = (address of next instruction) | 1
else if (H == 01)
PC = (LR + (offset_11 << 1)) AND 0xFFFFFFFC
LR = (address of next instruction) | 1
CPSR T bit = 0
Uso
Per generare la giusta coppia di istruzioni, l’assembler deve prima generare l’offset del salto, come
segue:
1. Forma l’indirizzo base del salto. È l’indirizzo della prima delle due istruzioni Thumb (quella
con H = 10), più 4. In altre parole, l’indirizzo base è uguale al valore del PC letto da
quest’istruzione.
2. Se l’istruzione è BLX, si imposta il bit*1+ dell’indirizzo di destinazione uguale al bit*1+
dell’indirizzo base. È un’eccezione alla regola che i bits*1:0+ dell’indirizzo di un’istruzione
ARM sono 0b00. Questo aggiustamento è necessario per assicurare che le restrizioni
associate con la forma dell’istruzione H = 01 siano ottemperate.
3. Sottrarre l’indirizzo base dall’indirizzo di destinazione (target) per formare l’offset.
L’offset risultante è sempre pari. Se l’offset è fuori dall’intervallo:
-222 ≤ offset ≤ +222 – 2
L’indirizzo di destinazione giace al di fuori dall’intervallo di queste istruzioni. Risulta quindi un
codice alternativo o un errore.
Se l’offset si trova nell’intervallo, deve essere generata una sequenza di due istruzioni Thumb,
entrambe usanti la forma vista in precedenza:

La prima con H = 10 e offset_11 = offset[22:12]

La seconda con H = 11 (per BL) o H = 01 (per BLX) e offset_11 = offset[11:1]
Note
Codifica
Se H = 00, l’istruzione rappresenta un salto incondizionato (vedere b(2))
Bit[0] per BLX
Se H = 01, il bit*0+ dell’istruzione deve essere zero, altrimenti l’istruzione
risulta indefinita. Il metodo di calcolo dell’offset descritto sopra assicura che
l’offset calcolato per un’istruzione BLX è un multiplo di quattro, e questa
restrizione è rispettata.
Limiti memoria
Il risultato di salti al di fuori dello spazio di memoria a 32-bit è imprevedibile.
73
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
Coppie di istruzioni Queste istruzioni Thumb devono sempre verificarsi in coppia come descritto
sopra. In particolare:

Se l’istruzione Thumb all’indirizzo A è nella forma H = 10, l’istruzione
all’indirizzo A + 2 deve essere nella forma H = 01 oppure H = 11.

Se l’istruzione Thumb all’indirizzo A è nella forma H = 01 oppure H =
11, l’istruzione all’indirizzo A – 2 deve essere nella forma H = 10.
Ancora, eccetto ciò che è notificato in Eccezioni sotto, la seconda istruzione
della coppia non deve essere l’obiettivo di alcun salto, così come il risultato
di un’istruzione di salto o di altre istruzioni che cambiano il PC.
Il non attenersi a ognuna di queste restrizioni può risultare in sviluppi
imprevedibili.
Eccezioni
È definito dall’implementazione se le eccezioni del processore possono
avvenire anche tra la coppia di istruzioni di BL e BLX. Se possono, le istruzioni
ARM usate per il ritorno dall’eccezione devono essere capaci di ritornare
correttamente alla seconda istruzione della coppia. Quindi, i gestori delle
eccezioni non devono prendere particolari precauzioni riguardo il ritorno alla
seconda istruzione di una coppia BL o BLX.
Sintassi e codifica equivalente ARM
Le istruzioni più simili a queste istruzioni Thumb sono le seguenti.
Per chiamare una subroutine Thumb:
BLX <target_addr>
dove L = offset[1]
Per chiamare una routine ARM:
BL <target_addr>
Differiscono leggermente dalle coppie di istruzioni Thumb a causa dei differenti valori del Pc nei
codici ARM e Thumb. Può essere compensato aggiustando l’offset di 4.
74
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
6.1.18. BLX(2)
(2) chiama una subroutine ARM o Thumb dal set istruzino Thumb, a un indirizzo specificato in
un registro. L’istruzione fa il salto e seleziona il decoder da usare per decodificare le istruzioni alla
destinazione del salto.
BLX
Il bit T del CPSR viene aggiornato con il bit[0] del valore del registro Rm. Per ritornare dalla
subroutine al chiamante si usa BX R14.
Sintassi
BLX <Rm>
dove:
<Rm>
Specifica il registro contenente l’indirizzo a cui saltare. Può essere uno qualsiasi tra
R0 e R14. Il numero del registro è codificato nell’istruzione in H2 (bit più
significativo) e in Rm (i rimanenti tre bit). Se viene specificato R15 come Rm il
risultato è imprevedibile.
Versione architettura
Varianti T di ARMv5 e superiori.
Eccezioni
Nessuna
Operazione
target = Rm
LR = (address of the instruction after this BLX) | 1
CPSR T bit = target[0]
PC = target AND 0xFFFFFFFE
Sintassi e codifica equivalente ARM
BLX <Rm>
75
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
6.1.19. BX
BX (Branch and Exchange) salta tra il codice ARM e il codice Thumb.
Sintassi
BX <Rm>
dove:
<Rm>
Specifica il registro contenente l’indirizzo a cui saltare. Può essere uno qualsiasi tra
R0 e R14. Il numero del registro è codificato nell’istruzione in H2 (bit più
significativo) e in Rm (i rimanenti tre bit).
Versione architettura
Tutte le varianti T.
Eccezioni
Nessuna
Operazione
CPSR T bit = Rm[0]
PC = Rm[31:1] << 1
Uso
L’istruzione normale di ritorno dalla subroutine in Thumb è bx R14. Le seguenti istruzioni di
chiamata lasciano un valore di ritorno appropriato in R14:


Le istruzioni blx di ARM.
Le istruzioni bl e blx di Thumb.
Nelle varianti T di ARMv4, una chiamata ad una routine ARM può essere fatta dal seguente codice:
<Put address of routine to call in Ra>
MOV LR, PC
;
Return to second following instruction
BX Ra
Nelle varianti T di ARMv5 e superiori, la chiamata può essere fatta in modo più efficiente con
l’istruzione BLX.
76
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
Sintassi e codifica equivalente ARM
BX <Rm>
77
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
6.1.20. CMN
(Compare Negative) compara il valore di un registro con la negazione del valore di un altro
registro. Aggiorna i flag di stato, a seconda del risultato della somma dei valori dei due registri, così
che le istruzioni seguenti possano essere eseguite a seconda della condizione (usando un salto
condizionato).
CMN
Sintassi
CMN <Rn>, <Rm>
dove:
<Rn> Specifica il registro contenente il primo valore da comparare.
<Rm> Specifica il registro contenente il secondo valore da comparare.
Versione architettura
Tutte le varianti T
Eccezioni
Nessuna
Operazione
alu_out = Rn + Rm
N Flag = alu_out[31]
Z Flag = if (alu_out == 0) {1} else {0}
C Flag = CarryFrom(Rn + Rm)
V Flag = OverflowFrom(Rn + Rm)
Sintassi e codifica equivalente ARM
CMN <Rn>, <Rm>
78
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
6.1.21. CMP(1)
CMP(1)
(Compare) compara il valore di un registro con un valore immediato di 8-bit. I flag di stato
vengono aggiornati, in base al risultato della sottrazione del valore immed_8 dal valore del
registro, così che le istruzioni seguenti possano essere eseguite a seconda della condizione
(usando un salto condizionato).
Sintassi
CMP <Rn>, #<immmed_8>
dove:
<Rn> Specifica il registro contenente il primo valore da comparare.
<immed_8>
Specifica il secondo valore da comparare.
Versione architettura
Tutte le varianti T
Eccezioni
Nessuna
Operazione
alu_out = Rn - immed_8
N Flag = alu_out[31]
Z Flag = if (alu_out == 0) {1} else {0}
C Flag = NOT BorrowFrom(Rn - immed_8)
V Flag = OverflowFrom(Rn - immed_8)
Sintassi e codifica equivalente ARM
CMP <Rn>, #<immed_8>
79
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
6.1.22. CMP(2)
CMP(2)
compara i valori di due registri. I flag di stato vengono aggiornati, in base al risultato della
sottrazione del valore del secondo registro dal valore del primo, così che le istruzioni seguenti
possano essere eseguite a seconda della condizione (usando un salto condizionato).
Sintassi
CMP <Rn>, <Rm>
dove:
<Rn> Specifica il registro contenente il primo valore da comparare.
<Rm> Specifica il registro contenente il secondo valore da comparare.
Versione architettura
Tutte le varianti T
Eccezioni
Nessuna
Operazione
alu_out = Rn - Rm
N Flag = alu_out[31]
Z Flag = if (alu_out == 0) {1} else {0}
C Flag = NOT BorrowFrom(Rn - Rm)
V Flag = OverflowFrom(Rn - Rm)
Sintassi e codifica equivalente ARM
CMP <Rn>, <Rm>
80
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
6.1.23. CMP(3)
CMP(3)
compara i valori di due registri, uno dei quali o entrambi sono registri alti. I flags di stato
vengono aggiornati, in base al risultato della sottrazione del valore del secondo registro dal valore
del primo, così che le istruzioni seguenti possano essere eseguite a seconda della condizione
(usando un salto condizionato).
Sintassi
CMP <Rn>, <Rm>
dove:
<Rn>
Specifica il registro contenente il primo valore da comparare. Può essere uno
qualsiasi tra R0 e R14. Il numero del registro è dato da H1 (bit più significativo) e Rn
(i restanti tre bit).
<Rm>
Specifica il registro contenente il secondo valore da comparare. Può essere uno
qualsiasi tra R0 e R14. Il numero del registro è dato da H2 (bit più significativo) e Rm
(i restanti tre bit).
Versione architettura
Tutte le varianti T
Eccezioni
Nessuna
Operazione
alu_out = Rn - Rm
N Flag = alu_out[31]
Z Flag = if (alu_out == 0) {1} else {0}
C Flag = NOT BorrowFrom(Rn - Rm)
V Flag = OverflowFrom(Rn - Rm)
Note
Restrizione operandi
Se viene specificato un registro basso per entrambi gli operandi il
risultato è imprevedibile.
81
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
Sintassi e codifica equivalente ARM
Un equivalente simile è:
CMP
<Rn>, <Rm>
Ci sono leggere differenze quando le istruzioni accedono al PC, a causa delle differenti definizioni
di PC nell’esecuzione di codice ARM e Thumb.
82
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
6.1.24. CPS
(Change Processor State) cambia uno o più dei bit A, I, e F del CPSR, senza cambiare altri bit del
CPSR.
CPS
Sintassi
CPS <effect>, <iflags>
dove:
<effect>
<iflags>
Specifica quale effetto si vuole sui bit di disabilitazione dell’interrupt A, I, e F del
CPSR. Possono essere:
IE
Interrupt Enable, codificato da imod = 0b0. Setta il bit specificato a zero.
ID
Interrupt Disable, codificato da imod = 0b1. Setta il bit specificato a 1.
È una sequenza di uno o più dei seguenti flags, che specificano quali bit di
disabilitazione dell’interrupt sono modificati:
A
Imposta il bit A (bit[2])
I
Imposta il bit I (bit[1])
F
Imposta il bit F (bit[0])
Versione architettura
ARMv6 e superiori
Eccezioni
Nessuna
Operazione
if (InAPrivilegedMode())
if A == 1 then CPSR[8] = imod
if I == 1 then CPSR[7] = imod
if F == 1 then CPSR[6] = imod
/* else no change to interrupt disable bits */
Note
User mode
Questa istruzione non ha effetti in modalità utente.
83
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Sintassi e codifica equivalente ARM
cps <effect>, <iflags>
84
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
6.1.25. CPY
(Copy) copia un valore da un registro alto o basso ad un altro registro alto o basso senza
cambiare i flags di stato.
CPY
Sintassi
CPY <Rd>, <Rm>
dove:
<Rd> Specifica il registro di destinazione. Può essere uno qualsiasi tra R0 e R15. Il numero del
registro è dato da H1 (bit più significativo) e Rn (i restanti tre bit).
<Rm> Specifica il registro contenente il valore da copiare. Può essere uno qualsiasi tra R0 e R15. Il
numero del registro è dato da H2 (bit più significativo) e Rm (i restanti tre bit).
Versione architettura
Varianti T di ARMv6 e superiori.
Eccezioni
Nessuna
Operazione
Rd = Rm
Uso
CPY PC, R14 può essere usata come istruzione di ritorno da una subroutine se il chiamante è
anch’essa una routine Thumb. Comunque, è più comune usare bx R14, che funzione sia che il
chiamante fosse una routine ARM sia che fosse una routine Thumb.
Note
Codifica
ha la stessa funzionalità di mov(3), e usa la stessa codifica di istruzione, ma ha
una sintassi assembler che permette a entrambi gli operandi di essere registri bassi.
CPY
Sintassi e codifica equivalente ARM
Un equivalente simile è:
85
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
CPY
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
<Rd>, <Rm>
Ci sono leggere differenze quando le istruzioni accedono al PC, a causa delle differenti definizioni
di PC nell’esecuzione di codice ARM e Thumb.
86
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
6.1.26. EOR
EOR (Exclusive Or) esegue un or esclusivo bit a bit tra i valori dei due registri.
Aggiorna i flag di stato, a seconda del risultato.
Sintassi
EOR
<Rd>, <Rm>
dove:
<Rd> Specifica il registro contenente il primo operando ed è anche il registro di destinazione.
<Rm> Specifica il registro contenente il secondo operando.
Versione architettura
Tutte le varianti T
Eccezioni
Nessuna
Operazione
Rd = Rd EOR Rm
N Flag = Rd[31]
Z Flag = if (Rd == 0) {1} else {0}
C Flag = unaffected
V Flag = unaffected
Sintassi e codifica equivalente ARM
EOR
<Rd>, <Rd>, <Rm>
87
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
6.1.27. LDMIA
(Load Multiple Increment After) carica un sottoinsieme non vuoto, oppure tutti, i registry
generic (R0-R7) da locazioni di memoria sequenziali.
LDMIA
Sintassi
LDMIA <Rn>!, <registers>
dove:
<Rn>
Specifica il registro contenente l’indirizzo di inizio per l’istruzione.
!
Causa la riscrittura del registro base, e non è opzionale.
<registers>
È la lista dei registri da caricare, separati da una virgola e racchiusi tra parentesi
graffe. La lista è codificata nel campo register_list dell’istruzione, settando il bit*i+ a
1 se il registro Ri è incluso nella lista, a zero altrimenti per ogni i da 0 a 7.
Almeno un registro deve essere caricato. Se tutti i bit[7:0] sono a zero il risultato è
imprevedibile.
I registri vengono caricati in sequenza, dal registro col numero più basso a cui
corrisponde l’indirizzo più piccolo in memoria (l’indirizzo iniziale), fino al registro col
numero più alto a cui corrisponde l’indirizzo più grande in memoria (l’indirizzo
finale).
L’indirizzo iniziale è il valore del registro base Rn. Gli indirizzi succesivi sono formati
incrementando l’indirizzo precedente di 4. Viene prodotto un indirizzo per ogni
registro specificato in register_list.
L’indirizzo finale è formato da: registro_base + 4 * (numero_registri_specificati – 1).
Infine, quando Rn non fa parte dei registri specificati in register_list, il suo valore è
incrementato di quattro volte i registri specificati in register_list. Vedere le
restrizioni sull’operando.
Versione architettura
Tutte le varianti T
Eccezioni
Data Abort
88
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
Operazione
MemoryAccess(B-bit, E-bit)
start_address = Rn
end_address = Rn + (Number_Of_Set_Bits_In(register_list) * 4) - 4
address = start_address
for i = 0 to 7
if (register_list[i] == 1)
Ri = Memory[address,4]
address = address + 4
assert end_address == address - 4
Rn = Rn + (Number_Of_Set_Bits_In(register_list) * 4)
Uso
Usare LDMIA come istruzione per caricare blocchi dalla memoria. In combinazione con stmia
permette un’efficiente gestione della copia di blocchi di memoria.
Note
Restrizione operandi
Se Rn è specificato nella register_list, il valore finale di Rn è quello caricato da
memoria e non quello riscritto come mostrato prima.
Data Abort
Per i dettagli sugli effetti dell’istruzione se avviene un Data Abort controllare la
sezione Effetti delle istruzioni che hanno provocato un Data-Abort.
Allineamento Se un implementazione include un sistema di controllo coprocessore e il controllo
dell’allineamento è abilitato, un indirizzo con i bit*1:0+ != 0b00 causa un’eccezione
di allineamento.
L’opzione di controllo dell’allineamento viene supportata dall’ARMv6 in poi:
Time order

Se CP15_reg1_Abit == 1, un accesso non allineato causa un Data-Abort.

Se CP15_reg1_Abit == 0:
-
e CP15_reg1_Ubit == 0, l’istruzione ignora i due bit meno significativi
dell’indirizzo;
-
e CP15_reg1_Ubit == 1, un accesso non allineato causa un Data-Abort.
L’ordine cronologico di accesso alle parole individuali della memoria generato da
questa istruzione è definito solo in alcune circostanze. Vedere Restrizioni di accesso
alla memoria per maggiori dettagli.
89
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Sintassi e codifica equivalente ARM
Se Rn non è nel register_list (W = 1):
LDMIA
<Rn>!, <registers>
Se Rn è nel register_list (W = 0):
LDMIA <Rn>, <registers>
90
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
6.1.28. LDR(1)
LDR(1)
(Load Register) permette di caricare un dato di 32-bit dalla memoria in un registro. Il modo
di indirizzamento è utile per accedere a strutture (record). Con un offset di zero l’indirizzo
prodotto è l’inalterato valore del registro base Rn.
Sintassi
LDR <Rd>, [<Rn>, #<immed_5> * 4]
dove:
<Rd> È il registro di destinazione della parola caricata dalla memoria.
<Rn> È il registro contenente l’indirizzo base dell’istruzione.
<immed_5> È un valore di 5-bit che viene moltiplicato per 4 e aggiunto ad Rn per formare
l’indirizzo di memoria.
Versione architettura
Tutte le varianti T
Eccezioni
Data Abort
Operazione
MemoryAccess(B-bit, E-bit)
address = Rn + (immed_5 * 4)
if (CP15_reg1_Ubit == 0)
if (address[1:0] == 0b00)
data = Memory[address,4]
else
data = UNPREDICTABLE
else /* CP15_reg1_Ubit == 1 */
data = Memory[address,4]
Rd = data
91
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Note
Data Abort
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
Per i dettagli sugli effetti dell’istruzione se avviene un Data Abort controllare la
sezione Effetti delle istruzioni che hanno provocato un Data-Abort.
Allineamento Prima di ARMv6, se l’indirizzo di memoria non era allineato alla parola, i dati letti
dalla memoria erano casuali. Il controllo di allineamento (si verifica un Data-Abort
quando i bit*1:0+ dell’indirizzo sono diversi da 0b00), e il supporto per dati più
grandi di 32-bit erano opzioni delle implementazioni.
L’opzione di controllo dell’allineamento viene supportata dall’ARMv6 in poi:

Se CP15_reg1_Abit == 1, un accesso non allineato causa un Data-Abort.

Se CP15_reg1_Abit == 0:
-
e CP15_reg1_Ubit == 0, l’istruzione ignora i due bit meno significativi
dell’indirizzo;
-
e CP15_reg1_Ubit == 1, un accesso non allineato causa un Data-Abort.
Sintassi e codifica equivalente ARM
LDR <Rd>, [<Rn>, #<immed_5> * 4]
92
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
6.1.29. LDR(2)
LDR(2)
permette di caricare un dato di 32-bit dalla memoria in un registro. Il modo di
indirizzamento è utile per puntatori + offset e per accedere ad un elemento di un vettore.
Sintassi
LDR <Rd>, [<Rn>, <Rm>]
dove:
<Rd> È il registro di destinazione della parola caricata dalla memoria.
<Rn> È il registro contenente il primo valore usato per formare l’indirizzo.
<Rm> È il registro contenente il secondo valore usato per formare l’indirizzo.
Versione architettura
Tutte le varianti T
Eccezioni
Data Abort
Operazione
MemoryAccess(B-bit, E-bit)
address = Rn + Rm
if (CP15_reg1_Ubit == 0)
if (address[1:0] == 0b00)
data = Memory[address,4]
else
data = UNPREDICTABLE
else /* CP15_reg1_Ubit == 1 */
data = Memory[address,4]
Rd = data
93
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Note
Data Abort
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
Per i dettagli sugli effetti dell’istruzione se avviene un Data Abort controllare la
sezione Effetti delle istruzioni che hanno provocato un Data-Abort.
Allineamento Prima di ARMv6, se l’indirizzo di memoria non era allineato alla parola, i dati letti
dalla memoria erano casuali. Il controllo di allineamento (si verifica un Data-Abort
quando i bit*1:0+ dell’indirizzo sono diversi da 0b00), e il supporto per dati più
grandi di 32-bit erano opzioni delle implementazioni.
L’opzione di controllo dell’allineamento viene supportata dall’ARMv6 in poi:

Se CP15_reg1_Abit == 1, un accesso non allineato causa un Data-Abort.

Se CP15_reg1_Abit == 0:
-
e CP15_reg1_Ubit == 0, l’istruzione ignora i due bit meno significativi
dell’indirizzo;
-
e CP15_reg1_Ubit == 1, un accesso non allineato causa un Data-Abort.
Sintassi e codifica equivalente ARM
LDR <Rd>, [<Rn>, <Rm>]
94
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
6.1.30. LDR(3)
LDR(3)
permette di caricare un dato di 32-bit dalla memoria in un registro. Il modo di
indirizzamento è utile per accedere alla memoria partendo dall’indirizzo contenuto nel PC.
Sintassi
LDR <Rd>, [PC, #<immed_8> * 4]
dove:
<Rd>
È il registro di destinazione della parola caricata dalla memoria.
PC
È il Program Counter. Il suo valore è usato per calcolare l’indirizzo di memoria. Il bit
1 viene forzato a 0 in modo che l’indirizzo sia allineato.
<immed_8>
È un valore di 8-bit che moltiplicato per 4 e aggiunto al valore del PC forma
l’indirizzo di memoria.
Versione architettura
Tutte le varianti T
Eccezioni
Data Abort
Operazione
MemoryAccess(B-bit, E-bit)
address = (PC & 0xFFFFFFFC) + (immed_8 * 4)
Rd = Memory[address, 4]
Note
Data Abort
Per i dettagli sugli effetti dell’istruzione se avviene un Data Abort controllare la
sezione Effetti delle istruzioni che hanno provocato un Data-Abort.
Allineamento Prima di ARMv6, se l’indirizzo di memoria non era allineato alla parola, i dati letti
dalla memoria erano casuali. Il controllo di allineamento (si verifica un Data-Abort
quando i bit*1:0+ dell’indirizzo sono diversi da 0b00), e il supporto per dati più
grandi di 32-bit erano opzioni delle implementazioni.
L’opzione di controllo dell’allineamento viene supportata dall’ARMv6 in poi:

Se CP15_reg1_Abit == 1, un accesso non allineato causa un Data-Abort.

Se CP15_reg1_Abit == 0:
-
e CP15_reg1_Ubit == 0, l’istruzione ignora i due bit meno significativi
dell’indirizzo;
95
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
-
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
e CP15_reg1_Ubit == 1, un accesso non allineato causa un Data-Abort.
Sintassi e codifica equivalente ARM
Un equivalente simile è:
LDR
<Rd>, [PC, #<immed_8> * 4]
Ci sono leggere differenze quando le istruzioni accedono al PC, a causa delle differenti definizioni
di PC nell’esecuzione di codice ARM e Thumb.
96
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
6.1.31. LDR(4)
LDR(4)
permette di caricare un dato di 32-bit dalla memoria in un registro. Il modo di
indirizzamento è utile per accedere allo stack.
Sintassi
LDR <Rd>, [SP, #<immed_8> * 4]
dove:
<Rd>
È il registro di destinazione della parola caricata dalla memoria.
SP
È lo Stack Pointer. Il suo valore è usato per calcolare l’indirizzo di memoria.
<immed_8>
È un valore di 8-bit che moltiplicato per 4 e aggiunto al valore dello SP forma
l’indirizzo di memoria.
Versione architettura
Tutte le varianti T
Eccezioni
Data Abort
Operazione
MemoryAccess(B-bit, E-bit)
address = SP + (immed_8 * 4)
if (CP15_reg1_Ubit == 0)
if (address[1:0] == 0b00)
data = Memory[address,4]
else
data = UNPREDICTABLE
else /* CP15_reg1_Ubit == 1 */
data = Memory[address,4]
Rd = data
97
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Note
Data Abort
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
Per i dettagli sugli effetti dell’istruzione se avviene un Data Abort controllare la
sezione Effetti delle istruzioni che hanno provocato un Data-Abort.
Allineamento Prima di ARMv6, se l’indirizzo di memoria non era allineato alla parola, i dati letti
dalla memoria erano casuali. Il controllo di allineamento (si verifica un Data-Abort
quando i bit*1:0+ dell’indirizzo sono diversi da 0b00), e il supporto per dati più
grandi di 32-bit erano opzioni delle implementazioni.
L’opzione di controllo dell’allineamento viene supportata dall’ARMv6 in poi:

Se CP15_reg1_Abit == 1, un accesso non allineato causa un Data-Abort.

Se CP15_reg1_Abit == 0:
-
e CP15_reg1_Ubit == 0, l’istruzione ignora i due bit meno significativi
dell’indirizzo;
-
e CP15_reg1_Ubit == 1, un accesso non allineato causa un Data-Abort.
Sintassi e codifica equivalente ARM
LDR <Rd>, [SP, #<immed_8> * 4]
98
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
6.1.32. LDRB(1)
LDRB(1)
(Load Register Byte) carica un byte da memoria, estende il dato con degli zeri per portarlo
alla dimensione di 32-bit, e scrive il risultato in un registro generico. Il modo di indirizzamento è
utile per accedere a strutture o record. Con un offset pari a zero, l’indirizzo prodotto è il valore
inalterato dell’indirizzo base Rn.
Sintassi
LDRB <Rd>, [<Rn>, #<immed_5>]
dove:
<Rd>
È il registro di destinazione del byte caricato dalla memoria.
<Rn>
È il registro contenente l’indirizzo base per l’istruzione.
<immed_5>
È un valore di 5-bit che viene aggiunto al valore di Rn per formare l’indirizzo di
memoria.
Versione architettura
Tutte le varianti T
Eccezioni
Data Abort
Operazione
address = Rn + immed_5
Rd = Memory[address,1]
Note
Data Abort
Per i dettagli sugli effetti dell’istruzione se avviene un Data Abort controllare la
sezione Effetti delle istruzioni che hanno provocato un Data-Abort.
Sintassi e codifica equivalente ARM
LDRB <Rd>, [<Rn>, #<immed_5>]
99
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
6.1.33. LDRB(2)
LDRB(2)
carica un byte da memoria, estende il dato con degli zeri per portarlo alla dimensione di
32-bit, e scrive il risultato in un registro generico. Il modo di indirizzamento è utile per puntatori +
offset e per accedere ad un elemento di un vettore.
Sintassi
LDRB <Rd>, [<Rn>, <Rm>]
dove:
<Rd> È il registro di destinazione del byte caricato dalla memoria.
<Rn> È il registro contenente il primo valore usato per formare l’indirizzo.
<Rm> È il registro contenente il secondo valore usato per formare l’indirizzo.
Versione architettura
Tutte le varianti T
Eccezioni
Data Abort
Operazione
address = Rn + Rm
Rd = Memory[address,1]
Note
Data Abort
Per i dettagli sugli effetti dell’istruzione se avviene un Data Abort controllare la
sezione Effetti delle istruzioni che hanno provocato un Data-Abort.
Sintassi e codifica equivalente ARM
LDRB <Rd>, [<Rn>, <Rm>]
100
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
6.1.34. LDRH(1)
LDRH(1) (Load Register Halfword) carica mezza parola (16-bit) da memoria, estende il dato con degli
zeri per portarlo alla dimensione di 32-bit, e scrive il risultato in un registro generico. Il modo di
indirizzamento è utile per accedere a strutture o record. Con un offset pari a zero, l’indirizzo
prodotto è il valore inalterato dell’indirizzo base Rn.
Sintassi
LDRH <Rd>, [<Rn>, #<immed_5> * 2]
dove:
<Rd>
È il registro di destinazione della mezza parola caricata dalla memoria.
<Rn>
È il registro contenente l’indirizzo base per l’istruzione.
<immed_5>
È un valore di 5-bit che moltiplicato per 2 viene aggiunto al valore di Rn per formare
l’indirizzo di memoria.
Versione architettura
Tutte le varianti T
Eccezioni
Data Abort
Operazione
MemoryAccess(B-bit, E-bit)
address = Rn + (immed_5 * 2)
if (CP15_reg1_Ubit == 0)
if (address[0] == 0b0)
data = Memory[address,2]
else
data = UNPREDICTABLE
else /* CP15_reg1_Ubit == 1 */
data = Memory[address,2]
Rd = ZeroExtend(data[15:0])
101
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Note
Data Abort
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
Per i dettagli sugli effetti dell’istruzione se avviene un Data Abort controllare la
sezione Effetti delle istruzioni che hanno provocato un Data-Abort.
Allineamento Prima di ARMv6, se l’indirizzo di memoria non era allineato alla parola, i dati letti
dalla memoria erano casuali. Il controllo di allineamento (si verifica un Data-Abort
quando i bit*1:0+ dell’indirizzo sono diversi da 0b00), e il supporto per dati più
grandi di 32-bit erano opzioni delle implementazioni.
L’opzione di controllo dell’allineamento viene supportata dall’ARMv6 in poi:

Se CP15_reg1_Abit == 1, un accesso non allineato causa un Data-Abort.

Se CP15_reg1_Abit == 0:
-
e CP15_reg1_Ubit == 0, l’istruzione ignora i due bit meno significativi
dell’indirizzo;
-
e CP15_reg1_Ubit == 1, un accesso non allineato causa un Data-Abort.
Sintassi e codifica equivalente ARM
LDRH <Rd>, [<Rn>, #<immed_5> * 2]
102
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
6.1.35. LDRH(2)
LDRH(2)
carica mezza parola (16-bit) da memoria, estende il dato con degli zeri per portarlo alla
dimensione di 32-bit, e scrive il risultato in un registro generico. Il modo di indirizzamento è utile
per puntatori + offset e per accedere ad un elemento di un vettore.
Sintassi
LDRH <Rd>, [<Rn>, <Rm>]
dove:
<Rd> È il registro di destinazione della mezza parola caricata dalla memoria.
<Rn> È il registro contenente il primo valore usato per formare l’indirizzo.
<Rm> È il registro contenente il secondo valore usato per formare l’indirizzo.
Versione architettura
Tutte le varianti T
Eccezioni
Data Abort
Operazione
MemoryAccess(B-bit, E-bit)
address = Rn + Rm
if (CP15_reg1_Ubit == 0)
if (address[0] == 0b0)
data = Memory[address,2]
else
data = UNPREDICTABLE
else /* CP15_reg1_Ubit == 1 */
data = Memory[address,2]
Rd = ZeroExtend(data[15:0])
103
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Note
Data Abort
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
Per i dettagli sugli effetti dell’istruzione se avviene un Data Abort controllare la
sezione Effetti delle istruzioni che hanno provocato un Data-Abort.
Allineamento Prima di ARMv6, se l’indirizzo di memoria non era allineato alla parola, i dati letti
dalla memoria erano casuali. Il controllo di allineamento (si verifica un Data-Abort
quando i bit*1:0+ dell’indirizzo sono diversi da 0b00), e il supporto per dati più
grandi di 32-bit erano opzioni delle implementazioni.
L’opzione di controllo dell’allineamento viene supportata dall’ARMv6 in poi:

Se CP15_reg1_Abit == 1, un accesso non allineato causa un Data-Abort.

Se CP15_reg1_Abit == 0:
-
e CP15_reg1_Ubit == 0, l’istruzione ignora i due bit meno significativi
dell’indirizzo;
-
e CP15_reg1_Ubit == 1, un accesso non allineato causa un Data-Abort.
Sintassi e codifica equivalente ARM
LDRH <Rd>, [<Rn>, <Rm>]
104
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
6.1.36. LDRSB
(Load Register Signed Byte) carica un byte da memoria, fa un’estensione di segno fino a 32bit, e scrive il risultato in un registro generico.
LDRSB
Sintassi
LDRSB <Rd>, [<Rn>, <Rm>]
dove:
<Rd> È il registro di destinazione del byte caricato dalla memoria.
<Rn> È il registro contenente il primo valore usato per formare l’indirizzo.
<Rm> È il registro contenente il secondo valore usato per formare l’indirizzo.
Versione architettura
Tutte le varianti T
Eccezioni
Data Abort
Operazione
address = Rn + Rm
Rd = SignExtend(Memory[address,1])
Note
Data Abort
Per i dettagli sugli effetti dell’istruzione se avviene un Data Abort controllare la
sezione Effetti delle istruzioni che hanno provocato un Data-Abort.
Sintassi e codifica equivalente ARM
LDRSB <Rd>, [<Rn>, <Rm>]
105
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
6.1.37. LDRSH
LDRSH (Load Register Signed Halfword) carica mezza parola (16-bit) da memoria, fa un’estensione di
segno fino a 32-bit, e scrive il risultato in un registro generico.
Sintassi
LDRSB <Rd>, [<Rn>, <Rm>]
dove:
<Rd> È il registro di destinazione della mezza parola caricata dalla memoria.
<Rn> È il registro contenente il primo valore usato per formare l’indirizzo.
<Rm> È il registro contenente il secondo valore usato per formare l’indirizzo.
Versione architettura
Tutte le varianti T
Eccezioni
Data Abort
Operazione
MemoryAccess(B-bit, E-bit)
address = Rn + Rm
if (CP15_reg1_Ubit == 0)
if (address[0] == 0b0)
data = Memory[address,2]
else
data = UNPREDICTABLE
else /* CP15_reg1_Ubit == 1 */
data = Memory[address,2]
Rd = SignExtend(data[15:0])
106
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Note
Data Abort
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
Per i dettagli sugli effetti dell’istruzione se avviene un Data Abort controllare la
sezione Effetti delle istruzioni che hanno provocato un Data-Abort.
Allineamento Prima di ARMv6, se l’indirizzo di memoria non era allineato alla parola, i dati letti
dalla memoria erano casuali. Il controllo di allineamento (si verifica un Data-Abort
quando i bit*1:0+ dell’indirizzo sono diversi da 0b00), e il supporto per dati più
grandi di 32-bit erano opzioni delle implementazioni.
L’opzione di controllo dell’allineamento viene supportata dall’ARMv6 in poi:

Se CP15_reg1_Abit == 1, un accesso non allineato causa un Data-Abort.

Se CP15_reg1_Abit == 0:
-
e CP15_reg1_Ubit == 0, l’istruzione ignora i due bit meno significativi
dell’indirizzo;
-
e CP15_reg1_Ubit == 1, un accesso non allineato causa un Data-Abort.
Sintassi e codifica equivalente ARM
LDRSH <Rd>, [<Rn>, <Rm>]
107
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
6.1.38. LSL(1)
LSL(1)
(Logical Shift Left) fornisce il valore di un registro moltiplicato per una costante potenza di
due. Inserisce degli zeri nelle posizioni liberate dai bit shiftati, e aggiorna i flags di stato, a seconda
del risultato.
Sintassi
LSL <Rd>, <Rn>, #<immed_5>
dove:
<Rd>
È il registro di destinazione dell’operazione.
<Rn>
È il registro contenente il valore da shiftare.
<immed_5>
Specifica il numero dello shift da 0 a 31.
Versione architettura
Tutte le varianti T
Eccezioni
Nessuna
Operazione
if immed_5 == 0
C Flag = unaffected
Rd = Rm
else /* immed_5 > 0 */
C Flag = Rm[32 - immed_5]
Rd = Rm Logical_Shift_Left immed_5
N Flag = Rd[31]
Z Flag = if Rd == 0 then 1 else 0
V Flag = unaffected
Sintassi e codifica equivalente ARM
MOVS <Rd>, <Rn>, lsl #<immed_5>
108
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
6.1.39. LSL(2)
LSL(2)
fornisce il valore di un registro moltiplicato per una variabile potenza di due. Inserisce degli
zeri nelle posizioni liberate dai bit shiftati, e aggiorna i flags di stato, a seconda del risultato.
Sintassi
LSL <Rd>, <Rs>
dove:
<Rd> Contiene il valore da shiftare ed è il registro di destinazione dell’operazione.
<Rs>
È il registro contenente il valore di shift. Il valore è memorizzato nel byte meno
significativo.
Versione architettura
Tutte le varianti T
Eccezioni
Nessuna
Operazione
if Rs[7:0] == 0
C Flag = unaffected
Rd = unaffected
else if Rs[7:0] < 32 then
C Flag = Rd[32 - Rs[7:0]]
Rd = Rd Logical_Shift_Left Rs[7:0]
else if Rs[7:0] == 32 then
C Flag = Rd[0]
Rd = 0
else /* Rs[7:0] > 32 */
C Flag = 0
Rd = 0
N Flag = Rd[31]
Z Flag = if Rd == 0 then 1 else 0
V Flag = unaffected
109
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Sintassi e codifica equivalente ARM
MOVS <Rd>, <Rd>, lsl #<Rs>
110
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
6.1.40. LSR(1)
LSR(1)
(Logical Shift Right) fornisce il valore senza segno di un registro diviso per una costante
potenza di due. Inserisce degli zeri nelle posizioni liberate dai bit shiftati, e aggiorna i flags di stato,
a seconda del risultato.
Sintassi
LSR <Rd>, <Rn>, #<immed_5>
dove:
<Rd>
È il registro di destinazione dell’operazione.
<Rn>
È il registro contenente il valore da shiftare.
<immed_5>
Specifica il numero dello shift da 1 a 32. Lo shift di 32 è indicato con immed_5 = 0.
Versione architettura
Tutte le varianti T
Eccezioni
Nessuna
Operazione
if immed_5 == 0
C Flag = Rm[31]
Rd = 0
else /* immed_5 > 0 */
C Flag = Rm[immed_5 - 1]
Rd = Rm Logical_Shift_Right immed_5
N Flag = Rd[31] /* 0b0 */
Z Flag = if Rd == 0 then 1 else 0
V Flag = unaffected
Sintassi e codifica equivalente ARM
MOVS <Rd>, <Rn>, lsr #<immed_5>
111
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
6.1.41. LSR(2)
LSR(2)
fornisce il valore senza segno di un registro diviso per una variabile potenza di due. Inserisce
degli zeri nelle posizioni liberate dai bit shiftati, e aggiorna i flags di stato, a seconda del risultato.
Sintassi
LSR <Rd>, <Rs>
dove:
<Rd> Contiene il valore da shiftare ed è il registro di destinazione dell’operazione.
<Rs>
È il registro contenente il valore di shift. Il valore è memorizzato nel byte meno
significativo.
Versione architettura
Tutte le varianti T
Eccezioni
Nessuna
Operazione
if Rs[7:0] == 0 then
C Flag = unaffected
Rd = unaffected
else if Rs[7:0] < 32 then
C Flag = Rd[Rs[7:0] - 1]
Rd = Rd Logical_Shift_Right Rs[7:0]
else if Rs[7:0] == 32 then
C Flag = Rd[31]
Rd = 0
else /* Rs[7:0] > 32 */
C Flag = 0
Rd = 0
N Flag = Rd[31]
Z Flag = if Rd == 0 then 1 else 0
V Flag = unaffected
112
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
Sintassi e codifica equivalente ARM
MOVS <Rd>, <Rn>, lsr <Rs>
113
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
6.1.42. MOV(1)
MOV(1) (Move) sposta un grande valore immediato in un registro.
Aggiorna i flags di stato in base al risultato.
Sintassi
MOV <Rd>, #<immed_8>
dove:
<Rd>
È il registro di destinazione dell’operazione.
<immed_8>
Valore immediato di 8-bit nell’intervallo 0-255 che viene scritto in Rd.
Versione architettura
Tutte le varianti T
Eccezioni
Nessuna
Operazione
Rd = immed_8
N Flag = Rd[31]
Z Flag = if Rd == 0 then 1 else 0
C Flag = unaffected
V Flag = unaffected
Sintassi e codifica equivalente ARM
MOVS <Rd>, #<immed_8>
114
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
6.1.43. MOV(2)
MOV(2) sposta un valore da un registro basso ad un altro.
Aggiorna i flags di stato in base al risultato.
Sintassi
MOV <Rd>, <Rn>
dove:
<Rd> È il registro di destinazione dell’operazione.
<Rn> Registro che contiene il valore da copiare.
Versione architettura
Tutte le varianti T
Eccezioni
Nessuna
Operazione
Rd = Rn
N Flag = Rd[31]
Z Flag = if Rd == 0 then 1 else 0
C Flag = 0
V Flag = 0
Note
Codifica
Questa istruzione è codificata come ADD Rd, Rn, #0.
Sintassi e codifica equivalente ARM
ADDS <Rd>, <Rn>, #0
115
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
6.1.44. MOV(3)
MOV(3) sposta un valore da un registro alto ad un altro.
Diversamente da MOV(2) questa istruzione non aggiorna i flags di stato.
Sintassi
MOV <Rd>, <Rm>
dove:
<Rd> Specifica il registro di destinazione. Può essere uno qualsiasi tra R0 e R15. Il numero del
registro è dato da H1 (bit più significativo) e Rd (i restanti tre bit).
<Rm> Specifica il registro contenente il valore da copiare. Può essere uno qualsiasi tra R0 e R15. Il
numero del registro è dato da H2 (bit più significativo) e Rm (i restanti tre bit).
Versione architettura
Tutte le varianti T
Eccezioni
Nessuna
Operazione
Rd = Rm
Uso
L’istruzione MOV PC, R14 può essere usata come istruzione di ritorno da una subroutine se si sa che
la subroutine è di tipo Thumb. Comunque, è fortemente raccomandato usare BX R14. L’istruzione
BX R14 funziona sempre sia che il chiamante fosse una ruotine ARM sia che fosse una routine
Thumb, ed ha vantaggi prestazionali su alcuni processori.
116
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Note
Sintassi Assembler
Se vengono specificati due registri bassi, la sintassi assembler
<Rn> viene riportata all’istruzione MOV(2).
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
MOV
<Rd>,
Entrambi reg. bassi Se H1 == 0 e H2 == 0 nella codifica, l’istruzione specifica una copia di
contenuti senza modificare i flags di stato. Questa istruzione non può essere
scritta usando la sintassi MOV <Rd>, <Rm> poiché andrebbe a modificare i
flags di stato. Comunque si può scrivere usando CPY.
------- Nota ---------------Nelle vers. precedenti ARMv6, specificando due reg. bassi il ris. è impreved.
------------------------------Sintassi e codifica equivalente ARM
Un equivalente simile è:
MOV
<Rd>, <Rm>
Ci sono leggere differenze quando le istruzioni accedono al PC, a causa delle differenti definizioni
di PC nell’esecuzione di codice ARM e Thumb.
117
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
6.1.45. MUL
MUL (Multiply) moltiplica variabili con o senza segno per ottenere un risultato di 32-bit.
MUL aggiorna i flags di stato, in base al risultato.
Sintassi
MUL <Rd>, <Rm>
dove:
<Rd> Contiene il valore da moltiplicare con il valore di <Rm> ed è il registro di destinazione
dell’operazione.
<Rm> È il registro contenente il valore da moltiplicare con il valore di <Rd>.
Versione architettura
Tutte le varianti T
Eccezioni
Nessuna
Operazione
Rd = (Rm * Rd)[31:0]
N Flag = Rd[31]
Z Flag = if Rd == 0 then 1 else 0
C Flag = unaffected /* See "C flag" note */
V Flag = unaffected
Note
Con e senza segno
C Flag
Siccome MUL produce solamente i 32 bits meno significativi di un prodotto a
64-bit, MUL da lo stesso risultato per moltiplicazioni di numeri con o senza
sengo.
L’istruzione MUL è definita in modo da lasciare il flag C inalterato in ARMv5 e
superiori. Nelle versioni precedenti il valore del flag C è imprevedibile dopo
l’esecuzione dell’istruzione MUL.
Restrizione operandi Prima di ARMv6 specificare lo stesso registro per Rd e Rm ha risultati
imprevedibili.
Sintassi e codifica equivalente ARM
MULS <Rd>, <Rm>, <Rd>
118
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
6.1.46. MVN
MVN (Move NOT) fa il complemento di un valore in un registro.
MVN aggiorna i flags di stato, in base al risultato.
Sintassi
MVN <Rd>, <Rm>
dove:
<Rd> È il registro di destinazione dell’operazione.
<Rm> È il registro contenente il valore il cui complemento viene scritto in <Rd>.
Versione architettura
Tutte le varianti T
Eccezioni
Nessuna
Operazione
Rd = NOT Rm
N Flag = Rd[31]
Z Flag = if Rd == 0 then 1 else 0
C Flag = unaffected
V Flag = unaffected
Sintassi e codifica equivalente ARM
MVNS <Rd>, <Rm>
119
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
6.1.47. NEG
NEG (Negate) nega il valore di un registro e lo salva in una altro registro.
NEG aggiorna i flags di stato, in base al risultato.
Sintassi
NEG <Rd>, <Rm>
dove:
<Rd> È il registro di destinazione dell’operazione.
<Rm> È il registro contenente il valore che verrà sottratto da zero.
Versione architettura
Tutte le varianti T
Eccezioni
Nessuna
Operazione
Rd = 0 - Rm
N Flag = Rd[31]
Z Flag = if Rd == 0 then 1 else 0
C Flag = NOT BorrowFrom(0 - Rm)
V Flag = OverflowFrom(0 - Rm)
Sintassi e codifica equivalente ARM
RSBS <Rd>, <Rm>, #0
120
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
6.1.48. ORR
ORR (Logical OR) fa un OR bit a bit tra i valori di due registri.
ORR aggiorna i flags di stato, in base al risultato.
Sintassi
ORR <Rd>, <Rm>
dove:
<Rd> È il registro di destinazione dell’operazione.
<Rm> È il registro contenente il valore che verrà confrontato con quello in <Rd>.
Versione architettura
Tutte le varianti T
Eccezioni
Nessuna
Operazione
Rd = Rd OR Rm
N Flag = Rd[31]
Z Flag = if Rd == 0 then 1 else 0
C Flag = unaffected
V Flag = unaffected
Sintassi e codifica equivalente ARM
ORRS <Rd>, <Rd>, <Rm>
121
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
6.1.49. POP
(Pop Multiple Registers) carica un sottoinsieme (o tutti) di registri generici R0-R7 e il PC dallo
stack.
POP
I registri generici caricati possono includere il PC. Se è così, la parola caricata per il PC è trattata
come un indirizzo e avviene un salto a questo indirizzo. In ARMv5 e superiori, il bit[0] del valore
caricato determina se l’esecuzione continua, dopo questo salto, nello stato ARM o nello stato
Thumb, come se fosse stata eseguita l’istruzione seguente:
BX (loaded_value)
Nelle varianti T di ARMv4, il bit*0+ del valore caricato viene ignorato e l’esecuzione continua nello
stato Thumb, come se fosse stata eseguita la seguente istruzione:
MOV PC, (loaded_value)
Sintassi
POP <registers>
dove:
<registers>
È la lista dei registri da caricare, separati da una virgola e racchiusi tra parentesi
graffe. La lista è codificata nel campo register_list dell’istruzione, settando il bit*i+ a
1 se il registro Ri è incluso nella lista, a zero altrimenti per ogni i da 0 a 7. Il bit R è
settato a 1 se il PC è incluso nella lista, è settato a 0 altrimenti.
Almeno un registro deve essere caricato. Se tutti i bit[8:0] sono a zero il risultato è
imprevedibile.
I registri vengono caricati in sequenza, dal registro col numero più basso a cui
corrisponde l’indirizzo più piccolo in memoria (l’indirizzo iniziale), fino al registro col
numero più alto a cui corrisponde l’indirizzo più grande in memoria (l’indirizzo
finale). Se il PC è specificato nella lista (bit*8+ settato a 1), l’istrtuzione causa un salto
all’indirizzo caricato nel PC.
L’indirizzo iniziale è il valore del registro SP. Gli indirizzi succesivi sono formati
incrementando l’indirizzo precedente di 4. Viene prodotto un indirizzo per ogni
registro specificato in register_list.
L’indirizzo finale è formato da: registro_base + 4 * (numero_registri_specificati – 1).
Infine il valore di SP è incrementato di quattro volte i registri specificati in
register_list.
Versione architettura
Tutte le varianti T
Eccezioni
Data Abort.
122
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
Operazione
MemoryAccess(B-bit, E-bit)
start_address = SP
end_address = SP + 4*(R + Number_Of_Set_Bits_In(register_list))
address = start_address
for i = 0 to 7
if register_list[i] == 1 then
Ri = Memory[address,4]
address = address + 4
if R == 1 then
value = Memory[address,4]
PC = value AND 0xFFFFFFFE
if (architecture version 5 or above) then
T Bit = value[0]
address = address + 4
assert end_address = address
SP = end_address
Uso
Usare POP per operazioni di stack. Un’istruzione POP con il PC nella lista dei registri può essere
usata per un’efficiente procedura di uscita, infatti, ripristina i registri salvati, carica il PC con
l’indirizzo di ritorno, e aggiorna lo stack pointer con una sola istruzione.
Note
Data Abort
Per i dettagli sugli effetti dell’istruzione se avviene un Data Abort controllare
la sezione Effetti delle istruzioni che hanno provocato un Data-Abort.
CPSR
Solo il bit T del CPSR può essere aggiornano da pop gli altri bit non vengono
modificati.
Allineamento
Se un implementazione include un sistema di controllo coprocessore e il
controllo dell’allineamento è abilitato, un indirizzo con i bit*1:0+ != 0b00
causa un’eccezione di allineamento.
L’opzione di controllo dell’allineamento viene supportata dall’ARMv6 in poi:

Se CP15_reg1_Abit == 1, un accesso non allineato causa un DataAbort.

Se CP15_reg1_Abit == 0:
-
e CP15_reg1_Ubit == 0, l’istruzione ignora i due bit meno
significativi dell’indirizzo;
123
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
-
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
e CP15_reg1_Ubit == 1, un accesso non allineato causa un DataAbort.
Trasferimento ARM/Thumb
In ARMv5 e superiori se i bits[1:0] del valore caricato per R15 sono 0b10, il
risultato è imprevedibile, poiché i salti a parole non allineate non sono
possibili nello stato ARM.
Time order
L’ordine cronologico di accesso alle parole individuali della memoria
generato da questa istruzione è definito solo in alcune circostanze. Vedere
Restrizioni di accesso alla memoria per maggiori dettagli.
Sintassi e codifica equivalente ARM
LDMIA SP!, <registers>
124
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
6.1.50. PUSH
(Push Multiple Registers) salva un sottoinsieme (o tutti) di registri generici R0-R7 e LR nello
stack.
PUSH
Sintassi
PUSH <registers>
dove:
<registers>
È la lista dei registri da salvare, separati da una virgola e racchiusi tra parentesi
graffe. La lista è codificata nel campo register_list dell’istruzione, settando il bit*i+ a
1 se il registro Ri è incluso nella lista, a zero altrimenti per ogni i da 0 a 7. Il bit R è
settato a 1 se il PC è incluso nella lista, è settato a 0 altrimenti.
Almeno un registro deve essere salvato. Se tutti i bit[8:0] sono a zero il risultato è
imprevedibile.
I registri vengono salvati in sequenza, dal registro col numero più basso a cui
corrisponde l’indirizzo più piccolo in memoria (l’indirizzo iniziale), fino al registro col
numero più alto a cui corrisponde l’indirizzo più grande in memoria (l’indirizzo
finale). Se il PC è specificato nella lista (bit*8+ settato a 1), l’istrtuzione causa un salto
all’indirizzo caricato nel PC.
L’indirizzo iniziale è il valore del registro SP. Gli indirizzi succesivi sono formati
incrementando l’indirizzo precedente di 4. Viene prodotto un indirizzo per ogni
registro specificato in register_list.
L’indirizzo finale è formato da: registro_base + 4 * (numero_registri_specificati – 1).
Infine il valore di SP è incrementato di quattro volte i registri specificati in
register_list.
Versione architettura
Tutte le varianti T
Eccezioni
Data Abort.
125
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
Operazione
MemoryAccess(B-bit, E-bit)
start_address = SP - 4*(R + Number_Of_Set_Bits_In(register_list))
end_address = SP - 4
address = start_address
for i = 0 to 7
if register_list[i] == 1
Memory[address,4] = Ri
address = address + 4
if R == 1
Memory[address,4] = LR
address = address + 4
assert end_address == address - 4
SP = SP - 4*(R + Number_Of_Set_Bits_In(register_list))
if (CP15_reg1_Ubit == 1) /* ARMv6 */
if Shared(address then /* from ARMv6 */
physical_address = TLB(address
ClearExclusiveByAddress(physical_address, size)
Uso
Usare PUSH per operazioni di stack. Un’istruzione PUSH con LR nella lista dei registri può essere
usata per un’efficiente procedura di entrata, infatti, salva i registri (incluso l’indirizzo di ritorno), e
aggiorna lo stack pointer con una sola istruzione. Una corrispondente istruzione pop può essere
usata dopo per ritornare dalla procedura.
126
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Note
Data Abort
Allineamento
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
Per i dettagli sugli effetti dell’istruzione se avviene un Data Abort controllare
la sezione Effetti delle istruzioni che hanno provocato un Data-Abort.
Se un implementazione include un sistema di controllo coprocessore e il
controllo dell’allineamento è abilitato, un indirizzo con i bit*1:0+ != 0b00
causa un’eccezione di allineamento.
L’opzione di controllo dell’allineamento viene supportata dall’ARMv6 in poi:
Time order

Se CP15_reg1_Abit == 1, un accesso non allineato causa un Data-Abort.

Se CP15_reg1_Abit == 0:
-
e CP15_reg1_Ubit == 0, l’istruzione ignora i due bit meno
significativi dell’indirizzo;
-
e CP15_reg1_Ubit == 1, un accesso non allineato causa un DataAbort.
L’ordine cronologico di accesso alle parole individuali della memoria
generato da questa istruzione è definito solo in alcune circostanze. Vedere
Restrizioni di accesso alla memoria per maggiori dettagli.
Sintassi e codifica equivalente ARM
STMD SP!, <registers>
127
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
6.1.51. REV
(Byte-Reverse Word) inverte l’ordine del byte in un registro a 32-bit. Non ha effetti sui flags di
stato.
REV
Sintassi
REV <Rd>, <Rn>
dove:
<Rd> È il registro di destinazione dell’operazione.
<Rn> È il registro che contiene l’operando.
Versione architettura
ARMv6 e superiori.
Eccezioni
Nessuna
Operazione
Rd[31:24] = Rn[ 7: 0]
Rd[23:16] = Rn[15: 8]
Rd[15: 8] = Rn[23:16]
Rd[ 7: 0] = Rn[31:24]
Uso
Usare REV per convertire un dato a 32-bit codificato con l’ordine “big-endian” in “little-endian” o
viceversa.
Sintassi e codifica equivalente ARM
REV <Rd>, <Rm>
128
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
6.1.52. REV16
REV16
(Byte-Reverse Packed Halfword) inverte l’ordine di ogni parola a 16-bit di un registro a 32bit. Non ha effetti sui flags di stato.
Sintassi
REV16 <Rd>, <Rn>
dove:
<Rd> È il registro di destinazione dell’operazione.
<Rn> È il registro che contiene l’operando.
Versione architettura
ARMv6 e superiori.
Eccezioni
Nessuna
Operazione
Rd[15: 8] = Rn[ 7: 0]
Rd[ 7: 0] = Rn[15: 8]
Rd[31:24] = Rn[23:16]
Rd[23:16] = Rn[31:24]
Uso
Usare REV16 per convertire un dato a 16-bit codificato con l’ordine “big-endian” in “little-endian” o
viceversa.
Sintassi e codifica equivalente ARM
REV16 <Rd>, <Rm>
129
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
6.1.53. REVSH
(Byte-Reverse Signed Halfword) inverte l’ordine della parola a 16-bit nella parte bassa di un
registro a 32-bit ed estende il segno fino a 32-bit. Non ha effetti sui flags di stato.
REVSH
Sintassi
REVSH <Rd>, <Rn>
dove:
<Rd> È il registro di destinazione dell’operazione.
<Rn> È il registro che contiene l’operando.
Versione architettura
ARMv6 e superiori.
Eccezioni
Nessuna
Operazione
Rd[15: 8] = Rn[ 7: 0]
Rd[ 7: 0] = Rn[15: 8]
if Rn[7] == 1 then
Rd[31:16] = 0xFFFF
else
Rd[31:16] = 0x0000
Uso
Usare REVSH per convertire:

un dato a 16-bit codificato in “big-endian” in un dato “little-endian” con segno a 32-bit.

un dato a 16-bit codificato in “little-endian” in un dato “big-endian” con segno a 32-bit.
Sintassi e codifica equivalente ARM
REVSH <Rd>, <Rm>
130
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
6.1.54. ROR
(Rotate Right Register) fornisce il contenuto di un registro ruotato di un valore variabile. I bit
che escono a destra nella rotazione vengono inseriti nei posti vuoti sulla sinistra.
ROR
ROR aggiorna i flags di condizione, a seconda del risultato.
Sintassi
ROR <Rd>, <Rs>
dove:
<Rd> Contiene il valore da ruotare, ed è anche il registro di destinazione dell’operazione.
<Rs>
È il registro contenente la rotazione applicata al valore di <Rd>. Il valore di rotazione è
contenuto nel byte meno significativo.
Versione architettura
Tutte le varianti T
Eccezioni
Nessuna
Operazione
if Rs[7:0] == 0 then
C Flag = unaffected
Rd = unaffected
//se gli ultimi 5 bit sono zeri significa che ruota di un multiplo di 32, quindi <Rd> rimane invariato
else if Rs[4:0] == 0 then
C Flag = Rd[31]
Rd = unaffected
else /* Rs[4:0] > 0 */
C Flag = Rd[Rs[4:0] - 1]
Rd = Rd Rotate_Right Rs[4:0]
N Flag = Rd[31]
Z Flag = if Rd == 0 then 1 else 0
V Flag = unaffected
131
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Sintassi e codifica equivalente ARM
MOV <Rd>, <Rd>, ror <Rs>
132
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
6.1.55. SBC
(Subtract with Carry) sottrae il valore del secondo operando e del flag C negato dal primo
operando.
SBC
SBC aggiorna i flags di condizione, a seconda del risultato.
Usare SBC per sintetizzare sottrazioni multiparola.
Sintassi
SBC <Rd>, <Rm>
dove:
<Rd> Contiene il primo operando della sottrazione, ed è anche il registro di destinazione
dell’operazione.
<Rm> Contiene il valore da sottrarre ad <Rd>.
Versione architettura
Tutte le varianti T
Eccezioni
Nessuna
Operazione
Rd = Rd - Rm - NOT(C Flag)
N Flag = Rd[31]
Z Flag = if Rd == 0 then 1 else 0
C Flag = NOT BorrowFrom(Rd - Rm - NOT(C Flag))
V Flag = OverflowFrom(Rd - Rm - NOT(C Flag))
Sintassi e codifica equivalente ARM
SBCS <Rd>, <Rd>, <Rm>
133
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
6.1.56. SETEND
SETEND modifica il bit E del CPSR, senza toccare gli altri bits del CPSR.
Sintassi
SETEND
<endian_specifier>
dove:
<endian_specifier>
Può essere:
LE
E=0
BE
E=1
Versione architettura
ARMv6 e superiori
Eccezioni
Nessuna
Operazione
CPSR = CPSR con modifica opportune del bit E
Uso
Usare SETEND per cambiare l’ordine di accesso ai byte dei dati. Si può usare SETEND per
incrementare l’efficienza di accesso ad una serie di dati big-endian in una diversa applicazione
little-endian, o viceversa. Vedere la sezione Supporto Endian per maggiori informazioni.
Sintassi e codifica equivalente ARM
SETEND
134
<endian_specifier>
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
6.1.57. STMIA
(Store Multiple Increment After) salva un sottoinsieme non vuoto, oppure tutti, i registri
generici (R0-R7) in locazioni di memoria sequenziali.
STMIA
Sintassi
STMIA <Rn>!, <registers>
dove:
<Rn>
Specifica il registro contenente l’indirizzo di inizio per l’istruzione.
!
Causa la riscrittura del registro base, e non è opzionale.
<registers>
È la lista dei registri da salvare, separati da una virgola e racchiusi tra parentesi
graffe. La lista è codificata nel campo register_list dell’istruzione, settando il bit[i] a
1 se il registro Ri è incluso nella lista, a zero altrimenti per ogni i da 0 a 7.
Almeno un registro deve essere salvato. Se tutti i bit[7:0] sono a zero il risultato è
imprevedibile.
I registri vengono salvati in sequenza, dal registro col numero più basso a cui
corrisponde l’indirizzo più piccolo in memoria (l’indirizzo iniziale), fino al registro col
numero più alto a cui corrisponde l’indirizzo più grande in memoria (l’indirizzo
finale).
L’indirizzo iniziale è il valore del registro base Rn. Gli indirizzi succesivi sono formati
incrementando l’indirizzo precedente di 4. Viene prodotto un indirizzo per ogni
registro specificato in <registers>.
L’indirizzo finale è formato da: registro_base + 4 * (numero_registri_specificati – 1).
Infine, il valore di <Rn> è incrementato di quattro volte i registri specificati in
<registers>.
Versione architettura
Tutte le varianti T
Eccezioni
Data Abort
135
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
Operazione
MemoryAccess(B-bit, E-bit)
processor_id = ExecutingProcessor()
start_address = Rn
end_address = Rn + (Number_Of_Set_Bits_In(register_list) * 4) - 4
address = start_address
for i = 0 to 7
if register_list[i] == 1
Memory[address,4] = Ri
if Shared(address) then /* from ARMv6 */
physical_address = TLB(address)
ClearExclusiveByAddress(physical_address,4)
address = address + 4
assert end_address == address - 4
Rn = Rn + (Number_Of_Set_Bits_In(register_list) * 4)
Uso
Usare STMIA come istruzione per salvare blocchi dalla memoria. In combinazione con ldmia
permette un’efficiente gestione della copia di blocchi di memoria.
Note
Restrizione operandi
Se <Rn> è specificato in <registers>:
Data Abort

se <Rn> è l’ultimo registro specificato in <registers>, il suo valore originale
viene salvato

altrimenti, il valore salvato per <Rn> è imprevedibile
Per i dettagli sugli effetti dell’istruzione se avviene un Data Abort controllare la
sezione Effetti delle istruzioni che hanno provocato un Data-Abort.
Allineamento Se un implementazione include un sistema di controllo coprocessore e il controllo
dell’allineamento è abilitato, un indirizzo con i bit*1:0+ != 0b00 causa un’eccezione
di allineamento.
L’opzione di controllo dell’allineamento viene supportata dall’ARMv6 in poi:
136

Se CP15_reg1_Abit == 1, un accesso non allineato causa un Data-Abort.

Se CP15_reg1_Abit == 0:
-
e CP15_reg1_Ubit == 0, l’istruzione ignora i due bit meno significativi
dell’indirizzo;
-
e CP15_reg1_Ubit == 1, un accesso non allineato causa un Data-Abort.
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Time order
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
L’ordine cronologico di accesso alle parole individuali della memoria generato da
questa istruzione è definito solo in alcune circostanze. Vedere Restrizioni di accesso
alla memoria per maggiori dettagli.
Sintassi e codifica equivalente ARM
STMIA <Rn>!, <registers>
137
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
6.1.58. STR(1)
STR(1)
(Store Register) permette di salvare un dato di 32-bit da un registro in memoria. Il modo di
indirizzamento è utile per accedere a strutture (record). Con un offset di zero l’indirizzo prodotto è
l’inalterato valore del registro base Rn.
Sintassi
STR <Rd>, [<Rn>, #<immed_5> * 4]
dove:
<Rd>
È il registro che contiene il valore della parola da salvare in memoria.
<Rn>
È il registro contenente l’indirizzo base dell’istruzione.
<immed_5>
È un valore di 5-bit che viene moltiplicato per 4 e aggiunto ad Rn per formare
l’indirizzo di memoria.
Versione architettura
Tutte le varianti T
Eccezioni
Data Abort
Operazione
MemoryAccess(B-bit, E-bit)
processor_id = ExecutingProcessor()
address = Rn + (immed_5 * 4)
if (CP15_reg1_Ubit == 0)
if address[1:0] == 0b00 then
Memory[address,4] = Rd
else
Memory[address,4] = UNPREDICTABLE
else /* CP15_reg1_Ubit == 1 */
Memory[address,4] = Rd
if Shared(address) then /* from ARMv6 */
physical_address = TLB(address)
ClearExclusiveByAddress(physical_address, 4)
138
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Note
Data Abort
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
Per i dettagli sugli effetti dell’istruzione se avviene un Data Abort controllare la
sezione Effetti delle istruzioni che hanno provocato un Data-Abort.
Allineamento Prima di ARMv6, se l’indirizzo di memoria non è allineato alla parola, l’istruzione è
imprevedibile. Il controllo di allineamento (si verifica un Data-Abort quando i
bit*1:0+ dell’indirizzo sono diversi da 0b00), e il supporto per dati più grandi di 32-bit
erano opzioni delle implementazioni.
L’opzione di controllo dell’allineamento viene supportata dall’ARMv6 in poi:

Se CP15_reg1_Abit == 1, un accesso non allineato causa un Data-Abort.

Se CP15_reg1_Abit == 0:
-
e CP15_reg1_Ubit == 0, l’istruzione ignora i due bit meno significativi
dell’indirizzo;
-
e CP15_reg1_Ubit == 1, un accesso non allineato causa un Data-Abort.
Sintassi e codifica equivalente ARM
STR <Rd>, [<Rn>, #<immed_5> * 4]
139
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
6.1.59. STR(2)
STR(2)
permette di salvare un dato di 32-bit da un registro in memoria. Il modo di indirizzamento è
utile per puntatori + offset e per accedere ad un elemento di un vettore.
Sintassi
STR <Rd>, [<Rn>, <Rm>]
dove:
<Rd> È il registro contenente la parola da salvare in memoria.
<Rn> È il registro contenente il primo valore usato per formare l’indirizzo.
<Rm> È il registro contenente il secondo valore usato per formare l’indirizzo.
Versione architettura
Tutte le varianti T
Eccezioni
Data Abort
Operazione
MemoryAccess(B-bit, E-bit)
processor_id = ExecutingProcessor()
address = Rn + Rm
if (CP15_reg1_Ubit == 0)
if address[1:0] == 0b00 then
Memory[address,4] = Rd
else
Memory[address,4] = UNPREDICTABLE
else /* CP15_reg1_Ubit == 1 */
Memory[address,4] = Rd
if Shared(address) then /* from ARMv6 */
physical_address = TLB(address)
ClearExclusiveByAddress(physical_address, 4)
140
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Note
Data Abort
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
Per i dettagli sugli effetti dell’istruzione se avviene un Data Abort controllare la
sezione Effetti delle istruzioni che hanno provocato un Data-Abort.
Allineamento Prima di ARMv6, se l’indirizzo di memoria non è allineato alla parola, l’istruzione è
imprevedibile. Il controllo di allineamento (si verifica un Data-Abort quando i
bit*1:0+ dell’indirizzo sono diversi da 0b00), e il supporto per dati più grandi di 32-bit
erano opzioni delle implementazioni.
L’opzione di controllo dell’allineamento viene supportata dall’ARMv6 in poi:

Se CP15_reg1_Abit == 1, un accesso non allineato causa un Data-Abort.

Se CP15_reg1_Abit == 0:
-
e CP15_reg1_Ubit == 0, l’istruzione ignora i due bit meno significativi
dell’indirizzo;
-
e CP15_reg1_Ubit == 1, un accesso non allineato causa un Data-Abort.
Sintassi e codifica equivalente ARM
STR <Rd>, [<Rn>, <Rm>]
141
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
6.1.60. STR(3)
STR(3)
permette di salvare un dato di 32-bit da un registro in memoria. Il modo di indirizzamento è
utile per accedere allo stack. In questo caso, str salva una parola da <Rd> in memoria.
Sintassi
STR <Rd>, [SP, #<immed_8> * 4]
dove:
<Rd>
È il registro che contiene la parola da salvare in memoria.
SP
È lo Stack Pointer. Il suo valore è usato per calcolare l’indirizzo di memoria.
<immed_8>
È un valore di 8-bit che moltiplicato per 4 e aggiunto al valore del SP forma
l’indirizzo di memoria.
Versione architettura
Tutte le varianti T
Eccezioni
Data Abort
Operazione
MemoryAccess(B-bit, E-bit)
processor_id = ExecutingProcessor()
address = SP + (immed_8 * 4)
if (CP15_reg1_Ubit == 0)
if address[1:0] == 0b00 then
Memory[address,4] = Rd
else
Memory[address,4] = UNPREDICTABLE
else /* CP15_reg1_Ubit == 1 */
Memory[address,4] = Rd
if Shared(address) then /* from ARMv6 */
physical_address = TLB(address)
ClearExclusiveByAddress(physical_address, 4)
142
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Note
Data Abort
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
Per i dettagli sugli effetti dell’istruzione se avviene un Data Abort controllare la
sezione Effetti delle istruzioni che hanno provocato un Data-Abort.
Allineamento Prima di ARMv6, se l’indirizzo di memoria non è allineato alla parola, l’istruzione è
imprevedibile. Il controllo di allineamento (si verifica un Data-Abort quando i
bit*1:0+ dell’indirizzo sono diversi da 0b00), e il supporto per dati più grandi di 32-bit
erano opzioni delle implementazioni.
L’opzione di controllo dell’allineamento viene supportata dall’ARMv6 in poi:

Se CP15_reg1_Abit == 1, un accesso non allineato causa un Data-Abort.

Se CP15_reg1_Abit == 0:
-
e CP15_reg1_Ubit == 0, l’istruzione ignora i due bit meno significativi
dell’indirizzo;
-
e CP15_reg1_Ubit == 1, un accesso non allineato causa un Data-Abort.
Sintassi e codifica equivalente ARM
STR <Rd>, [SP, #<immed_8> * 4]
143
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
6.1.61. STRB(1)
STRB(1)
(Store Register Byte) salva un dato di 8-bit da un registro generico in memoria. Il modo di
indirizzamento è utile per accedere a strutture o record.
Con un offset pari a zero, l’indirizzo prodotto è il valore inalterato dell’indirizzo base Rn.
Sintassi
STRB <Rd>, [<Rn>, #<immed_5>]
dove:
<Rd>
È il registro contenente il byte da salvare in memoria.
<Rn>
È il registro contenente l’indirizzo base per l’istruzione.
<immed_5>
È un valore di 5-bit che viene aggiunto al valore di Rn per formare l’indirizzo di
memoria.
Versione architettura
Tutte le varianti T
Eccezioni
Data Abort
Operazione
MemoryAccess(B-bit, E-bit)
processor_id = ExecutingProcessor()
address = Rn + immed_5
Memory[address,1] = Rd[7:0]
if Shared(address) then /* from ARMv6 */
physical_address = TLB(address)
ClearExclusiveByAddress(physical_address, 1)
144
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Note
Data Abort
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
Per i dettagli sugli effetti dell’istruzione se avviene un Data Abort controllare la
sezione Effetti delle istruzioni che hanno provocato un Data-Abort.
Sintassi e codifica equivalente ARM
STRB <Rd>, [<Rn>, #<immed_5>]
145
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
6.1.62. STRB(2)
STRB(2)
salva un dato di 8-bit contenuto in un registro in memoria. Il modo di indirizzamento è utile
per puntatori + offset e per accedere ad un elemento di un vettore.
Sintassi
STRB <Rd>, [<Rn>, <Rm>]
dove:
<Rd> È il registro contenente il byte da salvare in memoria.
<Rn> È il registro contenente il primo valore usato per formare l’indirizzo.
<Rm> È il registro contenente il secondo valore usato per formare l’indirizzo.
Versione architettura
Tutte le varianti T
Eccezioni
Data Abort
Operazione
MemoryAccess(B-bit, E-bit)
processor_id = ExecutingProcessor()
address = Rn + Rm
Memory[address,1] = Rd[7:0]
if Shared(address) then /* from ARMv6 */
physical_address = TLB(address)
ClearExclusiveByAddress(physical_address, 1)
Note
Data Abort
Per i dettagli sugli effetti dell’istruzione se avviene un Data Abort controllare la
sezione Effetti delle istruzioni che hanno provocato un Data-Abort.
Sintassi e codifica equivalente ARM
STRB <Rd>, [<Rn>, <Rm>]
146
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
6.1.63. STRH(1)
STRH(1)
(Store Register Halfword) salva mezza parola (16-bit) contenuta in un registro generico in
memoria. Il modo di indirizzamento è utile per accedere a strutture o record. Con un offset pari a
zero, l’indirizzo prodotto è il valore inalterato dell’indirizzo base Rn.
Sintassi
STRH <Rd>, [<Rn>, #<immed_5> * 2]
dove:
<Rd>
È il registro contenente la mezza parola da salvare in memoria.
<Rn>
È il registro contenente l’indirizzo base per l’istruzione.
<immed_5>
È un valore di 5-bit che moltiplicato per 2 viene aggiunto al valore di Rn per formare
l’indirizzo di memoria.
Versione architettura
Tutte le varianti T
Eccezioni
Data Abort
Operazione
MemoryAccess(B-bit, E-bit)
processor_id = ExecutingProcessor()
address = Rn + (immed_5 * 2)
if (CP15_reg1_Ubit == 0)
if address[0] == 0b0 then
Memory[address,2] = Rd[15:0]
else
Memory[address,2] = UNPREDICTABLE
else /* CP15_reg1_Ubit == 1 */
Memory[address,2] = Rd[15:0]
if Shared(address) then /* from ARMv6 */
physical_address = TLB(address)
ClearExclusiveByAddress(physical_address, 2)
147
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Note
Data Abort
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
Per i dettagli sugli effetti dell’istruzione se avviene un Data Abort controllare la
sezione Effetti delle istruzioni che hanno provocato un Data-Abort.
Allineamento Prima di ARMv6, se l’indirizzo di memoria non era allineato alla parola, i dati letti
dalla memoria erano casuali. Il controllo di allineamento (si verifica un Data-Abort
quando i bit*1:0+ dell’indirizzo sono diversi da 0b00), e il supporto per dati più
grandi di 32-bit erano opzioni delle implementazioni.
L’opzione di controllo dell’allineamento viene supportata dall’ARMv6 in poi:

Se CP15_reg1_Abit == 1, un accesso non allineato causa un Data-Abort.

Se CP15_reg1_Abit == 0:
-
e CP15_reg1_Ubit == 0, l’istruzione ignora i due bit meno significativi
dell’indirizzo;
-
e CP15_reg1_Ubit == 1, un accesso non allineato causa un Data-Abort.
Sintassi e codifica equivalente ARM
STRH <Rd>, [<Rn>, #<immed_5> * 2]
148
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
6.1.64. STRH(2)
STRH(2)
salva mezza parola (16-bit) da un registro generico in memoria. Il modo di indirizzamento è
utile per puntatori + offset e per accedere ad un elemento di un vettore.
Sintassi
STRH <Rd>, [<Rn>, <Rm>]
dove:
<Rd> È il registro contenente la mezza parola da salvare in memoria.
<Rn> È il registro contenente il primo valore usato per formare l’indirizzo.
<Rm> È il registro contenente il secondo valore usato per formare l’indirizzo.
Versione architettura
Tutte le varianti T
Eccezioni
Data Abort
Operazione
MemoryAccess(B-bit, E-bit)
processor_id = ExecutingProcessor()
address = Rn + Rm
if (CP15_reg1_Ubit == 0)
if address[0] == 0b0 then
Memory[address,2] = Rd[15:0]
else
Memory[address,2] = UNPREDICTABLE
else /* CP15_reg1_Ubit == 1 */
Memory[address,2] = Rd[15:0]
if Shared(address) then /* from ARMv6 */
physical_address = TLB(address)
ClearExclusiveByAddress(physical_address, 2)
149
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Note
Data Abort
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
Per i dettagli sugli effetti dell’istruzione se avviene un Data Abort controllare la
sezione Effetti delle istruzioni che hanno provocato un Data-Abort.
Allineamento Prima di ARMv6, se l’indirizzo di memoria non era allineato alla parola, i dati letti
dalla memoria erano casuali. Il controllo di allineamento (si verifica un Data-Abort
quando i bit*1:0+ dell’indirizzo sono diversi da 0b00), e il supporto per dati più
grandi di 32-bit erano opzioni delle implementazioni.
L’opzione di controllo dell’allineamento viene supportata dall’ARMv6 in poi:

Se CP15_reg1_Abit == 1, un accesso non allineato causa un Data-Abort.

Se CP15_reg1_Abit == 0:
-
e CP15_reg1_Ubit == 0, l’istruzione ignora i due bit meno significativi
dell’indirizzo;
-
e CP15_reg1_Ubit == 1, un accesso non allineato causa un Data-Abort.
Sintassi e codifica equivalente ARM
STRH <Rd>, [<Rn>, <Rm>]
150
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
6.1.65. SUB(1)
SUB(1)
(Subtract) sottrare il valore di una piccola costante dal valore di un registro e mette il
risultato in un secondo registro.
Aggiorna i flag di stato, a seconda del risultato.
Sintassi
SUB <Rd>, <Rn>, #<immed_3>
dove:
<Rd>
Registro di destinazione.
<Rn>
Specifica il registro che contiene il primo operando della sottrazione.
<immed_3>
Specifica un valore a 3-bit che viene sottratto a <Rn>.
Versione architettura
Tutte le varianti T
Eccezioni
Nessuna
Operazione
Rd = Rn - immed_3
N Flag = Rd[31]
Z Flag = if Rd == 0 then 1 else 0
C Flag = NOT BorrowFrom(Rn - immed_3)
V Flag = OverflowFrom(Rn - immed_3)
Sintassi e codifica equivalente ARM
SUBS <Rd>, <Rn>, #<immed_3>
151
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
6.1.66. SUB(2)
SUB(2)
sottrare il valore di una grande costante dal valore di un registro e mette il risultato nel
registro stesso.
Aggiorna i flag di stato, a seconda del risultato.
Sintassi
SUB <Rd>, #<immed_8>
dove:
<Rd>
Specifica il registro che contiene il primo operando della sottrazione, ed è anche il
registro di destinazione.
<immed_8>
Specifica un valore a 8-bit che viene sottratto a <Rd>.
Versione architettura
Tutte le varianti T
Eccezioni
Nessuna
Operazione
Rd = Rd - immed_8
N Flag = Rd[31]
Z Flag = if Rd == 0 then 1 else 0
C Flag = NOT BorrowFrom(Rd - immed_8)
V Flag = OverflowFrom(Rd - immed_8)
Sintassi e codifica equivalente ARM
SUBS <Rd>, <Rd>, #<immed_8>
152
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
6.1.67. SUB(3)
SUB(3)
sottrare il valore di un registro dal valore di un secondo registro e salva il risultato in un
terzo registro.
Aggiorna i flag di stato, a seconda del risultato.
Sintassi
SUB <Rd>, <Rn>, <Rm>
dove:
<Rd> È il registro di destinazione.
<Rn> Contiene il primo operando della sottrazione.
<Rm>
Contiene il valore che viene sottratto a <Rn>.
Versione architettura
Tutte le varianti T
Eccezioni
Nessuna
Operazione
Rd = Rn - Rm
N Flag = Rd[31]
Z Flag = if Rd == 0 then 1 else 0
C Flag = NOT BorrowFrom(Rn - Rm)
V Flag = OverflowFrom(Rn - Rm)
Sintassi e codifica equivalente ARM
SUBS <Rd>, <Rn>, <Rm>
153
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
6.1.68. SUB(4)
SUB(4)
decrementa lo SP di 4 volte un valore immediato a 7-bit (cioè un multiplo di 4 nell’intervallo
0-508).
I flags di stato non vengono modificati.
Sintassi
SUB SP, #<immed_7> * 4
dove:
<SP>
Indica lo Stack Pointer. Il risultato dell’operazione viene salvato nello SP.
<immed_7>
Valore immediato di 7-bit che viene sottratto allo SP.
Versione architettura
Tutte le varianti T
Eccezioni
Nessuna
Operazione
SP = SP - (immed_7 << 2)
// l’operatore ‘<<’ indica lo shift aritmetico a sinistra di n bit, che
n
equivale a moltiplicare per 2 .
Uso
Per lo stack decrescente che usa il set Thumb, decrementeare lo SP significa allocare ulteriore
memoria all’inizio dello stack.
Note
Questa istruzione può anche essere scritta in questo modo: SUB SP, SP, #<immed_7> * 4.
Sintassi e codifica equivalente ARM
SUB SP, SP, #<immed_7> * 4
154
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
6.1.69. SWI
(Software Interrupt) genera un’interruzione software o SWI, che è gestita dal sistema
operativo.
SWI
Usare quest’istruzione come chiamata ad un servizio del sistema operativo per fornire un servizio.
Sintassi
SWI #<immed_8>
dove:
<immed_8>
È un valore di 8-bit inserito nei bits*7:0+ dell’istruzione. Questo valore è ignorato dal
processore, ma può essere usato da un gestore di SWI del sistema operativo per
capire quale servizio si sta richiedendo.
Versione architettura
Tutte le varianti T
Eccezioni
Software Interrupts
Operazione
R14_svc = address of next instruction after the SWI instruction
SPSR_svc = CPSR
CPSR[4:0] = 0b10011 /* Enter Supervisor mode */
CPSR[5] = 0 /* Execute in ARM state */
/* CPSR[6] is unchanged */
CPSR[7] = 1 /* Disable normal interrupts */
/* CPSR[8] is unchanged */
CPSR[9] = CP15_reg1_EEbit
if high vectors configured then
PC = 0xFFFF0008
else
PC = 0x00000008
Sintassi e codifica equivalente ARM
SWI #<immed_8>
155
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
6.1.70. SXTB
(Signed Extend Byte) estrae gli 8-bit meno significativi dell’operando e fa un’estensione di
segno a 32-bit.
SXTB
Non modifica i flags di stato.
Sintassi
SXTB <Rd>, <Rm>
dove:
<Rd> Specifica il registro di destinazione.
<Rm> Specifica il registro dell’operando.
Versione architettura
ARMv6 e superiori
Eccezioni
Nessuna
Operazione
Rd = SignExtend(Rm[7:0])
Uso
Usare SXTB per fare un’estensione di segno di un byte ad una parola, per esempio su sequenze di
istruzioni che lavorano su dati di tipo signed char in C/C++.
Sintassi e codifica equivalente ARM
SXTB <Rd>, <Rm>
156
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
6.1.71. SXTH
(Signed Extend Halfword) estrae i 16-bit meno significativi dell’operando e fa un’estensione di
segno a 32-bit.
SXTH
Non modifica i flags di stato.
Sintassi
SXTH <Rd>, <Rm>
dove:
<Rd> Specifica il registro di destinazione.
<Rm> Specifica il registro dell’operando.
Versione architettura
ARMv6 e superiori
Eccezioni
Nessuna
Operazione
Rd = SignExtend(Rm[15:0])
Uso
Usare SXTH per fare un’estensione di segno di una mezza parola ad una parola, per esempio su
sequenze di istruzioni che lavorano su dati di tipo signed short in C/C++.
Sintassi e codifica equivalente ARM
SXTH <Rd>, <Rm>
157
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
6.1.72. TST
(Test) determina se in un particolare sottoinsieme di bits in un registro è presente almeno un
bit ad settato ad 1. Un uso comune di TST è per testare se un singolo bit è settato ad 1 o a 0.
TST
Aggiorna i flags di stato, a seconda del risultato.
Sintassi
TST <Rn>, <Rm>
dove:
<Rn> Specifica il registro contenente il primo operando dell’operazione.
<Rm> È il valore con il quale si fa un AND Logico con il valore in <Rn>.
Versione architettura
Tutte le varianti T
Eccezioni
Nessuna
Operazione
alu_out = Rn AND Rm
N Flag = alu_out[31]
Z Flag = if alu_out == 0 then 1 else 0
C Flag = unaffected
V Flag = unaffected
Sintassi e codifica equivalente ARM
TST <Rn>, <Rm>
158
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
6.1.73. UXTB
(Unsigned Extend Byte) estrae gli 8-bit meno significativi dell’operando e fa un’estensione di
zeri a 32-bit.
UXTB
Non modifica i flags di stato.
Sintassi
UXTB <Rd>, <Rm>
dove:
<Rd> Specifica il registro di destinazione.
<Rm> Specifica il registro dell’operando.
Versione architettura
ARMv6 e superiori
Eccezioni
Nessuna
Operazione
Rd = Rm AND 0x000000ff
Uso
Usare UXTB per fare un’estensione di zeri di un byte ad una parola, per esempio su sequenze di
istruzioni che lavorano su dati di tipo unsigned char in C/C++.
Sintassi e codifica equivalente ARM
UXTB <Rd>, <Rm>
159
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
6.1.74. UXTH
(Unsigned Extend Halfword) estrae i 16-bit meno significativi dell’operando e fa
un’estensione di zeri a 32-bit.
UXTH
Non modifica i flags di stato.
Sintassi
UXTH <Rd>, <Rm>
dove:
<Rd> Specifica il registro di destinazione.
<Rm> Specifica il registro dell’operando.
Versione architettura
ARMv6 e superiori
Eccezioni
Nessuna
Operazione
Rd = Rm AND 0x0000ffff
Uso
Usare UXTH per fare un’estensione di zeri di una mezza parola ad una parola, per esempio su
sequenze di istruzioni che lavorano su dati di tipo unsigned short in C/C++.
Sintassi e codifica equivalente ARM
UXTH <Rd>, <Rm>
160
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
6.2. Istruzioni Thumb e versione architettura
La tabella mostra quali istruzioni sono presenti in ogni architettura ARM che supporta il Thumb.
Tabella 6.1 Istruzioni presenti nelle varie versioni dell’architettura
Istruzioni
v4T
v5T
v6
ADC
Si
Si
Si
ADD (tutte le forme)
Si
Si
Si
AND
Si
Si
Si
ASR (entrambe le forme)
Si
Si
Si
B (entrambe le forme)
Si
Si
Si
BIC
Si
Si
Si
BKPT
No
Si
Si
BL
Si
Si
Si
BLX (entrambe le forme)
No
Si
Si
BX
Si
Si
Si
CMN
Si
Si
Si
CMP (tutte le forme)
Si
Si
Si
CPS
No
No
Si
CPY
No
No
Si
EOR
Si
Si
Si
LDMIA
Si
Si
Si
LDR (tutte le forme)
Si
Si
Si
LDRB (entrambe le forme)
Si
Si
Si
LDRH (entrambe le forme)
Si
Si
Si
LDRSB
Si
Si
Si
LDRSH
Si
Si
Si
LSL (entrambe le forme)
Si
Si
Si
LSR (entrambe le forme)
Si
Si
Si
MOV (tutte le forme)
Si
Si
Si
MUL
Si
Si
Si
MVN
Si
Si
Si
NEG
Si
Si
Si
ORR
Si
Si
Si
POP
Si
Si
Si
PUSH
Si
Si
Si
REV (tutte le forme)
No
No
Si
ROR
Si
Si
Si
SBC
Si
Si
Si
SETEND
No
No
Si
STMIA
Si
Si
Si
STR (tutte le forme)
Si
Si
Si
STRB (entrambe le forme)
Si
Si
Si
STRH (entrambe le forme)
Si
Si
Si
SUB (tutte le forme)
Si
Si
Si
SWI
Si
Si
Si
SXTB/H
No
No
Si
TST
Si
Si
Si
UXTB/H
No
No
Si
161
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
7. Test
Finora sono state descritte le varie funzionalità dell’architettura ARM, la configurazione
dell’hardware disponibile e le istruzioni del set Thumb. Ora vediamo in che modo funziona questo
particolare set di istruzioni a 16 bit facendo dei test sul processore con dei semplici programmini.
7.1. Impostazioni test
Innanzitutto si ha un programma scritto in C. La scelta di questo linguaggio di programmazione è
quasi ovvia quando sappiamo che sulla scheda gira un sistema Linux debian e i programmi da
realizzare per i test sono davvero semplici.
Quindi si ha il codice C del programma, il quale viene compilato tramite il compilatore Sourcery
G++ Lite 2011.03-41 for ARM GNU/Linux , in ambiente Linux.
Il comando usato per compilare il codice è:
arm-none-linux-gnueabi-gdb [options] nome_file
specificando le opzioni:
-mthumb
specifica al compilatore che il set di istruzioni con cui compilare il
programma è il set Thumb (istruzioni a 16 bit)
-S
genera il file contenente il codice assembler invece che il binario eseguibile
-o output
specifica il nome del file di output
-O1, -O2, -O3
con queste opzioni si specificano le varie ottimizzazioni che il compilatore è
in grado di apportare al codice generato
Con queste opzioni il codice generato è di default per l’architettura ARMv5TE, proprio quella del
processore considerato.
Per quanto riguarda le ottimizzazioni, invece, queste sono le principali modifiche apportate dalla
prima ottimizzazione (-O1):
-
Aumento e decremento degli indirizzi combinati con gli accessi in memoria;
Fa un propagamento di copia per ridurre le dipendenze di scheduling prima e dopo
l’allocazione dei registri;
Esegue l’eliminazione di codice morto;
Usa l’esecuzione condizionata, dove possibile, per trasformare i salti condizionati in codice
equivalente senza salti;
Scopre quali funzioni sono pure e quali costanti;
Esegue l’eliminazione condizionata di codice morto per chiamate a funzioni di sistema.
La seconda ottimizzazione (-O2) apporta le modifiche della prima, in più fa anche le seguenti
operazioni:
-
Allinea l’inizio delle funzioni in memoria su indirizzi multipli di potenze di due;
Abilita l’allocazione dei valori sui registri che verranno usati dalle chiamate di funzione;
Esegue altre piccole ottimizzazioni su codice che può risultare pesante.
La terza ottimizzazione (-O3) fa tutto ciò che fanno la prima e la seconda, in più:
-
162
Integra tutte le funzioni semplici nei loro chiamanti;
Aumenta molto il codice cercando di eliminare il più possibile cicli e salti per rendere il
programma lineare.
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
Come si può notare le prime due ottimizzazioni tendono a ridurre il codice, mentre la terza lo
aumenta ma lo rende più lineare.
Dopo aver creato i file binari si eseguono dei test di velocità di esecuzione del programma sulla
cpu, tramite l’apposito comando Linux:
time ./nome_eseguibile
Questo comando può essere anteposto a qualsiasi altro comando per ottenere statistiche sul
tempo di esecuzione:
-
real: tempo trascorso dall’invocazione alla terminazione del comando;
user: tempo di CPU in user space;
sys: tempo di CPU in kernel space.
Vengono effettuate 10 prove per ogni codice e si calcolano i tempi medi. Dopodiché viene
realizzato un grafico della distribuzione gaussiana dei tempi per confrontare i vari test.
7.2. Programma test: Fattoriale
Questo semplice programma esegue il fattoriale di 100 numeri da 0 a 99 e scrive i risultati a
schermo.
7.2.1.
Codice C
Fattoriale.c
/----------------------------------------------------------------------------------------/
#include <stdio.h>
double factorial(double n) {
if (n == 0)
return 1;
return n * factorial (n - 1);
}
int main () {
int i;
double n;
for (i = 0; i < 100; ++i) {
n = factorial (i);
printf ("factorial(%d) = %.0e\n", i, n);
}
return 0;
}
/----------------------------------------------------------------------------------------/
163
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
7.2.2.
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
Codice Assembler
Di seguito i vari codici assembler ottenuti dal compilatore compilando il codice C precedente, con
le varie ottimizzazioni.
7.2.2.1.
Arm
.arch armv5te
.fpu softvfp
.eabi_attribute 20, 1
.eabi_attribute 21, 1
.eabi_attribute 23, 3
.eabi_attribute 24, 1
.eabi_attribute 25, 1
.eabi_attribute 26, 2
.eabi_attribute 30, 6
.eabi_attribute 18, 4
.file "main.c"
.global __aeabi_dcmpeq
.global __aeabi_dsub
.global __aeabi_dmul
.text
.align 2
.global factorial
.type factorial, %function
factorial:
.fnstart
.LFB0:
@ args = 0, pretend = 0, frame = 8
@ frame_needed = 1, uses_anonymous_args = 0
stmfd sp!, {fp, lr}
.save {fp, lr}
.setfp fp, sp, #4
add
fp, sp, #4
.pad #8
sub
sp, sp, #8
strd
r0, [fp, #-12]
ldrd
r0, [fp, #-12]
mov
r2, #0
mov
r3, #0
bl
__aeabi_dcmpeq
mov
r3, r0
cmp
r3, #0
beq
.L6
.L5:
mov
r2, #0
mov
r3, #1069547520
add
r3, r3, #3145728
b
.L4
.L6:
ldrd
r0, [fp, #-12]
mov
r2, #0
mov
r3, #1069547520
add
r3, r3, #3145728
bl
__aeabi_dsub
mov
r2, r0
mov
r3, r1
mov
r0, r2
mov
r1, r3
bl
factorial
mov
r2, r0
mov
r3, r1
mov
r0, r2
mov
r1, r3
ldrd
r2, [fp, #-12]
bl
__aeabi_dmul
mov
r2, r0
mov
r3, r1
.L4:
mov
r0, r2
mov
r1, r3
sub
sp, fp, #4
ldmfd sp!, {fp, pc}
.fnend
.size factorial, .-factorial
.global __aeabi_i2d
.section
.rodata
164
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
.align 2
.LC0:
.ascii "factorial(%d) = %.0e\012\000"
.text
.align 2
.global main
.type main, %function
main:
.fnstart
.LFB1:
@ args = 0, pretend = 0, frame = 16
@ frame_needed = 1, uses_anonymous_args = 0
stmfd sp!, {fp, lr}
.save {fp, lr}
.setfp fp, sp, #4
add
fp, sp, #4
.pad #16
sub
sp, sp, #16
mov
r3, #0
str
r3, [fp, #-8]
b
.L8
.L9:
ldr
bl
mov
mov
mov
mov
bl
strd
ldr
mov
ldr
ldrd
bl
ldr
add
str
r0, [fp, #-8]
__aeabi_i2d
r2, r0
r3, r1
r0, r2
r1, r3
factorial
r0, [fp, #-20]
r3, .L10
r0, r3
r1, [fp, #-8]
r2, [fp, #-20]
printf
r3, [fp, #-8]
r3, r3, #1
r3, [fp, #-8]
ldr
cmp
ble
mov
mov
sub
ldmfd
r3, [fp, #-8]
r3, #99
.L9
r3, #0
r0, r3
sp, fp, #4
sp!, {fp, pc}
.L8:
.L11:
.align 2
.L10:
.word .LC0
.fnend
.size main, .-main
.ident "GCC: (Sourcery G++ Lite 2011.03-41) 4.5.2"
.section
.note.GNU-stack,"",%progbits
7.2.2.2.
Thumb
.arch armv5te
.fpu softvfp
.eabi_attribute 20, 1
.eabi_attribute 21, 1
.eabi_attribute 23, 3
.eabi_attribute 24, 1
.eabi_attribute 25, 1
.eabi_attribute 26, 2
.eabi_attribute 30, 6
.eabi_attribute 18, 4
.code 16
//Specifica che si tratta di istr. a 16 bit, quindi di istr. Thumb
.file "main.c"
.global __aeabi_dcmpeq
.global __aeabi_dsub
.global __aeabi_dmul
.text
.align 2
.global factorial
.code 16
.thumb_func
.type factorial, %function
factorial:
165
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
.fnstart
.LFB0:
.save {r4, r7, lr}
push
{r4, r7, lr}
.pad #12
sub
sp, sp, #12
.setfp r7, sp, #0
add
r7, sp, #0
str
r0, [r7]
str
r1, [r7, #4]
ldr
r0, [r7]
ldr
r1, [r7, #4]
ldr
r3, .L7+4
ldr
r2, .L7
bl
__aeabi_dcmpeq
mov
r3, r0
cmp
r3, #0
beq
.L6
.L5:
ldr
ldr
b
r3, .L7+8
r4, .L7+12
.L4
ldr
ldr
ldr
ldr
bl
mov
mov
mov
mov
bl
mov
mov
mov
mov
ldr
ldr
bl
mov
mov
r0, [r7]
r1, [r7, #4]
r2, .L7+8
r3, .L7+12
__aeabi_dsub
r3, r0
r4, r1
r0, r3
r1, r4
factorial
r3, r0
r4, r1
r0, r3
r1, r4
r2, [r7]
r3, [r7, #4]
__aeabi_dmul
r3, r0
r4, r1
.L6:
Alcune righe sono del codice morto, registri caricati, spostati e salvati
inutilmente, queste righe vengono ridotte o eliminate nella prima
ottimizzazione.
.L4:
mov
r0, r3
mov
r1, r4
mov
sp, r7
add
sp, sp, #12
@ sp needed for prologue
pop
{r4, r7, pc}
.L8:
.align 3
.L7:
.word 0
.word 0
.word 0
.word 1072693248
.fnend
.size factorial, .-factorial
.global __aeabi_i2d
.section
.rodata
.align 2
.LC0:
.ascii "factorial(%d) = %.0e\012\000"
.text
.align 2
.global main
.code 16
.thumb_func
.type main, %function
main:
.fnstart
.LFB1:
.save {r4, r7, lr}
push
{r4, r7, lr}
.pad #20
sub
sp, sp, #20
.setfp r7, sp, #0
add
r7, sp, #0
mov
r3, #0
str
r3, [r7, #12]
166
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
b
.L10
ldr
bl
mov
mov
mov
mov
bl
mov
mov
str
str
ldr
ldr
ldr
ldr
mov
mov
mov
mov
bl
ldr
add
str
r0, [r7, #12]
__aeabi_i2d
r3, r0
r4, r1
r0, r3
r1, r4
factorial
r3, r0
r4, r1
r3, [r7]
r4, [r7, #4]
r1, .L12
r2, [r7, #12]
r3, [r7]
r4, [r7, #4]
r0, r1
r1, r2
r2, r3
r3, r4
printf
r3, [r7, #12]
r3, r3, #1
r3, [r7, #12]
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
.L11:
Alcune righe sono del codice morto, registri caricati, spostati e salvati
inutilmente, queste righe vengono ridotte o eliminate nella prima
ottimizzazione.
Le righe sottolineate vengono accorpate in un numero minore di istruzioni
dall’ottimizzazione –O1
.L10:
ldr
r3, [r7, #12]
cmp
r3, #99
ble
.L11
mov
r3, #0
mov
r0, r3
mov
sp, r7
add
sp, sp, #20
@ sp needed for prologue
pop
{r4, r7, pc}
.L13:
.align 2
.L12:
.word .LC0
.fnend
.size main, .-main
.ident "GCC: (Sourcery G++ Lite 2011.03-41) 4.5.2"
.section
.note.GNU-stack,"",%progbits
7.2.2.3.
Thumb con ottimizzazione –O1
.arch armv5te
.fpu softvfp
.eabi_attribute 20, 1
.eabi_attribute 21, 1
.eabi_attribute 23, 3
.eabi_attribute 24, 1
.eabi_attribute 25, 1
.eabi_attribute 26, 2
.eabi_attribute 30, 1
.eabi_attribute 18, 4
.code 16
//Specifica che si tratta di istr. a 16 bit, quindi di istr. Thumb
.file "main.c"
.global __aeabi_dcmpeq
.global __aeabi_dsub
.global __aeabi_dmul
.text
In questo caso la seconda ottimizzazione non cambia di molto il codice ottenuto
.align 2
con la prima, a parte il fatto che divide la parte .LFB11(del codice –O1) in due
.global factorial
.code 16
parti e aggiunge qualche riga di spostamenti dei registri
.thumb_func
.type factorial, %function
factorial:
.fnstart
.LFB11:
.save {r3, r4, r5, lr}
push
{r3, r4, r5, lr}
mov
r4, r0
mov
r5, r1
ldr
r3, .L4+4
ldr
r2, .L4
bl
__aeabi_dcmpeq
cmp
r0, #0
bne
.L3
167
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
mov
mov
ldr
ldr
bl
bl
mov
mov
bl
b
r0, r4
r1, r5
r2, .L4+8
r3, .L4+12
__aeabi_dsub
factorial
r2, r4
r3, r5
__aeabi_dmul
.L2
ldr
ldr
r0, .L4+8
r1, .L4+12
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
.L3:
.L2:
@ sp needed for prologue
pop
{r3, r4, r5, pc}
.L5:
.align 3
.L4:
.word 0
.word 0
.word 0
.word 1072693248
.fnend
.size factorial, .-factorial
.global __aeabi_i2d
.align 2
.global main
.code 16
.thumb_func
.type main, %function
main:
.fnstart
.LFB12:
.save
push
mov
ldr
{r3, r4, r5, lr}
{r3, r4, r5, lr}
r4, #0
r5, .L9
.L7:
mov
r0, r4
bl
__aeabi_i2d
bl
factorial
mov
r2, r0
mov
r3, r1
mov
r0, r5
mov
r1, r4
bl
printf
add
r4, r4, #1
cmp
r4, #100
bne
.L7
mov
r0, #0
@ sp needed for prologue
pop
{r3, r4, r5, pc}
.L10:
.align 2
.L9:
.word .LC0
.fnend
.size main, .-main
.section
.rodata.str1.4,"aMS",%progbits,1
.align 2
.LC0:
.ascii "factorial(%d) = %.0e\012\000"
.ident "GCC: (Sourcery G++ Lite 2011.03-41) 4.5.2"
.section
.note.GNU-stack,"",%progbits
7.2.2.4.
Thumb con ottimizzazione –O2
.arch armv5te
.fpu softvfp
.eabi_attribute
.eabi_attribute
.eabi_attribute
.eabi_attribute
.eabi_attribute
.eabi_attribute
.eabi_attribute
.eabi_attribute
.code 16
168
20,
21,
23,
24,
25,
26,
30,
18,
1
1
3
1
1
2
2
4
//Specifica che si tratta di istr. a 16 bit, quindi di istr. Thumb
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
.file "main.c"
.global __aeabi_dcmpeq
.global __aeabi_dsub
.global __aeabi_dmul
.text
.align 2
.global factorial
.code 16
.thumb_func
.type factorial, %function
factorial:
.fnstart
.LFB11:
.save {r3, r4, r5, lr}
push
{r3, r4, r5, lr}
ldr
r3, .L6+4
ldr
r2, .L6
mov
r4, r0
mov
r5, r1
bl
__aeabi_dcmpeq
cmp
r0, #0
beq
.L5
ldr
r0, .L6+8
ldr
r1, .L6+12
.L2:
@ sp needed for prologue
pop
{r3, r4, r5, pc}
.L5:
ldr
r2, .L6+8
ldr
r3, .L6+12
mov
r0, r4
mov
r1, r5
bl
__aeabi_dsub
bl
factorial
mov
r2, r4
mov
r3, r5
bl
__aeabi_dmul
b
.L2
.L7:
.align 3
.L6:
.word 0
.word 0
.word 0
.word 1072693248
.fnend
.size factorial, .-factorial
.global __aeabi_i2d
.align 2
.global main
.code 16
.thumb_func
.type main, %function
main:
.fnstart
.LFB12:
.save {r3, r4, r5, lr}
push
{r3, r4, r5, lr}
ldr
r5, .L12
mov
r4, #0
.L9:
mov
r0, r4
bl
__aeabi_i2d
bl
factorial
mov
r2, r0
mov
r3, r1
mov
r0, r5
mov
r1, r4
add
r4, r4, #1
bl
printf
mov
r0, r4
bl
__aeabi_i2d
bl
factorial
mov
r2, r0
mov
r3, r1
mov
r0, r5
mov
r1, r4
add
r4, r4, #1
bl
printf
cmp
r4, #100
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
Data la complessità del programma fattoriale, il quale è realizzato con la
chiamata ricorsiva della funzione fattoriale, la terza ottimizzazione non opera
tagli di codice sulla seconda, bensì aumenta di molto il codice per renderlo più
lineare; questa operazione può sembrare controproducente, ma andando ad
analizzare, più avanti, i tempi medi di esecuzione del programma si può notare
un miglioramento nel passaggio dalla seconda alla terza ottimizzazione.
169
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
bne
.L9
mov
r0, #0
@ sp needed for prologue
pop
{r3, r4, r5, pc}
.L13:
.align 2
.L12:
.word .LC0
.fnend
.size main, .-main
.section
.rodata.str1.4,"aMS",%progbits,1
.align 2
.LC0:
.ascii "factorial(%d) = %.0e\012\000"
.ident "GCC: (Sourcery G++ Lite 2011.03-41) 4.5.2"
.section
.note.GNU-stack,"",%progbits
7.2.2.5.
Thumb con ottimizzazione –O3
.arch armv5te
.fpu softvfp
.eabi_attribute 20, 1
.eabi_attribute 21, 1
.eabi_attribute 23, 3
.eabi_attribute 24, 1
.eabi_attribute 25, 1
.eabi_attribute 26, 2
.eabi_attribute 30, 2
.eabi_attribute 18, 4
.code 16
//Specifica che si tratta di istr. a 16 bit, quindi di istr. Thumb
.file "main.c"
.global __aeabi_dcmpeq
.global __aeabi_dsub
.global __aeabi_dmul
.text
.align 2
.global factorial
.code 16
.thumb_func
.type factorial, %function
factorial:
.fnstart
.LFB11:
.save {r4, r5, r6, r7, lr}
push
{r4, r5, r6, r7, lr}
.pad #60
sub
sp, sp, #60
ldr
r3, .L30+4
ldr
r2, .L30
mov
r4, r0
mov
r5, r1
bl
__aeabi_dcmpeq
cmp
r0, #0
beq
.L21
ldr
r0, .L30+8
ldr
r1, .L30+12
.L2:
add
sp, sp, #60
@ sp needed for prologue
pop
{r4, r5, r6, r7, pc}
.L21:
ldr
r2, .L30+8
ldr
r3, .L30+12
mov
r0, r4
mov
r1, r5
bl
__aeabi_dsub
ldr
r3, .L30+4
ldr
r2, .L30
mov
r6, r0
mov
r7, r1
bl
__aeabi_dcmpeq
cmp
r0, #0
beq
.L22
ldr
r2, .L30+8
ldr
r3, .L30+12
.L3:
mov
r0, r4
mov
r1, r5
bl
__aeabi_dmul
170
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
b
.L2
ldr
ldr
mov
mov
bl
ldr
ldr
str
str
bl
cmp
beq
ldr
ldr
r2, .L30+8
r3, .L30+12
r0, r6
r1, r7
__aeabi_dsub
r3, .L30+4
r2, .L30
r0, [sp]
r1, [sp, #4]
__aeabi_dcmpeq
r0, #0
.L23
r2, .L30+8
r3, .L30+12
mov
mov
bl
mov
mov
b
r0, r6
r1, r7
__aeabi_dmul
r2, r0
r3, r1
.L3
ldr
ldr
ldr
ldr
bl
ldr
ldr
str
str
bl
cmp
beq
ldr
ldr
r2, .L30+8
r3, .L30+12
r0, [sp]
r1, [sp, #4]
__aeabi_dsub
r3, .L30+4
r2, .L30
r0, [sp, #8]
r1, [sp, #12]
__aeabi_dcmpeq
r0, #0
.L24
r2, .L30+8
r3, .L30+12
ldr
ldr
bl
mov
mov
b
r0, [sp]
r1, [sp, #4]
__aeabi_dmul
r2, r0
r3, r1
.L4
ldr
ldr
ldr
ldr
bl
ldr
ldr
str
str
bl
cmp
beq
ldr
ldr
r2, .L30+8
r3, .L30+12
r0, [sp, #8]
r1, [sp, #12]
__aeabi_dsub
r3, .L30+4
r2, .L30
r0, [sp, #16]
r1, [sp, #20]
__aeabi_dcmpeq
r0, #0
.L25
r2, .L30+8
r3, .L30+12
ldr
ldr
bl
mov
mov
b
r0, [sp, #8]
r1, [sp, #12]
__aeabi_dmul
r2, r0
r3, r1
.L5
ldr
ldr
ldr
ldr
bl
ldr
ldr
str
str
bl
cmp
beq
r2, .L30+8
r3, .L30+12
r0, [sp, #16]
r1, [sp, #20]
__aeabi_dsub
r3, .L30+4
r2, .L30
r0, [sp, #24]
r1, [sp, #28]
__aeabi_dcmpeq
r0, #0
.L26
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
.L22:
.L4:
.L23:
.L5:
.L24:
.L6:
.L25:
171
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
ldr
ldr
r2, .L30+8
r3, .L30+12
ldr
ldr
bl
mov
mov
b
r0, [sp, #16]
r1, [sp, #20]
__aeabi_dmul
r2, r0
r3, r1
.L6
ldr
ldr
ldr
ldr
bl
ldr
ldr
str
str
bl
cmp
beq
ldr
ldr
r2, .L30+8
r3, .L30+12
r0, [sp, #24]
r1, [sp, #28]
__aeabi_dsub
r3, .L30+4
r2, .L30
r0, [sp, #32]
r1, [sp, #36]
__aeabi_dcmpeq
r0, #0
.L27
r2, .L30+8
r3, .L30+12
ldr
ldr
bl
mov
mov
b
r0, [sp, #24]
r1, [sp, #28]
__aeabi_dmul
r2, r0
r3, r1
.L7
ldr
ldr
ldr
ldr
bl
ldr
ldr
str
str
bl
cmp
beq
ldr
ldr
r2, .L30+8
r3, .L30+12
r0, [sp, #32]
r1, [sp, #36]
__aeabi_dsub
r3, .L30+4
r2, .L30
r0, [sp, #40]
r1, [sp, #44]
__aeabi_dcmpeq
r0, #0
.L28
r2, .L30+8
r3, .L30+12
ldr
ldr
bl
mov
mov
b
r0, [sp, #32]
r1, [sp, #36]
__aeabi_dmul
r2, r0
r3, r1
.L8
ldr
ldr
ldr
ldr
bl
ldr
ldr
str
str
bl
cmp
beq
ldr
ldr
r2, .L30+8
r3, .L30+12
r0, [sp, #40]
r1, [sp, #44]
__aeabi_dsub
r3, .L30+4
r2, .L30
r0, [sp, #48]
r1, [sp, #52]
__aeabi_dcmpeq
r0, #0
.L29
r2, .L30+8
r3, .L30+12
ldr
ldr
bl
mov
mov
b
r0, [sp, #40]
r1, [sp, #44]
__aeabi_dmul
r2, r0
r3, r1
.L9
ldr
ldr
ldr
ldr
r2,
r3,
r0,
r1,
.L7:
.L26:
.L8:
.L27:
.L9:
.L28:
.L10:
.L29:
172
.L30+8
.L30+12
[sp, #48]
[sp, #52]
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
bl
bl
mov
mov
ldr
ldr
bl
mov
mov
b
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
__aeabi_dsub
factorial
r2, r0
r3, r1
r0, [sp, #48]
r1, [sp, #52]
__aeabi_dmul
r2, r0
r3, r1
.L10
.L31:
.align 3
.L30:
.word 0
.word 0
.word 0
.word 1072693248
.fnend
.size factorial, .-factorial
.global __aeabi_i2d
.align 2
.global main
.code 16
.thumb_func
.type main, %function
main:
.fnstart
.LFB12:
.save
push
mov
.save
push
ldr
ldr
ldr
mov
mov
mov
ldr
ldr
bl
mov
mov
mov
mov
bl
bl
mov
mov
mov
mov
mov
bl
ldr
ldr
mov
mov
mov
mov
bl
ldr
ldr
mov
mov
bl
bl
mov
mov
mov
mov
bl
ldr
ldr
mov
mov
mov
mov
bl
{r4, r5, r6, r7, lr}
{r4, r5, r6, r7, lr}
r7, r8
{r8}
{r7}
r3, .L58+32
r5, .L58+4
r4, .L58
r8, r3
r0, r3
r1, #0
r3, .L58+4
r2, .L58
printf
r2, r4
r3, r5
r0, r4
r1, r5
__aeabi_dsub
factorial
r6, #3
r2, r0
r3, r1
r0, r4
r1, r5
__aeabi_dmul
r4, .L58+8
r5, .L58+12
r2, r0
r3, r1
r0, r8
r1, #1
printf
r3, .L58+4
r2, .L58
r0, r4
r1, r5
__aeabi_dsub
factorial
r2, r0
r3, r1
r0, r4
r1, r5
__aeabi_dmul
r4, .L58+16
r5, .L58+20
r2, r0
r3, r1
r0, r8
r1, #2
printf
.L55:
173
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
ldr
ldr
mov
mov
bl
bl
mov
mov
mov
mov
bl
mov
mov
mov
mov
add
bl
cmp
beq
r3, .L58+4
r2, .L58
r0, r4
r1, r5
__aeabi_dsub
factorial
r2, r0
r3, r1
r0, r4
r1, r5
__aeabi_dmul
r2, r0
r3, r1
r0, r8
r1, r6
r6, r6, #1
printf
r6, #100
.L56
mov
bl
ldr
ldr
mov
mov
bl
cmp
beq
ldr
ldr
r0, r6
__aeabi_i2d
r2, .L58+24
r3, .L58+28
r4, r0
r5, r1
__aeabi_dcmpeq
r0, #0
.L57
r3, .L58+4
r2, .L58
mov
mov
add
bl
mov
bl
ldr
ldr
mov
mov
bl
cmp
beq
ldr
ldr
r1, r6
r0, r8
r7, r6, #1
printf
r0, r7
__aeabi_i2d
r2, .L58+24
r3, .L58+28
r4, r0
r5, r1
__aeabi_dcmpeq
r0, #0
.L51
r3, .L58+4
r2, .L58
mov
mov
add
bl
mov
bl
ldr
ldr
mov
mov
bl
cmp
beq
ldr
ldr
r1, r7
r0, r8
r7, r6, #2
printf
r0, r7
__aeabi_i2d
r2, .L58+24
r3, .L58+28
r4, r0
r5, r1
__aeabi_dcmpeq
r0, #0
.L53
r3, .L58+4
r2, .L58
mov
mov
add
bl
mov
bl
ldr
ldr
mov
mov
bl
cmp
beq
mov
ldr
ldr
r1, r7
r0, r8
r6, r6, #3
printf
r0, r6
__aeabi_i2d
r2, .L58+24
r3, .L58+28
r4, r0
r5, r1
__aeabi_dcmpeq
r0, #0
.L55
r1, r6
r3, .L58+4
r2, .L58
.L35:
.L50:
.L52:
.L54:
174
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
mov
add
bl
cmp
bne
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
r0, r8
r6, r6, #1
printf
r6, #100
.L35
.L56:
mov
r0, #0
@ sp needed for prologue
pop
{r2}
mov
r8, r2
pop
{r4, r5, r6, r7, pc}
.L57:
ldr
ldr
mov
mov
bl
bl
mov
mov
mov
mov
bl
mov
mov
b
r3, .L58+4
r2, .L58
r0, r4
r1, r5
__aeabi_dsub
factorial
r2, r0
r3, r1
r0, r4
r1, r5
__aeabi_dmul
r2, r0
r3, r1
.L50
ldr
ldr
mov
mov
bl
bl
mov
mov
mov
mov
bl
mov
mov
b
r3, .L58+4
r2, .L58
r0, r4
r1, r5
__aeabi_dsub
factorial
r2, r0
r3, r1
r0, r4
r1, r5
__aeabi_dmul
r2, r0
r3, r1
.L54
ldr
ldr
mov
mov
bl
bl
mov
mov
mov
mov
bl
mov
mov
b
r3, .L58+4
r2, .L58
r0, r4
r1, r5
__aeabi_dsub
factorial
r2, r0
r3, r1
r0, r4
r1, r5
__aeabi_dmul
r2, r0
r3, r1
.L52
.L53:
.L51:
.L59:
.align 3
.L58:
.word 0
.word 1072693248
.word 0
.word 1073741824
.word 0
.word 1074266112
.word 0
.word 0
.word .LC0
.fnend
.size main, .-main
.section
.rodata.str1.4,"aMS",%progbits,1
.align 2
.LC0:
.ascii "factorial(%d) = %.0e\012\000"
.ident "GCC: (Sourcery G++ Lite 2011.03-41) 4.5.2"
.section
.note.GNU-stack,"",%progbits
175
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
7.2.3.
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
Tempi di esecuzione
I file binari ottenuti dai codici precedenti, sono stati eseguiti sul processore, ed hanno dato i
seguenti risultati per quanto riguarda i tempi di esecuzione:
Tabella 7.1 Tempi di esecuzione del programma Fattoriale (tempi in ms)
Prova
1
2
3
4
5
6
7
8
9
10
176
arm
real
user
sys
real
user
sys
real
user
sys
real
user
sys
real
user
sys
real
user
sys
real
user
sys
real
user
sys
real
user
sys
real
user
sys
254
60
90
250
80
80
259
90
70
251
50
110
241
80
80
255
70
80
261
80
70
272
110
60
256
80
70
261
70
90
real
user
sys
256
77
80
Codifica e ottimizzazioni
thumb thumb_O1 thumb_O2 thumb_O3
268
258
246
259
70
90
80
90
100
60
80
70
280
258
253
252
70
90
90
90
90
70
60
60
287
259
253
252
90
80
70
60
80
80
90
100
262
272
245
256
40
60
90
70
120
110
60
80
271
253
262
246
90
60
70
70
70
90
90
90
280
262
256
261
120
100
90
80
50
50
60
70
257
256
262
255
90
70
70
90
70
90
100
70
271
261
254
238
100
100
70
90
70
50
80
60
262
260
260
247
90
80
90
80
70
80
80
70
259
260
256
251
100
100
100
60
60
50
50
100
Tempi medi
269,7
259,9
254,7
251,7
86
83
82
78
78
73
75
77
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
Figura 7.1 Grafico della distribuzione gaussiana dei tempi di esecuzione(real) rilevati.
1200
1000
Frequenza
800
ARM
Thumb
600
Thumb_O1
Thumb_O2
400
Thumb_O3
200
0
200
220
240
260
280
300
320
340
Tempi [ms]
Come si può vedere dal grafico le distribuzioni hanno una varianza abbastanza bassa, quindi i
risultati si possono considerare piuttosto attendibili.
Dai tempi medi:
-
Arm:
Thumb:
Thumb_O1:
Thumb_O2:
Thumb_O3:
256
269,7
259,9
254,7
251,7
ms
ms
ms
ms
ms
si può notare che il programma in Arm viene eseguito in tempi minori di quello in Thumb.
Adottando le varie ottimizzazioni il tempo di esecuzione scende. Il tempo più basso si ha con la
terza ottimizzazione nonostante sia quella che crea un codice di volume maggiore.
177
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
7.3. Programma test: Fattori primi
Questo programma ricava i fattori primi di un numero dato in input. Per questo test ho scelto il
numero “222881507” come input in tutti i casi.
7.3.1.
Codice C
/----------------------------------------------------------------------------------------/
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char* argv[]) {
int n, d = 2;
n = atoi(argv[1]);
if (n < 1)
return 0;
printf ("\nScomposizione in fattori primi di %d:\n", n);
if(n == 1)
printf ("1\n");
while (n != 1) {
if ((n % d) == 0) {
printf ("%d\n", d);
n /= d;
}
else {
d++;
}
}
return 0;
}
/----------------------------------------------------------------------------------------/
178
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
7.3.2.
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
Codice Assembler
Di seguito i vari codici assembler ottenuti dal compilatore compilando il codice C precedente, con
le varie ottimizzazioni.
7.3.2.1.
Arm
.arch armv5te
.fpu softvfp
.eabi_attribute 20, 1
.eabi_attribute 21, 1
.eabi_attribute 23, 3
.eabi_attribute 24, 1
.eabi_attribute 25, 1
.eabi_attribute 26, 2
.eabi_attribute 30, 6
.eabi_attribute 18, 4
.file "fatt_primi.c"
.section
.rodata
.align 2
.LC0:
.ascii "\012Scomposizione in fattori primi di %d:\012\000"
.align 2
.LC1:
.ascii "1\000"
.global __aeabi_idivmod
.align 2
.LC2:
.ascii "%d\012\000"
.global __aeabi_idiv
.text
.align 2
.global main
.type main, %function
main:
.fnstart
.LFB0:
@ args = 0, pretend = 0, frame = 16
@ frame_needed = 1, uses_anonymous_args = 0
stmfd sp!, {fp, lr}
.save {fp, lr}
.setfp fp, sp, #4
add
fp, sp, #4
.pad #16
sub
sp, sp, #16
str
r0, [fp, #-16]
str
r1, [fp, #-20]
mov
r3, #2
str
r3, [fp, #-12]
ldr
r3, [fp, #-20]
add
r3, r3, #4
ldr
r3, [r3, #0]
mov
r0, r3
bl
atoi
str
r0, [fp, #-8]
ldr
r3, [fp, #-8]
cmp
r3, #0
bgt
.L2
mov
r3, #0
b
.L3
.L2:
ldr
mov
ldr
bl
ldr
cmp
bne
ldr
bl
b
r3, .L8
r0, r3
r1, [fp, #-8]
printf
r3, [fp, #-8]
r3, #1
.L5
r0, .L8+4
puts
.L5
ldr
mov
ldr
bl
mov
r3, [fp, #-8]
r0, r3
r1, [fp, #-12]
__aeabi_idivmod
r3, r1
.L7:
179
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
cmp
bne
ldr
mov
ldr
bl
ldr
ldr
bl
mov
str
b
r3, #0
.L6
r3, .L8+8
r0, r3
r1, [fp, #-12]
printf
r0, [fp, #-8]
r1, [fp, #-12]
__aeabi_idiv
r3, r0
r3, [fp, #-8]
.L5
ldr
add
str
r3, [fp, #-12]
r3, r3, #1
r3, [fp, #-12]
ldr
cmp
bne
mov
r3, [fp, #-8]
r3, #1
.L7
r3, #0
mov
sub
ldmfd
r0, r3
sp, fp, #4
sp!, {fp, pc}
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
.L6:
.L5:
.L3:
.L9:
.align 2
.L8:
.word .LC0
.word .LC1
.word .LC2
.fnend
.size main, .-main
.ident "GCC: (Sourcery G++ Lite 2011.03-41) 4.5.2"
.section
.note.GNU-stack,"",%progbits
7.3.2.2.
Thumb
.arch armv5te
.fpu softvfp
.eabi_attribute 20, 1
.eabi_attribute 21, 1
.eabi_attribute 23, 3
.eabi_attribute 24, 1
.eabi_attribute 25, 1
.eabi_attribute 26, 2
.eabi_attribute 30, 6
.eabi_attribute 18, 4
.code 16
//Specifica che si tratta di istr. a 16 bit, quindi di istr. Thumb
.file "fatt_primi.c"
.section
.rodata
.align 2
.LC0:
.ascii "\012Scomposizione in fattori primi di %d:\012\000"
.align 2
.LC2:
.ascii "1\000"
.global __aeabi_idivmod
.align 2
.LC4:
.ascii "%d\012\000"
.global __aeabi_idiv
.text
.align 2
.global main
.code 16
.thumb_func
.type main, %function
main:
.fnstart
.LFB0:
.save {r7, lr}
push
{r7, lr}
.pad #16
sub
sp, sp, #16
.setfp r7, sp, #0
add
r7, sp, #0
str
r0, [r7, #4]
180
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
str
mov
str
ldr
add
ldr
mov
bl
mov
str
ldr
cmp
bgt
mov
b
r1, [r7]
r3, #2
r3, [r7, #8]
r3, [r7]
r3, r3, #4
r3, [r3]
r0, r3
atoi
r3, r0
r3, [r7, #12]
r3, [r7, #12]
r3, #0
.L2
r3, #0
.L3
ldr
ldr
mov
mov
bl
ldr
cmp
bne
ldr
mov
bl
b
r2, .L8
r3, [r7, #12]
r0, r2
r1, r3
printf
r3, [r7, #12]
r3, #1
.L5
r3, .L8+4
r0, r3
puts
.L5
ldr
mov
ldr
bl
mov
cmp
bne
ldr
ldr
mov
mov
bl
ldr
ldr
bl
mov
str
b
r3, [r7, #12]
r0, r3
r1, [r7, #8]
__aeabi_idivmod
r3, r1
r3, #0
.L6
r2, .L8+8
r3, [r7, #8]
r0, r2
r1, r3
printf
r0, [r7, #12]
r1, [r7, #8]
__aeabi_idiv
r3, r0
r3, [r7, #12]
.L5
ldr
add
str
r3, [r7, #8]
r3, r3, #1
r3, [r7, #8]
ldr
cmp
bne
mov
r3, [r7, #12]
r3, #1
.L7
r3, #0
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
Alcune righe sono del codice morto, registri caricati, spostati e salvati
inutilmente, queste righe vengono ridotte nella prima ottimizzazione.
.L2:
Questo codice morto, è un doppio caricamento inutile.
.L7:
.L6:
.L5:
Ci sono 2 righe di codice morto, si può notare che si sposta un dato e lo si salva,
invece di salvarlo direttamente. Altre istruzioni vengono accorpate, infatti nella
ottimizzazione –O1 i registri sono già caricati e si effettuano meno accessi in
memoria.
Queste righe sono del codice morto in quanto prima caricano un dato e poi lo
salvano nella stessa posizione, vengono quindi eliminate con la prima
ottimizzazione
.L3:
mov
r0, r3
mov
sp, r7
add
sp, sp, #16
@ sp needed for prologue
pop
{r7, pc}
.L9:
.align 2
.L8:
.word .LC0
.word .LC2
.word .LC4
.fnend
.size main, .-main
.ident "GCC: (Sourcery G++ Lite 2011.03-41) 4.5.2"
.section
.note.GNU-stack,"",%progbits
181
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
7.3.2.3.
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
Thumb con ottimizzazione –O1
.arch armv5te
.fpu softvfp
.eabi_attribute 20, 1
.eabi_attribute 21, 1
.eabi_attribute 23, 3
.eabi_attribute 24, 1
.eabi_attribute 25, 1
.eabi_attribute 26, 2
.eabi_attribute 30, 1
.eabi_attribute 18, 4
.code 16
//Specifica che si tratta di istr. a 16 bit, quindi di istr. Thumb
.file "fatt_primi.c"
.global __aeabi_idivmod
.global __aeabi_idiv
.text
.align 2
.global main
.code 16
.thumb_func
.type main, %function
main:
.fnstart
.LFB18:
.save
push
ldr
mov
mov
bl
mov
cmp
ble
ldr
mov
bl
mov
cmp
bne
ldr
bl
b
{r4, r5, r6, lr}
{r4, r5, r6, lr}
r0, [r1, #4]
r1, #0
r2, #10
strtol
r5, r0
r0, #0
.L2
r0, .L9
r1, r5
printf
r4, #2
r5, #1
.L3
r0, .L9+4
puts
.L2
ldr
r6, .L9+8
mov
mov
bl
cmp
bne
mov
mov
bl
mov
mov
bl
mov
b
r0, r5
r1, r4
__aeabi_idivmod
r1, #0
.L4
r0, r6
r1, r4
printf
r0, r5
r1, r4
__aeabi_idiv
r5, r0
.L5
add
r4, r4, #1
cmp
bne
r5, #1
.L7
Queste due righe che fanno un confronto vengono sostituite da un’unica
istruzione nella seconda ottimizzazione.
.L3:
.L7:
.L4:
.L5:
Queste due righe vengono accorpate in .L7 nella seconda ottimizzazione.
.L2:
mov
r0, #0
@ sp needed for prologue
pop
{r4, r5, r6, pc}
.L10:
.align 2
.L9:
.word .LC0
.word .LC2
.word .LC4
.fnend
.size main, .-main
.section
.rodata.str1.4,"aMS",%progbits,1
.align 2
.LC0:
182
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
.ascii "\012Scomposizione in fattori primi di %d:\012\000"
.LC2:
.ascii "1\000"
.space 2
.LC4:
.ascii "%d\012\000"
.ident "GCC: (Sourcery G++ Lite 2011.03-41) 4.5.2"
.section
.note.GNU-stack,"",%progbits
7.3.2.4.
Thumb con ottimizzazione –O2
.arch armv5te
.fpu softvfp
.eabi_attribute 20, 1
.eabi_attribute 21, 1
.eabi_attribute 23, 3
.eabi_attribute 24, 1
.eabi_attribute 25, 1
.eabi_attribute 26, 2
.eabi_attribute 30, 2
.eabi_attribute 18, 4
.code 16
//Specifica che si tratta di istr. a 16 bit, quindi di istr. Thumb
.file "fatt_primi.c"
.global __aeabi_idivmod
.global __aeabi_idiv
.text
.align 2
.global main
.code 16
.thumb_func
.type main, %function
main:
.fnstart
.LFB18:
.save
push
ldr
mov
mov
bl
sub
ble
ldr
mov
bl
mov
cmp
beq
ldr
b
{r4, r5, r6, lr}
{r4, r5, r6, lr}
r0, [r1, #4]
r2, #10
r1, #0
strtol
r5, r0, #0
.L2
r0, .L11
r1, r5
printf
r4, #2
r5, #1
.L10
r6, .L11+4
.L7
add
cmp
beq
r4, r4, #1
r5, #1
.L2
mov
mov
bl
cmp
bne
mov
mov
bl
mov
mov
bl
mov
cmp
bne
r0, r5
r1, r4
__aeabi_idivmod
r1, #0
.L4
r1, r4
r0, r6
printf
r0, r5
r1, r4
__aeabi_idiv
r5, r0
r5, #1
.L7
Il codice prodotto dalla terza ottimizzazione è uguale a quello prodotto dalla
seconda ottimizzazione, non ci sono quindi cambiamenti importanti da
evidenziare. Si vedrà infatti più avanti che i tempi di esecuzione tra questi due
codici sono praticamente identici.
.L4:
.L7:
.L2:
mov
r0, #0
@ sp needed for prologue
pop
{r4, r5, r6, pc}
.L10:
ldr
bl
b
r0, .L11+8
puts
.L2
.L12:
.align 2
183
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
.L11:
.word .LC0
.word .LC4
.word .LC2
.fnend
.size main, .-main
.section
.rodata.str1.4,"aMS",%progbits,1
.align 2
.LC0:
.ascii "\012Scomposizione in fattori primi di %d:\012\000"
.LC2:
.ascii "1\000"
.space 2
.LC4:
.ascii "%d\012\000"
.ident "GCC: (Sourcery G++ Lite 2011.03-41) 4.5.2"
.section
.note.GNU-stack,"",%progbits
7.3.2.5.
Thumb con ottimizzazione –O3
.arch armv5te
.fpu softvfp
.eabi_attribute 20, 1
.eabi_attribute 21, 1
.eabi_attribute 23, 3
.eabi_attribute 24, 1
.eabi_attribute 25, 1
.eabi_attribute 26, 2
.eabi_attribute 30, 2
.eabi_attribute 18, 4
.code 16
//Specifica che si tratta di istr. a 16 bit, quindi di istr. Thumb
.file "fatt_primi.c"
.global __aeabi_idivmod
.global __aeabi_idiv
.text
.align 2
.global main
.code 16
.thumb_func
.type main, %function
main:
.fnstart
.LFB18:
.save
push
ldr
mov
mov
bl
sub
ble
ldr
mov
bl
mov
cmp
beq
ldr
b
{r4, r5, r6, lr}
{r4, r5, r6, lr}
r0, [r1, #4]
r2, #10
r1, #0
strtol
r5, r0, #0
.L2
r0, .L11
r1, r5
printf
r4, #2
r5, #1
.L10
r6, .L11+4
.L7
add
cmp
beq
r4, r4, #1
r5, #1
.L2
mov
mov
bl
cmp
bne
mov
mov
bl
mov
mov
bl
mov
cmp
bne
r0, r5
r1, r4
__aeabi_idivmod
r1, #0
.L4
r1, r4
r0, r6
printf
r0, r5
r1, r4
__aeabi_idiv
r5, r0
r5, #1
.L7
.L4:
.L7:
.L2:
184
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
mov
r0, #0
@ sp needed for prologue
pop
{r4, r5, r6, pc}
.L10:
ldr
bl
b
r0, .L11+8
puts
.L2
.L12:
.align 2
.L11:
.word .LC0
.word .LC4
.word .LC2
.fnend
.size main, .-main
.section
.rodata.str1.4,"aMS",%progbits,1
.align 2
.LC0:
.ascii "\012Scomposizione in fattori primi di %d:\012\000"
.LC2:
.ascii "1\000"
.space 2
.LC4:
.ascii "%d\012\000"
.ident "GCC: (Sourcery G++ Lite 2011.03-41) 4.5.2"
.section
.note.GNU-stack,"",%progbits
185
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
7.3.3.
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
Tempi di esecuzione
I file binari ottenuti dai codici precedenti, sono stati eseguiti sul processore, ed hanno dato i
seguenti risultati per quanto riguarda i tempi di esecuzione:
Tabella 7.2 Tempi di esecuzione del programma Fattori Primi (tempi in ms)
Prova
1
2
3
4
5
6
7
8
9
10
186
real
user
sys
real
user
sys
real
user
sys
real
user
sys
real
user
sys
real
user
sys
real
user
sys
real
user
sys
real
user
sys
real
user
sys
arm
450
370
50
443
360
50
448
340
70
457
360
60
440
370
50
441
370
50
439
340
70
441
340
70
442
360
60
435
350
60
real
user
sys
443,6
356
59
Codifica e ottimizzazioni
thumb thumb_1 thumb_2 thumb_3
457
435
428
422
400
340
340
330
30
50
50
60
460
430
417
417
360
330
320
340
60
70
70
50
452
425
422
429
380
320
320
360
40
70
80
40
455
427
421
416
380
320
350
360
40
70
50
40
455
421
425
419
390
330
370
350
40
70
30
50
462
428
420
422
370
340
320
360
60
60
70
40
461
420
427
424
380
330
330
340
40
70
60
60
452
428
426
427
360
340
320
320
60
60
70
70
452
425
421
425
370
340
350
350
60
50
50
40
467
423
416
425
370
350
330
360
60
40
70
30
Tempi medi
457,3
426,2
422,3
422,6
376
334
335
347
49
61
60
48
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
Figura 7.2 Grafico della distribuzione gaussiana dei tempi di esecuzione(real) rilevati.
1200
1000
Frequenza
800
Arm
Thumb
600
Thumb_O1
Thumb_O2
400
Thumb_O3
200
0
350
400
450
500
550
Tempi [ms]
Come si può vedere dal grafico le distribuzioni hanno una varianza abbastanza bassa, quindi i
risultati si possono considerare piuttosto attendibili.
Dai tempi medi:
-
Arm:
Thumb:
Thumb_O1:
Thumb_O2:
Thumb_O3:
443,6
457,3
426,2
422,3
422,6
ms
ms
ms
ms
ms
si può notare che il programma in Arm viene eseguito in tempi minori di quello in Thumb.
Adottando le varie ottimizzazioni il tempo di esecuzione scende. Il tempo più basso si ha con la
seconda ottimizzazione che è molto vicino a quello della terza.
187
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
7.4. Programma test: Serie di Fibonacci
Questo programma stampa a video la serie di Fibonacci dei numeri da 0 a 40.
7.4.1.
Codice C
/----------------------------------------------------------------------------------------/
#include <stdio.h>
int main() {
int x, y = 1, z = 0, i;
printf("\nSerie di Fibonacci dei primi 40 numeri:\n");
printf("F(0) = 0\nF(1) = 1\n");
for (i = 2; i < 41; i++) {
x = y + z;
printf("F(%d) = %d\n", i, x);
z = y;
y = x;
}
return 0;
}
/----------------------------------------------------------------------------------------/
7.4.2.
Codice Assembler
Di seguito i vari codici assembler ottenuti dal compilatore compilando il codice C precedente, con
le varie ottimizzazioni.
7.4.2.1.
Arm
.arch armv5te
.fpu softvfp
.eabi_attribute 20, 1
.eabi_attribute 21, 1
.eabi_attribute 23, 3
.eabi_attribute 24, 1
.eabi_attribute 25, 1
.eabi_attribute 26, 2
.eabi_attribute 30, 6
.eabi_attribute 18, 4
.file "fibonacci.c"
.section
.rodata
.align 2
.LC0:
.ascii "\012Serie di Fibonacci dei primi 40 numeri:\000"
.align 2
.LC1:
.ascii "F(0) = 0\012F(1) = 1\000"
.align 2
.LC2:
.ascii "F(%d) = %d\012\000"
.text
.align 2
.global main
.type main, %function
main:
.fnstart
188
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
.LFB0:
@ args = 0, pretend = 0, frame = 16
@ frame_needed = 1, uses_anonymous_args = 0
stmfd sp!, {fp, lr}
.save {fp, lr}
.setfp fp, sp, #4
add
fp, sp, #4
.pad #16
sub
sp, sp, #16
mov
r3, #1
str
r3, [fp, #-8]
mov
r3, #0
str
r3, [fp, #-12]
ldr
r0, .L4
bl
puts
ldr
r0, .L4+4
bl
puts
mov
r3, #2
str
r3, [fp, #-16]
b
.L2
.L3:
ldr
ldr
add
str
ldr
mov
ldr
ldr
bl
ldr
str
ldr
str
ldr
add
str
r2, [fp, #-8]
r3, [fp, #-12]
r3, r2, r3
r3, [fp, #-20]
r3, .L4+8
r0, r3
r1, [fp, #-16]
r2, [fp, #-20]
printf
r3, [fp, #-8]
r3, [fp, #-12]
r3, [fp, #-20]
r3, [fp, #-8]
r3, [fp, #-16]
r3, r3, #1
r3, [fp, #-16]
ldr
cmp
ble
mov
mov
sub
ldmfd
r3, [fp, #-16]
r3, #40
.L3
r3, #0
r0, r3
sp, fp, #4
sp!, {fp, pc}
.L2:
.L5:
.align 2
.L4:
.word .LC0
.word .LC1
.word .LC2
.fnend
.size main, .-main
.ident "GCC: (Sourcery G++ Lite 2011.03-41) 4.5.2"
.section
.note.GNU-stack,"",%progbits
7.4.2.2.
Thumb
.arch armv5te
.fpu softvfp
.eabi_attribute 20, 1
.eabi_attribute 21, 1
.eabi_attribute 23, 3
.eabi_attribute 24, 1
.eabi_attribute 25, 1
.eabi_attribute 26, 2
.eabi_attribute 30, 6
.eabi_attribute 18, 4
.code 16
//Specifica che si tratta di istr. a 16 bit, quindi di istr. Thumb
.file "fibonacci.c"
.section
.rodata
.align 2
.LC0:
.ascii "\012Serie di Fibonacci dei primi 40 numeri:\000"
.align 2
.LC2:
.ascii "F(0) = 0\012F(1) = 1\000"
.align 2
.LC4:
189
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
.ascii "F(%d) = %d\012\000"
.text
.align 2
.global main
.code 16
.thumb_func
.type main, %function
main:
.fnstart
.LFB0:
.save {r7, lr}
push
{r7, lr}
.pad #16
sub
sp, sp, #16
.setfp r7, sp, #0
add
r7, sp, #0
mov
r3, #1
str
r3, [r7, #12]
mov
r3, #0
str
r3, [r7, #8]
ldr
r3, .L4
mov
r0, r3
bl
puts
ldr
r3, .L4+4
mov
r0, r3
bl
puts
mov
r3, #2
str
r3, [r7, #4]
b
.L2
Queste due righe vengono ridotte a meno istruzioni nella prima ottimizzazione.
.L3:
ldr
ldr
add
str
ldr
ldr
ldr
mov
mov
mov
bl
ldr
str
ldr
str
ldr
add
str
r2, [r7, #12]
r3, [r7, #8]
r3, r2, r3
r3, [r7]
r1, .L4+8
r2, [r7, #4]
r3, [r7]
r0, r1
r1, r2
r2, r3
printf
r3, [r7, #12]
r3, [r7, #8]
r3, [r7]
r3, [r7, #12]
r3, [r7, #4]
r3, r3, #1
r3, [r7, #4]
Questo codice morto non fa altro che spostare dei registri da e verso la
memoria centrale e viene eliminato nella prima ottimizzazione.
.L2:
ldr
r3, [r7, #4]
cmp
r3, #40
ble
.L3
mov
r3, #0
mov
r0, r3
mov
sp, r7
add
sp, sp, #16
@ sp needed for prologue
pop
{r7, pc}
.L5:
.align 2
.L4:
.word .LC0
.word .LC2
.word .LC4
.fnend
.size main, .-main
.ident "GCC: (Sourcery G++ Lite 2011.03-41) 4.5.2"
.section
.note.GNU-stack,"",%progbits
7.4.2.3.
Thumb con ottimizzazione –O1
.arch armv5te
.fpu softvfp
.eabi_attribute
.eabi_attribute
.eabi_attribute
.eabi_attribute
.eabi_attribute
.eabi_attribute
190
20,
21,
23,
24,
25,
26,
1
1
3
1
1
2
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
.eabi_attribute 30, 1
.eabi_attribute 18, 4
.code 16
//Specifica che si tratta di istr. a 16 bit, quindi di istr. Thumb
.file "fibonacci.c"
.text
.align 2
.global main
.code 16
.thumb_func
.type main, %function
main:
.fnstart
.LFB11:
.save
push
ldr
bl
ldr
bl
mov
mov
mov
ldr
b
{r3, r4, r5, r6, r7, lr}
{r3, r4, r5, r6, r7, lr}
r0, .L4
puts
r0, .L4+4
puts
r4, #2
r3, #0
r5, #1
r7, .L4+8
.L2
mov
mov
r3, r5
r5, r6
.L3:
.L2:
add
r6, r3, r5
mov
r0, r7
mov
r1, r4
mov
r2, r6
bl
printf
add
r4, r4, #1
cmp
r4, #41
bne
.L3
mov
r0, #0
@ sp needed for prologue
pop
{r3, r4, r5, r6, r7, pc}
.L5:
.align 2
.L4:
.word .LC0
.word .LC2
.word .LC4
.fnend
.size main, .-main
.section
.rodata.str1.4,"aMS",%progbits,1
.align 2
.LC0:
.ascii "\012Serie di Fibonacci dei primi 40 numeri:\000"
.space 3
.LC2:
.ascii "F(0) = 0\012F(1) = 1\000"
.space 2
.LC4:
.ascii "F(%d) = %d\012\000"
.ident "GCC: (Sourcery G++ Lite 2011.03-41) 4.5.2"
.section
.note.GNU-stack,"",%progbits
7.4.2.4.
Thumb con ottimizzazione –O2
.arch armv5te
.fpu softvfp
.eabi_attribute 20, 1
.eabi_attribute 21, 1
.eabi_attribute 23, 3
.eabi_attribute 24, 1
.eabi_attribute 25, 1
.eabi_attribute 26, 2
.eabi_attribute 30, 2
.eabi_attribute 18, 4
.code 16
//Specifica che si tratta di istr. a 16 bit, quindi di istr. Thumb
.file "fibonacci.c"
.text
.align 2
.global main
.code 16
.thumb_func
191
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
.type
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
main, %function
main:
.fnstart
.LFB11:
.save
push
ldr
bl
ldr
bl
mov
mov
mov
ldr
b
{r3, r4, r5, r6, r7, lr}
{r3, r4, r5, r6, r7, lr}
r0, .L6
puts
r0, .L6+4
puts
r4, #2
r5, #0
r6, #1
r7, .L6+8
.L2
add
mov
mov
mov
bl
add
r6, r6, r5
r1, r4
r0, r7
r2, r6
printf
r4, r4, #1
.L3:
Queste righe di codice vengono aggiunte nella seconda ottimizzazione rispetto
alla prima.
.L2:
add
r5, r5, r6
mov
r1, r4
mov
r0, r7
mov
r2, r5
add
r4, r4, #1
bl
printf
cmp
r4, #41
bne
.L3
mov
r0, #0
@ sp needed for prologue
pop
{r3, r4, r5, r6, r7, pc}
.L7:
.align 2
.L6:
.word .LC0
.word .LC2
.word .LC4
.fnend
.size main, .-main
.section
.rodata.str1.4,"aMS",%progbits,1
.align 2
.LC0:
.ascii "\012Serie di Fibonacci dei primi 40 numeri:\000"
.space 3
.LC2:
.ascii "F(0) = 0\012F(1) = 1\000"
.space 2
.LC4:
.ascii "F(%d) = %d\012\000"
.ident "GCC: (Sourcery G++ Lite 2011.03-41) 4.5.2"
.section
.note.GNU-stack,"",%progbits
7.4.2.5.
Thumb con ottimizzazione –O3
.arch armv5te
.fpu softvfp
.eabi_attribute 20, 1
.eabi_attribute 21, 1
.eabi_attribute 23, 3
.eabi_attribute 24, 1
.eabi_attribute 25, 1
.eabi_attribute 26, 2
.eabi_attribute 30, 2
.eabi_attribute 18, 4
.code 16
//Specifica che si tratta di istr. a 16 bit, quindi di istr. Thumb
.file "fibonacci.c"
.text
.align 2
.global main
.code 16
.thumb_func
.type main, %function
main:
.fnstart
.LFB11:
.save
192
{r4, r5, r6, r7, lr}
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
push
mov
.save
push
ldr
bl
ldr
bl
ldr
mov
mov
mov
bl
mov
mov
mov
bl
mov
mov
mov
mov
b
{r4, r5, r6, r7, lr}
r7, r8
{r8}
{r7}
r0, .L10
puts
r0, .L10+4
puts
r5, .L10+8
r1, #2
r2, #1
r0, r5
printf
r0, r5
r1, #3
r2, #2
printf
r3, #2
r4, #4
r6, #1
r8, r3
.L2
add
mov
mov
add
mov
bl
add
mov
mov
add
mov
bl
add
mov
mov
bl
add
mov
r8, r8,
r1, r7
r2, r8
r6, r6,
r0, r5
printf
r1, r7,
r7, r6
r2, r6
r7, r7,
r0, r5
printf
r1, r4,
r0, r5
r2, r7
printf
r4, r4,
r8, r7
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
Nella terza ottimizzazione, anche in questo caso, come nel primo programma,
vengono aggiunte diverse righe di codice, le quali però, in questo caso, non
portano vantaggi in termini di prestazioni, come si vedrà più avanti, bensì il
tempo medio di esecuzione aumenta leggermente.
.L3:
r6
r8
#1
r8
#3
#4
.L2:
add
r6, r6, r8
mov
r0, r5
mov
r1, r4
mov
r2, r6
add
r7, r4, #1
bl
printf
cmp
r7, #41
bne
.L3
mov
r0, #0
@ sp needed for prologue
pop
{r2}
mov
r8, r2
pop
{r4, r5, r6, r7, pc}
.L11:
.align 2
.L10:
.word .LC0
.word .LC2
.word .LC4
.fnend
.size main, .-main
.section
.rodata.str1.4,"aMS",%progbits,1
.align 2
.LC0:
.ascii "\012Serie di Fibonacci dei primi 40 numeri:\000"
.space 3
.LC2:
.ascii "F(0) = 0\012F(1) = 1\000"
.space 2
.LC4:
.ascii "F(%d) = %d\012\000"
.ident "GCC: (Sourcery G++ Lite 2011.03-41) 4.5.2"
.section
.note.GNU-stack,"",%progbits
193
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
7.4.3.
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
Tempi di esecuzione
I file binari ottenuti dai codici precedenti, sono stati eseguiti sul processore, ed hanno dato i
seguenti risultati per quanto riguarda i tempi di esecuzione:
Tabella 7.3 Tempi di esecuzione del programma Serie di (tempi in ms)
Prova
1
2
3
4
5
6
7
8
9
10
194
real
user
sys
real
user
sys
real
user
sys
real
user
sys
real
user
sys
real
user
sys
real
user
sys
real
user
sys
real
user
sys
real
user
sys
arm
97
10
60
96
10
70
99
10
60
100
20
50
100
10
70
99
0
70
94
10
60
102
10
60
102
0
80
97
20
50
real
user
sys
98,6
10
63
Codifica e ottimizzazioni
thumb thumb_1 thumb_2 thumb_3
91
97
92
101
20
0
10
10
60
70
60
60
99
100
96
99
0
20
10
0
70
60
60
70
97
96
105
109
10
10
10
0
70
60
70
80
105
95
95
94
0
10
0
0
70
70
70
60
91
97
95
104
0
0
10
20
60
60
70
60
96
102
95
98
0
10
0
0
70
60
70
70
98
99
90
96
0
10
10
20
70
60
60
60
95
99
98
93
10
0
10
0
60
70
60
70
104
97
97
100
0
0
20
10
70
70
50
70
99
101
98
93
0
0
10
20
70
70
70
50
Tempi medi
97,5
98,3
96,1
98,7
4
6
9
8
67
65
64
65
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
Figura 7.3 Grafico della distribuzione gaussiana dei tempi di esecuzione(real) rilevati.
1000
900
800
Frequenza
700
600
Arm
Thumb
500
Thumb_O1
400
Thumb_O2
300
Thumb_O3
200
100
0
70
80
90
100
110
120
Tempi [ms]
Come si può vedere dal grafico le distribuzioni hanno una varianza abbastanza bassa, quindi i
risultati si possono considerare piuttosto attendibili.
Dai tempi medi:
-
Arm:
Thumb:
Thumb_O1:
Thumb_O2:
Thumb_O3:
98,6
97,5
98,3
96,1
98,7
ms
ms
ms
ms
ms
In questo caso, si può notare che il programma in Arm viene eseguito in tempi maggiori di quello
in Thumb. Adottando le varie ottimizzazioni il tempo di esecuzione non sempre scende. Il tempo
più basso si ha con la seconda ottimizzazione.
195
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
8. Conclusioni
Dopo aver visto la forma dell’architettura ARM, la gestione delle risorse e tutto il set di istruzioni
Thumb, ho effettuato i test descritti precedentemente sulla scheda disponibile in laboratorio.
Dando un’occhiata ai risultati ottenuti sui tempi di esecuzione si può notare come nei primi due
casi, cioè nel programma del fattoriale e nel programma dei fattori primi, l’esecuzione sia
mediamente più veloce usando il set di istruzioni ARM piuttosto che il Thumb. Le cose cambiano
nell’ultimo programma di test, cioè quello della serie di Fibonacci, nel quale, dall’analisi dei tempi
medi di esecuzione, si può notare che il codice Thumb viene eseguito leggermente più veloce
rispetto al codice ARM.
Per quanto riguarda le ottimizzazioni, invece, si può notare il trend a scendere dei tempi medi di
esecuzione in entrambi i primi due casi. Nel terzo caso invece risulta più veloce la seconda
ottimizzazione piuttosto che la terza, la quale risulta addirittura la più lenta in esecuzione (anche
se di poco) rispetto a tutti gli altri codici.
Le variazioni dei tempi di esecuzione ottenute con le varie ottimizzazioni possono essere spiegate
con il fatto che viene eliminato del codice morto, cioè del codice che il compilatore inserisce in un
primo momento, ma che poi può essere cancellato dato che non è utile all’esecuzione finale del
programma. Queste variazioni dipendono molto anche dalla struttura dei programmi stessi e dei
registri che vanno a sfruttare. Questo fatto è dimostrato proprio dal terzo programma (la serie di
Fibonacci) che viene eseguito più velocemente con codifica Thumb a 16 bit piuttosto che con la
codifica ARM a 32 bit.
Come spiegato all’inizio del capitolo 5 il set di istruzioni Thumb ha accesso completo ai primi otto
registri (R0-R7), mentre l’accesso ai restanti otto registri (R8-R15), detti registri alti, è piuttosto
limitato. Inoltre viene anche detto che “Il Thumb è pensato per aumentare le performance delle
implementazioni ARM che usano un bus dati a 16-bit o anche più piccolo e per permettere una
densità di codice migliore di quella fornita dal set di istruzioni ARM”. In questo modo si può capire
perchè il nostro processore (il quale ha un bus dati di 32 bit), in generale, senza ottimizzazioni,
esegue più velocemente il codice ARM.
In conclusione, il set di istruzioni Thumb sarebbe più adatto per processori che hanno un bus
istruzioni di 16 bit, piuttosto che 32 bit come nel nostro caso, e comunque alcune piccole
differenze si sono potute notare anche con questo processore data la diversità di accesso ai
registri.
196
Studi e sperimentazioni su processori ad architettura ARM:
il set di istruzioni Thumb
Tesi di Laurea di:
Loredano Rapari
matr. 1029262
9. Bibliografia e sitografia
“Architettura e organizzazione dei calcolatori – Progetto e prestazioni”, ed. Pearson, di William
Stallings, ottava edizione
“ARMv5 Architecture Reference Manual” dal sito www.arm.com
“System on chip architecture”, ed. Addison-Wesley, di Steve Furber, seconda edizione
“ARM System developers guide”, ed. Elsevier, di A.N. Sloss, D. Symes, C. Wright
http://arm.com/products/processors/licensees.php
http://arm.com/products/processors/index.php
http://www.marvell.com/processors/embedded/kirkwood/assets/FS_88F6180_9x_6281_OpenSo
urce.pdf
http://www.globalscaletechnologies.com/t-sheevaplugdetails.aspx#features
197