I livelli di astrazione nella
rappresentazione di un calcolatore
L’architettura generale di un calcolatore
Mariagiovanna Sami
2007-08
1
LA GERARCHIA
Applicazione tipica: può consistere di milioni di
linee di codice e servirsi di librerie software
che realizzano funzioni complesse;
‰ Lo hardware esegue solo istruzioni molto
semplici di basso livello (le istruzioni di
macchina); le istruzioni aritmetiche sono solo
istruzioni elementari a due operandi, etc;
‰ Passare dall’applicazione a queste istruzioni
richiede vari livelli di sw che traducano le
operazioni di alto livello in operazioni di
macchina.
‰
20072007-08
-2-
LA GERARCHIA
‰
Fra applicazione (il livello più esterno) e
hardware si trovano vari livelli e tipi di
software di sistema; classi di sw di sistema
presenti per qualsiasi calcolatore:
¾
¾
20072007-08
Sistema operativo
Compilatore
-3-
LA GERARCHIA
Una vista semplificata
dei livelli gerarchici
hw/sw:
Sw applicativo
Sistema operativo
Un’applicazione
complessa ha in realtà
più livelli di sw
applicativo
20072007-08
hardware
-4-
LA GERARCHIA
‰
Sistema operativo: interfaccia fra programma
di utente e hardware: fornisce funzioni di
supervisione e servizi vari, in particolare:
1.
2.
3.
20072007-08
Gestisce le operazioni fondamentali di ingresso e
uscita;
Alloca memoria di lavoro e memoria di massa;
Supporta la condivisione del calcolatore fra più
applicazioni che lo usano simultaneamente.
-5-
LA GERARCHIA
‰
‰
Compilatore: traduce il programma sorgente,
scritto dal programmatore in un linguaggio ad
alto livello, in un programma oggetto
costituito da opprotune sequenze di istruzioni
di macchina, immediatamente interpretabili
ed eseguibili dallo hardware del calcolatore.
La traduzione per i moderni calcolatori è un
problema complesso, e può influenzare
pesantemente le prestazioni ottenibili da una
data applicazione.
20072007-08
-6-
LA TRADUZIONE
‰
Programmare in un linguaggio ad alto livello
consente:
–
–
‰
Di programmare con maggiore facilità,
Di mantenere l’indipendenza dalla particolare
architettura che si sta utilizzando – e quindi garantire la
portabilità.
Linguaggio interno della macchina: composto da 0 e
1 – segnali che devono attivare particolari unità o
trasferire opportune informazioni da un’unità ad
un’altra; la rappresentazione binaria è usata sia per
le istruzioni sia per i dati;
20072007-08
-7-
LA TRADUZIONE
‰
Programmare in linguaggio di macchina è
praticamente impossibile; il linguaggio di
macchina può essere tradotto (mediante una
traduzione “1 a 1”) in un linguaggio simbolico,
che rende comprensibile al programmatore il
significato della singola istruzione ma
corrisponde ancora in modo immediato al
linguaggio di macchina (ed è quindi dipendente
dal calcolatore): si tratta del linguaggio
assemblatore (assembly language).
20072007-08
-8-
LA TRADUZIONE
‰
‰
‰
Es.: il programmatore scrive l’istruzione ad
alto livello A+B
Il corrispondente in linguaggio assemblatore
potrebbe essere add A,B
L’istruzione binaria potrebbe essere
1000110010100000
20072007-08
-9-
LA TRADUZIONE
Programma in linguaggio
ad alto livello (es., C)
‰
Relazione fra
programmi (e
linguaggi):
Compilatore
Programma in
linguaggio assemblatore
Assemblatore
Programma in
linguaggio binario
20072007-08
- 10 -
LE ISTRUZIONI
‰
Linguaggio di macchina: costituito da
istruzioni. L’insieme delle istruzioni
(Instruction set) costituisce (insieme ad altre
informazioni) l’architettura astratta del
calcolatore, visibile al programmatore (o al
compilatore) e indipendente dalla specifica
implementazione interna delle unità
funzionali, dai percorsi che trasferiscono
informazione fra di esse, etc.
20072007-08
- 11 -
LE ISTRUZIONI
‰
‰
Le istruzioni devono specificare l’operazione
che il calcolatore deve compiere (codice
operativo – opcode) e indicare dove si
possono trovare i dati su cui l’operazione deve
essere compiuta.
Insieme delle istruzioni di macchina: devono
consentire di tradurre qualunque programma
scritto in un linguaggio di alto livello – è
indispensabile che particolari classi di
istruzioni siano rappresentate.
20072007-08
- 12 -
LE CLASSI DI ISTRUZIONI
Classi indispensabili:
1. Istruzioni aritmetiche e logiche: qualsiasi
calcolatore deve essere in grado di compierle.
L’insieme di tali istruzioni ha diversa
cardinalità a seconda delle prestazioni che ci
si aspetta, delle applicazioni previste, della
complessità dell’ALU e dell’unità di controllo.
(come minimo occorrono addizione e
complementazione per gli interi come
operazioni aritmetiche, negazione e una delle
operazioni AND e OR come operazioni logiche).
‰
20072007-08
- 13 -
Istruzioni aritmetiche e logiche
(cont)
1. Un insieme ridotto di istruzioni aritmetiche si
traduce in un’ALU più semplice ma in
programmi oggetto più lunghi e complessi (e in
una più vasta libreria di programmi di sistema)
e in un’esecuzione più lenta del programma
originale in linguaggio ad alto livello; oggi si
tende ad avere tutte le istruzioni aritmetiche
in virgola fissa e – almeno in numerose CPU –
anche le istruzioni aritmetiche in virgola
mobile.
20072007-08
- 14 -
LE CLASSI DI ISTRUZIONI
2. È indispensabile che la CPU possa leggere dati
dalla memoria e scrivere dati in memoria –
occorrono quindi istruzioni di accesso alla
memoria (di norma indicate come Load –
istruzione che “carica” dalla memoria in un
registro interno della CPU – e Store, istruzione
che “registra” dalla CPU in memoria).
20072007-08
- 15 -
LE CLASSI DI ISTRUZIONI
3. Di norma, l’esecuzione di un normale
programma per calcolatore che segua il
“paradigma di esecuzione di Von Neumann” è
sequenziale: le istruzioni sono registrate in
posizioni di memoria consecutive e vengono
eseguite nell’ordine in cui sono registrate. A
volte occorre però modificare il flusso del
controllo – dopo avere eseguito un’istruzione
Ik si deve passare a eseguirne una che non la
segue direttamente, quindi si deve operare un
salto Ö occorrono istruzioni di controllo.
20072007-08
- 16 -
LE CLASSI DI ISTRUZIONI
3. In un linguaggio ad alto livello, le istruzioni di
controllo si presentano come “cicli” (es. for
i = 1,N do…) o come scelta fra alternative
(es.: if C then s1 else s2), o ancora
come chiamate a procedura o ritorni da
procedura. Nel linguaggio interno del
calcolatore, i costrutti di controllo devono
essere tradotti facendo riferimento a un
numero molto ridotto di tipi di istruzioni di
controllo.
20072007-08
- 17 -
LE CLASSI DI ISTRUZIONI
3. Tipiche istruzioni di controllo sono:
a) salti incondizionati: l’istruzione che deve essere
eseguita immediatamente dopo quella di salto non
è l’istruzione che segue in ordine di programma,
ma quella all’indirizzo specificato nell’istruzione
stessa – es. jump L1, dove L1 e’ il nome simbolico
di un indirizzo (corrispondono a un “go to”): ,
20072007-08
- 18 -
LE CLASSI DI ISTRUZIONI
3. Tipiche istruzioni di controllo (segue):
b) salti condizionati (tipicamente derivati da
costrutti di iterazione o da espressioni del tipo ifthen-else): si presentano tipicamente nella forma
branch C L1, dove
™ C è una condizione booleana che può essere vera o falsa;
™ Se la condizione C è vera, la prossima istruzione che deve
essere letta ed eseguita si trova all’indirizzo L1;
™ Se la condizione C è falsa, la prossima istruzione è quella
che segue immediatamente l’istruzione di salto (procedi
in sequenza).
20072007-08
- 19 -
LE CLASSI DI ISTRUZIONI
3. Tipiche istruzioni di controllo (segue):
c) Infine, si dispone di istruzioniu per chiamata a
procedura e ritorno da procedura. Le prime si
presentano nella forma “call L” , dove L è
l’indirtizzo della prima istruzione della procedura;
le seconde hanno semplicemente la forma
“return”, e sta all’unità di controllo memorizzare
opportunamente (al momento della chiamata)
l’indirizzo di ritorno
20072007-08
- 20 -
LE CLASSI DI ISTRUZIONI
4. Istruzioni di ingresso e uscita: occorre che il
processore possa scambiare informazione con
le unità periferiche (in molte CPU, è possibile
anche “mappare” gli indirizzi delle periferiche
su indirizzi di memoria e quindi accedere alle
periferiche mediante istruzioni di tipo Load e
Store).
5. … e infine un’istruzione fondamentale: nop –
un’istruzione che non esegue nulla (acronimo
di no operation) ma che a volte è
indispensabile!
20072007-08
- 21 -
Come reperire i dati?
‰ Per le istruzioni “operative” (riguardanti l’ALU)
occorre indicare dove reperire gli operandi e dove
registrare il risultato;
‰ Per le istruzioni che modificano il controllo occorre
precisare il punto del programma verso cui si deve
spostare il controllo – punto identificato da un
indirizzo;
‰ In ambedue i casi, il problema si riporta a quello delle
modalità di indirizzamento.
‰ Esistono numerose modalità di indirizzamento; in
genere, un determinato processore ne utilizza solo un
sottoinsieme.
20072007-08
- 22 -
Le modalità di indirizzamento
‰ Gli operandi di un’istruzione aritmetica o
logica possono trovarsi:
¾ In un registro interno della CPU – di norma questi
sono in numero abbastanza limitato (oggi: da 32 a
256, a seconda delle CPU), quindi possono essere
individuati mediante pochi bit;
¾ Nella memoria primaria del calcolatore, che viene
vista come un unico spazio di indirizzamento: ci
sono vari modi per identificare l’indirizzo.
20072007-08
- 23 -
Le modalità di indirizzamento
‰ Indirizzo in memoria primaria: può essere
specificato come:
¾ Indirizzo assoluto: nell’istruzione si precisa un
valore X determinato, l’indirizzo punta alla
posizione di memoria M[X]
¾ Indirizzo relativo a registro: l’indirizzo in
memoria si calcola come la somma di uno
spiazzamento ∆ (offset) e del contenuto di un
registro interno della CPU detto in genere registro
base (si tratta solitamente di un registro generico
Rx). L’indirizzo punta alla posizione M[∆+(Rx)]
20072007-08
- 24 -
Le modalità di indirizzamento
‰ Ancora:
¾ Indirizzo indiretto da registro: l’indirizzo si trova
in un registro interno della CPU, Rx: la parola di
memoria si reperisce come M[(Rx)] ;
¾ Indirizzo indiretto da memoria: la parola di
memoria indirizzata con altra tecnica (tipicamente,
mediante indirizzamento assoluto) contiene
l’indirizzo della effettiva parola che contiene il
dato: la parola di memoria si reperisce come
M[M[X]]
20072007-08
- 25 -
Le modalità di indirizzamento
‰ Ancora:
¾ Il dato si trova su una area di memoria detta
“stack” (pila) gestita in modo particolare – si può
accedere sempre e solo al dato che si trova sulla
cima della pila – in questo caso non occorre
precisare un in dirizzo, dato che questo è
“implicito”. Se la pila è ricavata nella memoria
principale, la posizione più alta nella pila è
indicata da un puntatore (stack pointer). Quando
si scrive sulla sommità della pila, il puntatore viene
poi “spostato verso l’alto”; quando si legge, il dato
viene tolto dalla pila e il puntatore viene “spostato
verso il basso”.
20072007-08
- 26 -
Le modalità di indirizzamento
‰ … sono stati proposti (e in alcuni casi vengono
usati) anche molti altri modi di
indirizzamento!
‰ Si possono utilizzare tutti questi modi con tutti
i tipi di istruzioni che fanno un qualche
riferimento alla memoria?
¾ Architetture “ortogonali”: praticamente ogni tipo
di istruzione può utilizzare ogni tipo di
indirizzamento;
¾ In altri casi, modi di indirizzamento diversi sono
“riservati” a istruzioni di tipo differente.
20072007-08
- 27 -
Le modalità di indirizzamento
‰ Es.: l’architettura x86 (progenitrice della
famiglia Pentium) è fortemente ortogonale;
‰ In molte architetture di CPU, le istruzioni di
salto fanno ricorso a un numero limitato di
modi di indirizzamento (es., modo indiretto o
modo relativo, a volte facendo riferimento al
Contatore di Programma come registro base;
uso dello stack per le istruzioni di rientro da
procedura).
20072007-08
- 28 -
Le modalità di indirizzamento
‰ Un secondo aspetto delle modalità di
indirizzamento (significativa per le istruzioni
che fanno riferimento all’ALU): quanti
indirizzi si precisano in un’istruzione?
‰ Di norma, le operazioni aritmetiche e logiche
considerate sono “semplici” – svolgono cioè
un’unica operazione aritmetica o logica
elementare e hanno due operandi e un
risultato Ö soluzione più “naturale”: si
indicano esplicitamente gli indirizzi di
ambedue gli operandi e del risultato (formato
a tre indirizzi).
20072007-08
- 29 -
Le modalità di indirizzamento
‰ In questo caso, l’istruzione elementare di
somma si presenta in codice assembly come
add a, b, c
dove a è l’indirizzo del risultato e b, c sono gli
indirizzi dei due operandi.
‰ La struttura interna dell’istruzione sarà del
tipo
opcode
20072007-08
risult. dato1
- 30 -
dato1
Modalità a tre indirizzi
‰ L’istruzione vista ora ospita il codice operativo
+ tre indirizzi… occorrono molti bit!
¾ Se i tre indirizzi possono fare riferimento alla
memoria si deve ammettere che l’istruzione sia
anche molto “lunga”, (la memoria di lavoro ha
grandi dimensioni! E se le parole della memoria
sono N, l’indirizzo richiede log2N bit.)
¾ Altrimenti, si deve imporre che alcuni, o tutti, gli
indirizzi riguardino solo registri interni della CPU
(dato che questi sono pochi, bastano pochi bit per
indirizzarli)
20072007-08
- 31 -
Modalità a due indirizzi
‰ In questa modalità, si precisano solo due
indirizzi: l’istruzione elementare di somma si
presenta ora in codice assembly come
add a, b
dove il significato di a e b varia con due
possibili alternative. Nella prima, si impone
che il risultato venga memorizzato alla fine
dell’operazione nella posizione che ospita uno
degli operandi:
20072007-08
- 32 -
Modalità a due indirizzi
‰ La scrittura del risultato in questo caso
distrugge il valore dell’operando – se questo
deve essere riutilizzato in futuro, occorre
“salvarlo” da qualche parte!
L’istruzione è più “corta” che nel caso a tre
indirizzi, se si accede direttamente alla
memoria: il formato interno è
opcode
20072007-08
ris./dato1
- 33 -
dato2
Modalità a due indirizzi
¾ In alternativa, uno dei due operandi – oppure il
risultato – si trova in una posizione fissa,
tipicamente in un particolare registro interno
della CPU detto accumulatore, il cui indirizzo
è quindi “implicito”. In questo caso, i regsirti
interni non sono tutti indifferenziati, dato che
l’accumulatore vien visto separatamente. Il
codice add a, b sottintende – ad esempio –
che il risultato si troverà nell’accumulatore; il
formato interno è
opcode
20072007-08
dato1
- 34 -
dato2
Modalità a un solo indirizzo
‰ La più ampiamente usata nelle CPU che fanno
riferimento alla memoria anche nelle istruzioni
operative – in particolare, ampiamente usata
nei microprocessori più semplici. Si indica in
modo esplicito solo l’indirizzo di uno degli
operandi; l’altro operando – e il risultato – si
trovano in un registro interno predefinito, di
norma l’accumulatore. Il formato interno è
opcode
20072007-08
dato1
- 35 -
Modalità a un solo indirizzo
‰ Quest’ultima modalità permette di accedere
alla memoria anche con istruzioni operative
relativamente “corte” – il codice oggetto
corrispondente a un’istruzione anche semplice
in codice sorgente diventa però più lungo. Es.:
si debba tradurre A = B + C; sarà necessario:
– Trasferire B nell’accumulatore
– Eseguire la somma con C
– Trasferire il contenuto dell’accumulatore
all’indirizzo A.
20072007-08
- 36 -
Modalità a zero indirizzi
‰ Utilizzata con una memoria organizzata a pila
(quindi secondo il principio “Last In – First
Out” LIFO): gli indirizzi sono tutti impliciti,
dato che i due operandi vengono tolti dalla
sommità della pila e il risultato viene
depositato sulla sommità della pila.
La modalità presume che esistano istruzioni
“di servizio” che permettano di gestire la pila.
Questa modalità – molto elegante per quanto
riguarda l’organizzazione di un programma di
traduzione da un linguaggio ad alto livello – in
pratica no né oggi utilizzata in CPU reali.
20072007-08
- 37 -
Come sono rappresentate le
istruzioni nella macchina?
‰ In memoria, o comunque nel calcolatore,
l’istruzione è registrata come una “stringa” di
bit (normalmente una o più “parole”);
‰ La struttura dell’istruzione deve permettere
all’unità di controllo di decodificarla, cioè
assegnare un significato ai vari bit così da
attivare correttamente le altre unità e i
percorsi di informazione che li collegano.
‰ A questo scopo, la stringa di bit che
rappresenta l’istruzione va considerata
suddivisa in opportuni campi.
20072007-08
- 38 -
Come sono rappresentate le
istruzioni nella macchina?
‰ Le istruzioni in formato binario costituiscono il
linguaggio di macchina del calcolatore.
‰ Es.: si consideri un calcolatore a tre indirizzi,
con parola di 32 bit, nel quale le istruzioni di
tipo operativo trovano gli operandi e scrivono
il risultato in registri interni alla CPU, facenti
parte di un banco di 32 registri. Per
identificare un registro occorrono quindi 5 bit.
20072007-08
- 39 -
Come sono rappresentate le
istruzioni nella macchina?
‰ L’istruzione di macchina è strutturata in campi
come segue:
– Un campo che distingue la classe dell’operazione
(nel nostro caso, un’operazione di tipo aritmetico);
– Tre campi che ospiteranno l’identificativo degli
operandi, posti in un ordine fisso (ad esempio, il
primo e il secodno operando e poi il risultato);
l’identificativo è qui il numero d’ordoine del
registro;
– Eventuali altri campi che forniscono alla macchina
informazioni addizionali (es., un’ulteriore
specificazione della particolare operazione).
20072007-08
- 40 -
Come sono rappresentate le
istruzioni nella macchina?
La nostra add si trasforma quindi come segue:
6 bit
Cod.
op
20072007-08
5 bit 5 bit
1°
oper.
5 bit
2° Risult.
oper. destinazi
sorgente sorgente
one
- 41 -
11 bit
Campo
funzione
Come sono rappresentate le
istruzioni nella macchina?
‰ Si vedrà nel seguito quali modi di
indirizzamento si useranno nella CPU di
riferimento di questo corso e come tali
modalità si traducono nella struttura interna
delle istruzioni di macchina.
20072007-08
- 42 -
La struttura interna della CPU
‰ Indipendentemente dal formato, come viene
supportata dalla struttura delle CPU
l’esecuzione del programma in linguaggio di
macchina?
‰ La CPU deve:
¾ Leggere dalla memoria le istruzioni (fase di fetch)
¾ Interpretarle (= decodificare il significato e le
operazioni elementari che devono essere
comandate alle varie unità interne);
¾ Leggere i dati;
¾ Elaborare i dati
¾ Scrivere i risultati.
20072007-08
- 43 -
La struttura interna della CPU
‰ Per garantire la corretta esecuzione
automatica del programma, l’unità di controllo
– dopo avere comandato lettura di
un’istruzione – contemporaneamente
incrementa il contenuto del contatore di
programma in modo che sia pronto a indicare
l’istruzione successiva (nel caso il flusso del
controllo debba essere modificato in
conseguenza di un’istruzione di controllo, tale
valore verrà opportunamente sostituito nel
corso dell’esecuzione dell’istruzione).
20072007-08
- 44 -
La struttura interna della CPU
‰ In questo modo, non appena l’esecuzione di
un’istruzione è terminata (si vedrà in seguito il
dettaglio di decodifica ed esecuzione), nel
contatore di programma è già pronto
l’indirizzo della prossima istruzione da
eseguire, quindi si ripèrende automaticamente
la sequenza lettura dell’istruzione –
decodifica… etc.
20072007-08
- 45 -
La struttura interna del
calcolatore
‰ Nello schema di Von Neumann, la CPU è
collegata alle altre unità del sistema
((Memoria, I/O) mediante interconnessioni
dirette; oggi tale soluzione non è più adottata
‰ Lo schema elementare di interconnessione è
organizzato intorno a un Bus di Sistema che
trasferisce sulle sue varie sezioni i dati, gli
indirizzi, i segnali di controllo.
20072007-08
- 46 -
Il collegamento fra CPU e
sistema
CPU
registri
ALU
Unità di
controllo
Bus degli
indirizzi
Bus di
controllo
20072007-08
- 47 -
Bus di
sistema
Bus dei
dati
La struttura interna della CPU
‰
Per leggere un’istruzione dalla memoria, la CPU:
¾
¾
‰
Trasferisce l’indirizzo dell’istruzione (contenuto nel
Contatore di Programma, che è uno dei registri
interni) sul bus degli indirizzi;
Invia alla memoria il comando di lettura (tramite
opportune linee del bus di controllo);
In risposta, la memoria estrae la parola richiesta
e:
¾
¾
20072007-08
Porta l’istruzione sul bus dei dati
Segnala alla CPU - mediante il bus di controllo – che
l’istruzione è disponibile.
- 48 -
La struttura interna della CPU
Ogni bus è costituito da un certo numero di
linee, ognuna delle quali trasporta un singolo
bit;
‰ Ogni linea del bus degli indirizzi trasporta un bit
dell’indirizzo; analogamente, ogni linea del bus
dati trasporta un bit di dato – la differenza fra
due linee corrisponde solo alla posizione del bit;
‰ Le diverse linee del bus di controllo sono invece
associate a funzionalità diverse – corrispondono
a segnali di controllo con significati diversi,
scambiati fra le varie unità del sistema.
‰
20072007-08
- 49 -
La struttura interna della CPU
All’interno della CPU sono presenti dei registri,
alcuni dei quali sono specializzati e non “visibili
al programmatore” (non esistono istruzioni
specifiche che permettano di scrivevi un valore
arbitrario o di leggerne il contenuto): tali registri
sono utilizzati fondamentalmente dalla unità di
controllo;
‰ Esistono inoltre registri di tipo generale, che
fungono da “memoria di lavoro” interna alla
CPU.
‰
20072007-08
- 50 -
I registri interni
Come minimo, esiste un registro visibile al
programmatore (detto in questo caso
“accumulatore”);
‰ Nelle CPU moderne, esiste un certo numero di
registri general purpose visibili al
programmatore e indifferenziati (hanno cioè
tutti le stesse funzioni e capacità, e le stesse
dimensioni, uguali a quelle di una parola di
memoria) organizzati in un register file (o
“banco di registri”)
‰
20072007-08
- 51 -
Il register file
Struttura generale di un register file:
Porta di
lettura
Register
file
Indirizzo (=
numero
d’ordine del
registro)
20072007-08
Porta di
scrittura
- 52 -
Il register file
L’ indirizzo (costituito da log2 k bit, se k sono i
registri nel banco) permette di selezionare il
particolare registro cui si vuole accedere;
‰ Alla porta di lettura si legge il contenuto del
registro selezionato;
‰ Alla porta di scrittura si trasferisce da un’altra
unità (es., dalla memoria, o dall’uscita dell’ALU)
il valore che si vuole scrivere nel registro
selezionato;
‰
20072007-08
- 53 -
Il register file
In genere, è possibile accedere simultaneamente
in lettura e in scrittura a due registri (non
necessariamente diversi) o meglio ancora
leggere simultaneamente da più registri (es.,
due) e scrivere in un registro.
‰ Il register file costituisce la memoria più
“vicina” alla CPU (al “massimo livello” nella
gerarchia di memorie);
‰
20072007-08
- 54 -
Il register file
‰
Decidere il numero dei registri nel register file e
il numero di porte di lettura e scrittura sono
scelte molto importanti al momento del progetto
di una CPU;un numero elevato di registri
aumenta la flessibilità e le opzioni del
programmatore (o del compilatore) ma cresce il
numero dei bit di indirizzamento che compaiono
nelle istruzioni e l’accesso al register file
diventa più lento!
20072007-08
- 55 -
Il register file
Nelle CPU moderne: da 32 a 256 registri nel
Register File;
‰ Spesso è possibile combinare due registri per
ospitare una “doppia parola” (ad esempio, per
fare calcoli “in doppia precisione”) etc.
‰
20072007-08
- 56 -
Altri registri
‰
Registro/i di “flag” o di “condition code”:
¾
¾
¾
20072007-08
Insieme di singoli bit (ognuno costituisce una “flag”) il
cui valore viene implicitamente posizionato da una
particolare condizione che si verifica durante
l’esecuzione di determinate istruzioni (es., il
confronto fra i contenuti di due registri, oppure il
fatto che il risultato di un’operazione aritmetica sia
0, etc.)
Possono essere implicitamente letti dal programma
(es., in un’ istruzione di salto condizionato vincolato a
una delle condizioni);
Di norma i bit di questo registro non possono essere
scritti in modo esplicito dal programma.
- 57 -
Registri di controllo e di stato
Contatore di Programma (PC)
‰ Registro Istruzione (vi viene portata l’istruzione
appena letta, perché l’unità di controllo possa
interpretarla e comandarne l’esecuzione);
‰ Registro di indirizzamento della memoria
(MAR);
‰ Registro di interfaccia con la memoria (Memory
Buffer);
‰ E altri registri (es., Stack Pointer, Program
Status Word) di cui si parlerà quando necessario.
‰
20072007-08
- 58 -
Struttura interna della CPU
È di nuovo organizzata intorno a un sistema di
bus:
Bus interno della CPU
‰
ALU
20072007-08
- 59 -
Register
file
Unità di
contr.
Le caratteristiche dell’insieme di
istruzioni
‰
Due alternative fondamentali:
¾
¾
20072007-08
Architetture “con riferimento alla memoria” –
sostanzialmente ortogonali: anche le istruzioni
operative possono accedere direttamente a dati in
memoria (in lettura o in scrittura).
Architetture di tipo “registro-registro” (dette anche
“Load-Store”): solo le istruzioni Load e Store possono
accedere direttamente alla memoria, le istruzioni
operative possono fare riferimento solo al contenuto
dei registri del register file (oltre che su valori
immediati).
- 60 -
Architetture “con riferimento alla
memoria”
‰
‰
‰
Consentono programmi in linguaggio macchina più
compatti;
Le diverse istruzioni possono richiedere un numero
diverso di parole di memoria per potere ospitare (oltre al
codice operativo) indirizzi di un numero di bit sufficiente
ad indirizzare una memoria di dimensioni abbastanza
grande Ö l’unità di controllo risulta più complessa (la
lettura di un’istruzione può estendersi su più parole di
memoria…);
Lettura ed esecuzione delle diverse istruzioni hanno
caratteristiche “irregolari”.
20072007-08
- 61 -
Architetture “registro-registro”
‰
Il programma oggetto risulta più lungo; la
semplice istruzione “A=B+C” con dati in
memoria e risultato che deve anch’esso essere
scritto in memoria si traduce nella sequenza:
¾
¾
¾
¾
20072007-08
leggi B dalla memoria in un registro RB;
leggi C dalla memoria in un registro RC;
somma i contenuti di RB ed RC e scrivi il risultato in un
registro RA;
scrivi il valore contenuto in RA in memoria.
- 62 -
Architetture “registro-registro”
‰
Ma…
¾
¾
¾
20072007-08
Tutte le istruzioni hanno la stessa lunghezza;
L’unità di controllo è nettamente più semplice;
Lettura ed esecuzione delle diverse istruzioni hanno
caratteristiche fortemente “regolari” – questo porta a
soluzioni ottimizzate della CPU che permettono
prestazioni molto più elevate (= esecuzione più veloce
dell’intero programma).
- 63 -
L’architettura di riferimento
Si farà riferimento all’architettura MIPS –
progettata inizialmente da un gruppo guidato da
Hennessy e Patterson (delle università di
Berkeley e Stanford), poi diventata
un’architettura commerciale (oggi per sistemi
embedded): essenzialmente un’architettura
registro-registro.
‰ Le istruzioni operative precisano tipicamente gli
indirizzi dei due operandi e del risultato come
registri – l’unica alternativa è che uno degli
operandi sia un “immediato” (una costante).
‰
20072007-08
- 64 -
L’architettura di riferimento
MIPS ha un banco di 32 registri; 5 bit bastano per
indirizzare un registro;
‰ La notazione $x verrà usata per indicare il
registro x (quindi $1, $2…)
‰ Es.: sia data l’espressione
f = (g+h) – (i+j)
se ne vuole la traduzione nell’assembler del
MIPS:
‰
20072007-08
- 65 -
MIPS: un esempio di assembler
‰
Dapprima si traduce l’espressione complessa in
una sequenza di operazioni aritmetiche semplici
(binarie), introducendo variabili ausiliarie e
avendo cura di scegliere una traduzione che
minimizzi la lunghezza del codice oggetto:
quindi
t0 = g+h
t1 = i+j
f = t0 – t1
20072007-08
- 66 -
MIPS: un esempio di assembler
‰
Si supponga ora che il registro $1 contenga la
variabile g, $2 la variabile h, $3 la variabile i, $4
la variabile i, e che il registro $10 debba
contenere il risultato f: la traduzione nel
linguaggio assembler sarà:
add $5, $1, $2 # t0 si trova in $5
add $6, $3, $2 # t1 si trova in $6
sub $10, $5, $6
20072007-08
- 67 -
MIPS: i riferimenti alla memoria
‰
Come già detto, solo le istruzioni specifiche di
lettura da memoria e scrittura in memoria (Load
e Store) possono accedere alla memoria;
l’indirizzo cui accedere viene costruito mediante
indirizzamento relativo, indicando uno
spiazzamento rispetto a un registro base (un
registro del register file, scelto liberamente) in
cui è memorizzato il valore-base dell’indirizzo.
20072007-08
- 68 -
MIPS: i riferimenti alla memoria
‰
Es.: data l’espressione in C
g = h + A[8]
si supponga che la variabile g si trovi nel registro
$2; occorre portare in un registro il valore A[8],
che si trova in memoria. Si supponga che
l’indirizzo-base del vettore A si trovi nel registro
$3; la sequenza di istruzioni sarà:
lw $4, 8($3) # la parola viene letta
add $1, $2, $4
20072007-08
- 69 -
MIPS: i riferimenti alla memoria
‰
L’istruzione lw sta per “load word” – leggi
un’intera parola di 32 bit. In realtà, la memoria
del MIPS (come di molti calcolatori…) è
organizzata a byte – gruppi di otto bit. Gli
indirizzi delle parole iniziano quindi sempre a
distanza quattro: nell’esempio appena fatto, il
codice macchina darà uno spiazzamento pari a
32 (quattro byte), quindi la sequenza reale sarà:
lw $4, 32($3)
add $1, $2, $4
20072007-08
- 70 -
MIPS: il formato interno delle
istruzioni
Si sono visti due esempi di istruzioni: quale è
l’effettiva organizzazione della parola che
rappresenta un’istruzione?
‰ I 32 bit che costituiscono una parola vengono
numerati da sinistra a destra, da 0 a 31 e
organizzati in “campi” (gruppi di bit consecutivi
cui viene assegnato un particolare significato)
‰
20072007-08
- 71 -
MIPS: il formato interno delle istruzioni
‰
Per le istruzioni che utilizzano il contenuto di registri per
istruzioni aritmetico-logico (istruzioni di tipo R) il
formato è:
op
6 bit
rs
rt
rd
5 bit
5 bit
5 bit
shamt funct
5 bit
6 bit
dove op è il codice operativo fondamentale, rs il
registro sorgente del primo operando, rt il registro
sorgente del secondo, rd il registro destinazione del
risultato, shamt (shift amount) verrà discusso in seguito,
funct specifica la variante dell’operazione il cui tipo è
indicato da op.
20072007-08
- 72 -
MIPS: il formato interno delle istruzioni
‰
Il precedente formato non è utile quando si vogliano
utilizzare campi più lunghi di 5 bit; ad esempio, una
Load o una Store utilizzano uno spiazzamento che – per
essere significativo – non può limitarsi a 5 bit. Si
introduce quindi un nuovo formato, mantenendo sempre
l’istruzione di 32 bit (formato I, dove I sta per
Immediato), utile sia per le istruzioni di riferimento a
memoria sia per quelle che utilizzano una costante
(indirizzamento immediato):
op
6 bit
20072007-08
rs
rt
5 bit
5 bit
Costante o indirizzo
16 bit
- 73 -
MIPS: il formato delle istruzioni di tipo I
‰
Es.: l’istruzione
lw $5, 32($3)
avrà la seguente struttura interna:
lw
6 bit
$3
$5
5 bit
5 bit
32
16 bit
si noti: ora nel campo rs si specifica il registro base,
mentre nel campo rt si indica il registro destinazione
dell’operazione di lettura.
20072007-08
- 74 -
MIPS: il formato interno delle istruzioni
‰
‰
Le istruzioni che modificano il flusso del controllo fanno
ricorso a indirizzamento relativo. Consideriamo un
primo caso:
Si confrontano i valori di due registri del register file
(possono essere uguali o non uguali) e in conseguenza del
risultato si procede in sequenza oppure si “salta” a un
indirizzo calcolato come somma dello spiazzamento
indicato nell’istruzione e del contenuto del Program
Counter. IL formato è
op
6 bit
20072007-08
rs
rt
5 bit
5 bit
spiazzamento
16 bit
- 75 -
MIPS: il formato interno delle istruzioni
‰
Es.: sia data l’istruzione
beq $1, $2, L1
l’istruzione in assembler indica che se il confronto fra i
due registri dà risultato “uguale” l’esecuzione deve
passare all’indirizzo L1, altrimenti deve procedere in
sequenza dopo l’istruzione di salto condizionato.
L’indirizzo nell’istruzione di macchina viene precisato
come somma algebrica di uno spiazzamento di 16 bit e
del PC.
rt
spiazzamento
rs
op
6 bit
20072007-08
5 bit
16 bit
5 bit
- 76 -
MIPS: il formato interno delle istruzioni
‰
‰
Analogamente, si può imporre un salto condizionato del
tipo bne – il salto viene effettuato se i due registri hanno
contenuto diverso.
Sia data l’istruzione in C.
if (i==j) f = g+ h ; else f = g – h
e si supponga che i e j si trovino rispettivamente nei
registri 3 e 4, mentre f deve andare nel registro 5, g e h
si trovano nei registri 1 e 2: può valere la pena di
tracciare innanzitutto un diagramma di flusso delle
operazioni elementari corrispondenti all’istruzione:
20072007-08
- 77 -
MIPS: il formato interno delle istruzioni
vero
else
i=j?
F=g+h
F=g-h
Exit
‰
Il codice assembler corrispondente sarà:
20072007-08
- 78 -
MIPS: le istruzioni di salto condizionato
Si utilizza innanzitutto un’istruzione di salto
condizionato, dove come condizione si usa la verifica che
i valori contenuti nei registri 3 e 4 siano diversi – se la
condizione è vera, si deve passare a eseguire le istruzioni
corrispondenti al ramo “else”: quindi:
bne $3, $4, Else
20072007-08
# Else è l’etichetta
della destinazione se la
condizione if è vera
- 79 -
MIPS: le istruzioni di salto condizionato
Se invece la condizione nell’istruzione bne è falsa, si
continua in sequenza (ramo “vero” nello schema di
flusso) sommando le variabili contenute nei registri $1 e
$2; al termine di questa operazione si deve passare alla
“chiusura” (indirizzo simbolico exit) con un’istruzione di
salto incondizionato. Quindi il ramo “vero” dello schema
di flusso si traduce in
add $5, $1, $2
j exit
# si deve saltare alla
destinazione comune delle
due diramazioni
20072007-08
- 80 -
MIPS: le istruzioni di salto condizionato
concludendo, il segmento di programma assembly è
bne $3, $4, Else # Else è l’etichetta
della destinazione se la
condizione if è falsa
add $5, $1, $2
# la condizione if è vera
j exit
# si deve saltare alla
destinazione comune delle
due diramazioni
Else: sub $5, $1, $2 # ramo else
Exit: ….
20072007-08
- 81 -
MIPS: le istruzioni di salto
‰
Il salto incondizionato, jump (j) fa si che il contenuto del
contatore di programma venga modificato –
sostituendolo con quello precisato nell’istruzione –
indipendentemente da qualsiasi condizione. Il formato
interno sarà ancora diverso dai precedenti; accanto al
codice operativo si indicano 26 bit che vanno concatenati
con i sei bit più significativi del PC.
op
6 bit
20072007-08
spiazzamento
26 bit
- 82 -
Come gestire le procedure?
‰
Una chiamata alla procedura implica:
¾
¾
Il passaggio dei parametri
Il passaggio del controllo all’indirizzo iniziale della
procedura
Così come il ritorno implica un passaggio di
risultati e il trasferimento del controllo alla
prima istruzione immediatamente successiva a
quella di chiamata a procedura.
‰ Come implementare queste operazioni nello
hardware?
‰
20072007-08
- 83 -
Come gestire le procedure?
IL passaggio dei parametri viene gestito
sfruttando i registri; il cambiamento del flusso
del controllo richiede qualche aggiunta allo
hardware:
‰ Chiamare una procedura implica la necessità di
salvare l’indirizzo di rientro – una procedura può
essere chiamata da molti, diversi punti di uno
stesso programma, e al termine della sua
esecuzione si deve ogni volta tornare
all’istruzione del progamma chiamante
immediatamente successiva alla chiamata!
‰
20072007-08
- 84 -
Come gestire le procedure?
‰
È chiaro che una semplice istruzione di salto
incondizionato non è sufficiente, dato che non
“salva” l’indirizzo dell’istruzione successiva a
quella di chiamata. Si introduce una nuova
istruzione “jump-and-link” (jal) il cui formato è
simile a quello di un salto incondizionato:
jal
6 bit
20072007-08
spiazzamento
26 bit
- 85 -
Come gestire le procedure?
Il nuovo indirizzo viene ancora creato concatenando
lo spiazzamento coi sei bit più significativi del
program counter;
‰ L’operazione “link” consiste nel memorizzare in un
apposito registro $ra l’indirizzo di ritorno (che
coincide con il contenuto del PC).
‰ L’istruzione di “ritorno” che conclude la procedura
sarà un salto incondizionato all’indirizzo contenuto
nel registro $ra (si noti: in questo caso nel registro
si trova l’indirizzo intero!)
‰
20072007-08
- 86 -
Come gestire le procedure?
E se ci sono procedure “annidate”? La soluzione ora
indicata non darebbe buon esito – alla chiamata
della procedura più interna il “salvataggio” del
relativo indirizzo di rientro distruggerebbe
l’indirizzo di rientro dalla procedura più esterna!
‰ Per gestire più procedure annidate, o permettere
trasferimenti di parametri più complessi, la CPU può
far uso di uno stack (pila).
‰
20072007-08
- 87 -
Come gestire le procedure?
‰Stack: un’area della memoria di lavoro (definita
in fase di inizializzazione del sistema) cui si
accede mediante un altro registro speciale,
detto stack pointer (puntatore alla pila).
‰Lo stack viene gestito “come una pila di piatti”:
il puntatore indica l’indirizzo in memoria che
corrisponde alla “cima” della pila.
20072007-08
- 88 -
Come gestire le procedure?
‰ Le operazioni possibili consistono
1. nel “porre” un dato sulla pila – operazione detta
push, istruzione in cui si indica solo il nome del
registro il cui contenuto va trasferito sulla pila
(l’indirizzo di memoria è implicito, essendo
contenuto nel puntatore); al termine dell’istruzione,
il puntatore viene automaticamente incrementato
per puntare alla prima posizione libera nella pila;
2. Nel “togliere” un dato dalla pila – operazione detta
pop; al termine dell’istruzione, il puntatore viene
automaticamente decrementato (è “come se” il dato
fosse stato fisicamente eliminato).
20072007-08
- 89 -
Come gestire le procedure?
‰ In presenza di procedure annidate, il
programmatore (o il compilatore) salva sulla
pila l’indirizzo di ritorno della procedura più
esterna; procedendo in ordine, è chiaro che la
sequenza push-pop garantisce la sequenza
corretta salvataggio – utilizzo degli indiriuzzi di
rientro.
‰ La pila viene usata anche per il passaggio dei
parametri.
20072007-08
- 90 -
Riassumendo: i modi di
indirizzamento del MIPS
‰
‰
‰
‰
‰
Indirizzamento a registro – l’operando è contentuo in un registro;
Indirizzamento mediante spiazzamento l’operando è in una
posizione di memoria il cui indirizzo si ottiene sommando lo
spiazzamento al contenuto di un registro base,
Indirizzamento immediato: l’operando è una costante indicato
direttamente nell’istruzione;
Indirizzamento relativo al PC: l’indirizzo è la somma del contenuto
del PC e di una costante contenuta nell’istruzione;
Indirizzamento pseudodiretto: l’indirizzo destinazione di un salto
incondizionato è costituito dai 26 bit meno significativi
dell’istruzione concatenati con i sei bit più significativi del PC.
20072007-08
- 91 -
Riassumendo: i modi di
indirizzamento del MIPS
Indirizzamento immediato:
op
rs
rt
immediato
Indirizzamento a registro
op
rs
rt
rd
shamt funct
registro
20072007-08
- 92 -
Riassumendo: i modi di
indirizzamento del MIPS
Indirizzamento mediante spiazzamento:
op
rs
rt spiazzamento
memoria
byte
registro
20072007-08
- 93 -
parola
Riassumendo: i modi di
indirizzamento del MIPS
Indirizzamento relativo al PC:
op
rs
rt spiazzamento
memoria
parola
PC
20072007-08
- 94 -
Riassumendo: i modi di
indirizzamento del MIPS
Indirizzamento psudodiretto:
op
indirizzo
memoria
:
PC
20072007-08
- 95 -
parola
Alcune considerazioni
‰
‰
I salti condizionati puntano a indirizzi a distanza di ±215
parole dall’istruzione corrente (di fatto, dall’indirizzo
della istruzione successiva al salto stesso); di fatto, la
statistica dimostra che la destinazione di un salto
condizionato è di norma anche molto vicina al salto
stesso (comunque si indica la distanza come numero di
parole, non di byte);
Salti incondizionati, chiamate a e ritorni da procedura
hanno più probabilità di puntare a indirizzi anche
notevolmente lontani (anche qui, la distanza viene data
in parole) – il campo di 26 bit nelle istruzioni permette
di esplorare un campo di 228 bytes!
20072007-08
- 96 -
Alcune considerazioni
‰
‰
Le costanti usate di norma sono piccole (fatto verificato
statisticamente) – 16 bit sono sufficienti per specificarle.
Esistono istruzioni particolari che permettono anche di
costruire costanti di 32 bit, ma non sono essenziali per i
nostri scopi, quindi non si approfondiranno!
Particolari tipi di istruzioni possono usare più modi di
indirizzamento; ad esempio, per la somma esistono sia la
forma add rd, rs1, rs2 sia la forma
addi rd, rs1, costante
20072007-08
- 97 -