Laboratorio di Architettura degli Elaboratori

Transcript

Laboratorio di Architettura degli Elaboratori
Laboratorio di Architettura degli Elaboratori
Dott. Massimo Tivoli
Introduzione al corso
e
Concetti di base per la programmazione di microprocessori
Ringraziamenti
• Le slides che vederete durante il corso sono una versione leggermente modificata delle slides presentate dal Dott. Henry Muccini
durante le edizioni passate del corso
• Il contenuto delle slides 7‐11 è tratto da:
– http://www.lithium.it/articolo0017p5.htm
Informazioni utili (continua…)
•
Pagina web del corso
– http://www.di.univaq.it/tivoli/LabArch/LabArch.html
•
Pagina web del docente
– http://www.di.univaq.it/tivoli
•
E‐mail del docente:
– [email protected]
– va usata con estrema parsimonia
•
Testo di riferimento
– D. A. Patterson e J. L. Hennessy, Struttura e progetto dei calcolatori: l’interfaccia hardware‐software, Zanichelli, seconda edizione 2006, quinta ristampa 2010.
•
•
Capitoli 1‐3 e Appendice A (in formato elettronico)
Materiale didattico di supporto
– vari manuali/guide e tutorial disponibili, in formato elettronico, sulla pagina web del corso
•
Tool
– MARS (MIPS Assembler and Run‐time Simulator)
•
•
richiede Java 1.4.2 o superiore
multi‐piattaforma
– http://courses.missouristate.edu/KenVollmar/MARS/
•
Modalità d’esame
– scritto (obbligatorio, voto max: 25/30) + progetto e discussione progetto (facoltativo, voto max: 6/30)
– potrà cambiare… in ogni caso, almeno uno scritto ci sarà…
Informazioni utili
• Eventuali avvisi o cambiamenti
– la fonte più attendibile è sempre la pagina del corso disponibile attraverso la pagina web del docente (vedi slide precedente)
• monitoratela spesso
• Ricevimento studenti
– Lunedì & Martedì, 14:00 – 15:00
• Per chi non segue
– le slide non possono essere considerate materiale di studio
• traccia della discussione che il docente tiene a lezione
– servono solo come riferimento degli argomenti discussi a lezione
• per coprire in modo soddisfacente gli argomenti si faccia riferimento al testo consigliato e al materiale di supporto disponibile in formato elettronico (vedi slide precedente)
Scopi del corso
• Insegnare i concetti HW e SW di base per le generazioni di processori MIPS32 (MIPS R2000/R3000)
– architettura HW del processore MIPS32
• cenni
– set di istruzioni del processore MIPS32
• assemblatore e simulatore MARS
Architetture RISC
•
Si riferisce ad una gamma di microprocessori sviluppati solo a partire dal 1985
•
Reduced Instruction Set Computer
–
–
–
–
•
processori ad alta velocità e dal costo ridotto
si può ottenere maggiore velocità ma sono di difficile programmazione
ottimizzazione del codice prioritaria
mercati di nicchia
Alcuni celebri computer Desktop e Server di tipo RISC
– Digital Alpha, Hewlett‐Packard PA‐RISC, IBM and Motorola PowerPC, Silicon Graphics MIPS, Sun Microsystems SPARC
•
Prodotti commerciali di grande successo basati su soluzioni RISC
– PlayStation, PlayStation 2, PlayStation Portable (utilizzano tutti MIPS)
•
Contrapposto a set di istruzioni CISC a lunghezza variabile
– Complex Instruction Set Computer
•
•
maggiore potenza e conseguente semplicità di programmazione
comodo negli anni ‘70, di scomoda gestione oggi
– Tutta la gamma di microprocessori Intel x86
•
•
dai primi anni ‘70 (Intel 4004) ad oggi (Intel Pentium, Core Duo, Core Quad, Core Extreme, etc.)
anche se quelli più recenti sfruttano un approccio ibrido
Un po’ di storia (continua…)
• Anni ‘70
– introduzione dei primi calcolatori basati su transistor altamente integrati
• era della miniaturizzazione, processori CISC, e.g., Intel 4004, 8080, 8085
– memorie a nucleo magnetico
• lente, grosse e molto costose
– i compilatori producevano codice molto inefficiente
• programmazione direttamente in assembler
– dispositivi di memoria secondaria magnetici, lenti e costosissimi
– con l’avvento delle memorie dinamiche a semiconduttore (metà anni ‘70) ci furono dei miglioramenti ma il costo delle memoria era ancora molto elevato
• nel ’74, 1Mbit (125 byte) costava 150000$
CONSEGUENZA: i programmi dovevano essere molto semplici e molto compatti per risiedere in una memoria di pochi Kb
Un po’ di storia (continua…)
• Metà anni ‘70
– lo stato di integrazione non era ancora tale da avere un unico chip sulla stessa scheda madre per tutte le mansioni
• poche migliaia di transistor su un singolo chip
• e.g., ancora nel ‘90 il 386 aveva bisogno di un altro chip per svolgere i calcoli in virgola mobile, i.e., co‐processore matematico
– bus di comunicazione memoria‐chipset e chipset‐
processore ad alta limitazione di banda
• introduzione di colli di bottiglia
CONSEGUENZA: si avvertiva la necessità di impacchettare quanta più logica possibile su un singolo chip, anziché rivolgersi ad architetture distribuite (Intel 4004)
Un po’ di storia (continua…)
• Dagli anni ‘70 agli inizi degli anni ‘80
– memorie sempre costose e compilatori sempre inefficienti
– rendere i computer più facilmente programmabili costruendo chip in grado di eseguire in hardware istruzioni anche molto complesse
• architetture CISC
– compatibilità verso le precedenti versioni di microprocessore
• limitato sfruttamento dei progressi tecnologici
CONSEGUENZA: efficienza nella scrittura di programmi e nella loro manutenzione, inefficienza nell’esecuzione del codice
Un po’ di storia
• Inizi anni ‘80 in poi
– compilatori più efficienti, memorie meno costose
– introduzione di una nuova filosofia di progettazione dei microprocessori
• il 90% del tempo, il processore utilizza sempre un sottoinsieme ristretto di istruzioni
• idea di permettere l’esecuzione diretta solo di queste poche istruzioni lasciando al compilatore l'onere di spezzettare le istruzioni più rare e molto più complesse in una sequenza di queste istruzioni direttamente eseguibili
• limitare gli accessi in memoria centrale definendo poche e semplici modalità di accesso alla memoria e disponendo il chip del processore di un maggior numero di registri
CONSEGUENZA: architetture RISC
CISC vs RISC
Approccio fondamentale
Impatto lato programmatore
Impatto sull’hardware
CISC
RISC
hardware complesso + software semplice (compilatore inefficiente)
hardware semplice + software complesso (compilatore efficiente)
codice molto compatto, la dimensione del codice l’hardware si preoccupa aumenta, l’hardware si semplifica della decodifica di istruzioni complesse
‐ pochi registri,
‐ presenza di una ROM per la decodifica,
‐ centinaia di istruzioni macchina,
‐ tante modalità di indirizzamento
‐ molti registri
‐ alla memoria si accede solo con load e store
‐ qualche decina di istruzioni soltanto
Unità di misura per la rappresentazione dei dati (continua…)
• 1 Bit
– 0 o 1
• 1 Nibble
– 4 bit
• 1 Byte
– 8 bit, 2 nibble
• 1 Word (Intel x86)
– 16 bit, 2 byte, 4 nibble
• 1 Word (MIPS32), 1 Double Word (Intel x86)
– 32 bit, 1 word (MIPS32), 2 word (Intel x86), 4 byte, 8 nibble
• Quadruple Word, Block, etc.
Unità di misura per la rappresentazione dei dati
• 1 Kb (K‐byte o Kilo‐byte)
– 1024 byte ~ 1 migliaio di byte
• 1 MB (Mega‐byte)
– 1024 Kb ~ 1 milione di byte
• 1 GB (Giga‐byte)
– 1024 MB ~ 1 miliardo di byte
• 1 TB (Tera‐byte)
– 1024 GB ~ 1000 miliardi di byte
• etc.
– 1 Peta‐byte (1024 TB), etc.
Sistema di numerazione
• Un insieme di simboli per rappresentare numeri + regole di interpretazione di tali simboli per contare ed eseguire operazioni
• Ogni sistema di numerazione quindi fa riferimento a una scala convenzionale di simboli chiamata “base”
– permette di classificare numeri sempre più grandi, evitando sforzi di memoria o di rappresentazione macchinosa
Sistema decimale
• Alfabeto di 10 simboli (base 10)
– 0,1,2,3,4,5,6,7,8,9
• I numeri <= 10 e le potenze di 10 ricevono ciascuno un nome individuale, mentre i nomi dei numeri intermedi sono parole composte a partire dai precedenti, seguendo un principio additivo o moltiplicativo
– 0,1,2,3,4,5,6,7,8,9,10,100,1000
– 101,200,110,2000,2009
• Il più diffuso oggi per ovvie ragioni antropomorfiche
– un uomo, per contare, può avvalersi di 10 dita
• Lo si usa anche per interpretare il valore delle cifre di numeri espressi con altri sistemi di numerazione Sistemi binario e esadecimale
•
Binario: alfabeto di 2 simboli (base 2)
– 0,1
– corrispondenza con i componenti elettronici che funzionano in spento/acceso, NO/SI, idle/pronto,etc.
•
Esadecimale: alfabeto di 16 simboli (base 16)
– 0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
– A=10, B=11, C=12, D=13, E=14, F=15 (in base 10)
•
Tutti sistemi posizionali
– Il valore delle cifre dipende dalla posizione che occupano nel numero
– spostandosi a sinistra di una posizione, il valore della cifra viene moltiplicato per
• 10 (base 10)
• 2 (base 2)
• 16 (base 16)
•
Un sistema non posizionale è ad esempio quello degli antichi romani
– XVIII = 18 e non 15111 = 1*100 + 1*101 + 1*102 + 5*103 + 1*104
Sistemi posizionali
• Il valore N (in base 10) del numero anan‐1…a1a0 è
– N = a0*B0 + a1*B1 + … + an‐1*Bn‐1 + an*Bn
dove B è la base di rappresentazione del numero, gli ai sono le cifre del sistema ovvero gli elementi dell’alfabeto di B simboli, e gli ai sono i rispettivi valori (in base 10)
– e.g., B = 10 e ai ∈ {0,…,9}
– e.g., B = 2 e ai ∈ {0,1}
– e.g., B = 16 e ai ∈ {0,…,9,A,…,F} • Esempi
– decimale: 350 = 0*100 + 5*101 + 3*102 = 300 + 50 + 0
– binario: 101011110 = 0*20 + 1*21 + 1*22 + 1*23 + 1*24 + 0*25 + 1*26 + 0*27 + 1*28 = 256 + 0 + 64 + 0 + 16 + 8 + 4 + 2 + 0 = 350
– Esadecimale: 15E = 14*160 + 5*161 + 1*162 = 256 + 80 + 14 = 350
Parte intera e parte frazionaria
• N = Ni + Nf
– e.g., N=1936.27 => Ni = 1936; Nf = 0.27
• Decimale: N=a0*100 + … +an*10n+
a‐1*10‐1+…+a‐n*10‐n
– N=10.3
Ni=10 = 0*100 + 1*101 +
Nf=0.3 = 3*10‐1
= 10.3
• Binario: N=a0*20 + … +an*2n+
a‐1*2‐1+…+a‐n*2‐n
– N=100.11
• NOTA: x‐y = 1/xy
Ni=100 = 0*20 + 0*21 + 1*22 +
Nf=0.11 = 1*2‐1 + 1*2‐2
= 4.75
Da base 10 a base 2
• N = 47.485 (= 47 + 0.485)
– Ni = 47
•
•
•
•
•
•
•
47/2 ‐> Q: 23, R: 1
23/2 ‐> Q: 11, R: 1
11/2 ‐> Q: 5, R: 1
5/2 ‐> Q: 2, R: 1
2/2 ‐> Q: 1, R: 0
1/2 ‐> Q: 0, R: 1 (ci si ferma quando il quoziente si annulla)
Ni = 101111 = 25+23+22+21+20 = 32+8+4+2+1 = 47
– Nf = 0.485
• 0.485 * 2 ‐> 0.970 * 2 ‐> 1.940 * 2 ‐> 3.880 * 2 ‐> 7.760 * 2
‐> 15.520 * 2 ‐> … (ci si ferma o quando la parte decimale si annulla o per approssimazione)
• Nf = 0.01111… ~ 0.011 (approssimando a solo 3 cifre in Nf) =
= 2‐2 + 2‐3 = 1/4 + 1/8 = 0.375
• N ~ 101111.011 considerando solo 3 cifre nella parte frazionaria
Esempi di conversione (continua…)
• Convertire 5210 in base 3
–
–
–
–
–
52/3 ‐> Q: 17, R: 1
17/3 ‐> Q: 5, R: 2
5/3 ‐> Q: 1, R: 2
1/3 ‐> Q:0, R: 1
5210 = 12213
• Verifica
– 12213 = 1*33 + 2*32 * 2*31 + 1*30 = 27+18+6+1 = 5210
Esempi di conversione
• Convertire 25310 in base 16
– 253/16 ‐> Q: 15, R: 13 (= D)
– 15/16 ‐> Q: 0, R: 15 (= F)
– 25310 = FD16
• Verifica
– FD16 = 15*161 + 13*160 = 240 + 13 = 25310
Riassumendo
• Conversione da qualsiasi base alla base 10
– regola posizionale
• Conversione dalla base 10 a qualsiasi base
– metodo delle divisioni successive
• E per convertire da qualsiasi base a qualsiasi altra base?
– per alcune basi specifiche ci sono altre regole specifiche
– comunque, in generale, posso sempre passare per la base 10 senza dover ricordare nessun’altra regola di conversione
Altri esempi di conversione (continua…)
• Convertire 2128 in base 2
– lo converto in base 10: 2*82+8+2 = 138
– dalla base 10 alla base 2:
•
•
•
•
•
•
•
•
•
138/2 ‐> Q: 69, R: 0
68/2 ‐> Q: 34, R: 1
34/2 ‐> Q: 17, R: 0
17/2 ‐> Q: 8, R: 1
8/2 ‐> Q: 4, R: 0
4/2 ‐> Q: 2, R: 0
2/2‐> Q: 1, R: 0
1/2 ‐> Q: 0, R: 1
2128 = 100010102
• Regola alternativa (specifica da base 8 a base 2 e viceversa)
– 2128 ‐‐‐‐‐> 2 = 010, 1 = 001, 2 = 010 ‐‐‐‐‐> 0100010102 = 100010102
– 11012 ‐‐‐‐‐> 0011012 ‐‐‐‐‐> 001 = 1, 101 = 5 ‐‐‐‐‐> 158
Altri esempi di conversione
• Convertire A416 in base 2
– lo converto in base 10: 10*161+4*160 = 164
– dalla base 10 alla base 2:
•
•
•
•
•
•
•
•
•
164/2 ‐> Q: 82, R: 0
82/2 ‐> Q: 41, R: 0
41/2 ‐> Q: 20, R: 1
20/2 ‐> Q: 10, R: 0
10/2 ‐> Q: 5, R: 0
5/2 ‐> Q: 2, R: 1
2/2‐> Q: 1, R: 0
1/2 ‐> Q: 0, R: 1
A416 = 101001002
• Regola alternativa (specifica da base 16 a base 2 e viceversa)
– A416 ‐‐‐‐‐> A = 1010, 4 = 0100 ‐‐‐‐‐> 101001002
– 1011012 ‐‐‐‐‐> 001011012 ‐‐‐‐‐> 0010 = 2, 1101 = D ‐‐‐‐‐> 2D16
Aritmetica binaria (continua…)
• Somma
–
–
–
–
0+0 = 0
0+1 = 1
1+0 = 1
1+1 = 10 ovvero 0 con riporto di 1
• 101+111 =
–
–
–
–
1+1 = 0 e riporto 1
1+0+1 = 0 e riporto 1
1+1+1 = 1 + (0 e riporto 1) = 1 e riporto 1
= 1100
Aritmetica binaria (continua…)
•
Sottrazione
–
–
–
–
•
1101‐1011 =
–
–
–
–
–
•
0‐0 = 0
0‐1 = 1 con prestito di 1
1‐0 = 1
1‐1 = 0
1‐1 = 0
0‐1 = 1 e prestito 1
1‐1‐0 = 0
1‐1 = 0
= 0010 = 10
11000‐111 =
–
–
–
–
–
–
0‐1 = 1 e prestito 1
0‐1‐1 = 1‐1 e prestito 1 = 0 e prestito 1
0‐1‐1 = 1‐1 e prestito 1 = 0 e prestito 1
1‐1‐0 = 0
1‐0 = 1
= 10001
Aritmetica binaria (continua…)
• Moltiplicazione
– 0*0 = 0
– 0*1 = 0
– 1*0 = 0
– 1*1 = 1
• 1101*101
– 1101 + 00000 + 110100 = 1000001
– 11110*1011 = 101001010
Aritmetica binaria
• Divisione
– 0/1 = 0
– 1/1 = 1
• 11011/11 = –
–
–
–
–
11/11 = 1 con resto 00
000/11 = 0 con resto 000
0001/11 = 0 con resto 0001
00011/11 = 1 con resto 00000
= 1001
• 1101011/1011 = –
–
–
–
–
1101/1011 = 1 con resto 0010
00100/1011 = 0 con resto 00100
001001/1011 = 0 con resto 001001
0010011/1011 = 1 con resto 0001000
= 1001 con resto 1000
Codifica binaria dei numeri negativi
• Rappresentazione in complemento a 2
– abbiamo visto che con n bit possiamo rappresentare i numeri naturali (>=0) nell’intervallo [0,2n‐1]
– se vogliamo rappresentare anche numeri negativi (numeri interi) sacrifichiamo il bit più significativo per la rappresentazione del segno
• 0 => la sequenza di n‐1 bit che segue è un numero positivo nell’intervallo [0,2n‐1‐1]
• 1 => la sequenza di n‐1 bit che segue è un numero negativo nell’intervallo [‐2n‐1,‐1]
• Quindi con n bit e in complemento a 2 possiamo rappresentare i numeri interi nell’intervallo
[‐2n‐1,2n‐1‐1]
Rappresentazione in complemento a 2 di un numero negativo (continua…)
• Si parte dalla rappresentazione binaria del valore assoluto (bit di segno = 0)
• Si esegue il complemento a 1 di ciascun bit
• Si aggiunge 1
• E.g., vogliamo rappresentare ‐27
– considero 27, mi servono almeno 5 bit ([0,31]) per il valore + 1 bit per il segno => almeno 6 bit per la sua rappresentazione in complemento a 2
– 27 = (00)011011
– complemento a 1 di (00)011011 = (11)100100
– (11)100100 + 1 = (11)100101 Rappresentazione in complemento a 2 di un numero negativo
• Processo inverso
– consideriamo 11100101 e il fatto che “qualcuno” ci ha detto che è rappresentato in complemento a 2
– se il bit più significativo fosse stato 0, potevamo procedere con l’usuale conversione da binario a decimale
– non è, però, il nostro caso
• complemento a 1 di 11100101 = 00011010
• aggiungo 1 a 00011010 = 00011011
• lo converto nella maniera usuale, metodo posizionale
– 00011011 = 27
Somma e sottrazione nella rappresentazione in complemento a 2
• Supponiamo di lavorare con 4 bit, quindi nell’intervallo [‐8,7]
• 2+4 = 0010 + 0100 = 0110 = 6
• 5+4 = 0101 + 0100 = 1001 = ‐7 (overflow)
• ‐2‐4 = 1110 + 1100 = [1]1010 = ‐6
• ‐5‐4 = 1011 + 1100 = [1]0111 = 7
(overflow)
• 2‐4 = 0010 + 1100 = 1110 = ‐2
• ‐5+7 = 1011 + 0111 = [1]0010 = 2
Concetti fondamentali
• Linguaggio macchina
– linguaggio basato su sequenze di bit (seq. di 0 e 1) utilizzato dai computer per memorizzare ed eseguire programmi
• per parlare ad una macchina occorre inviare segnali elettrici, on e off
• Linguaggio assembly
– rappresentazione simbolica del linguaggio macchina
– utilizza simboli, invece di numeri, per rappresentare istruzioni, registri e dati
• Linguaggio di alto livello (e.g., C, Pascal, Fortran, C++, Java, etc.)
– linguaggio il più simile possibile a quello naturale
– astrazione dalla macchina fisica
Linguaggio assembly
• Sollevare il programmatore dal dover lavorare direttamente con sequenze di bit
– identificare ciascun comando in linguaggio macchina (codice operativo) con una parola chiave più facile da ricordare (codice mnemonico)
– indirizzare le locazioni di memoria ed i registri attraverso degli identificatori testuali, anziché attraverso i loro indirizzi binari
• Programma assembly = file di testo contenente una serie di comandi
Ling. Macchina vs Ling. Assembly
MIPS32
Ling. Assembly vs Ling. Alto Livello
Assembler x86:
.model small
.stack
.data Message db "Hello World!$”
.code mov dx,OFFSET Message
mov ax,SEG Message
mov ds,ax
mov ah,9 int 21h mov ax,4c00h int 21h END
~
int main(int argc, char*
argv[]) {
printf(“Hello World!\n”);
}
Non c’è solo un assembly
• L’Assembly dipende dall’HW
– non esiste un unico assembly
– noi vedremo l’assembly per MIPS32 (assemblatore e simulatore MARS)
• Ogni CPU o famiglia di CPU ha un suo proprio assembly, diverso dagli altri
– uno specifico linguaggio assembly serve per programmare solo una specifica famiglia di CPU
Vantaggi e svantaggi
• Contro
– nessun controllo sui tipi
– il programmatore si deve occupare di ogni singolo dettaglio
– richiede un esteso lavoro di commento del codice
– minore portabilità
• Pro
– efficienza senza pari (memoria e tempo)
– controllo completo e assoluto sull’hardware (nel bene e nel male)
Assembler
• Per l’assembly, è l’analogo del compilatore per i ling. di alto livello
• Traduce un programma scritto in assembly in un equivalente programma scritto in ling. macchina MARS (continua…)
MARS
*
Architettura di un Calcolatore
MAR
DISCHI
TASTIERA
Memoria
Bus (
MBR
MEMORIA
• di alimentazione
• di controllo
• degli indirizzi
• dei dati
)
R1 R2 … Rn
MONITOR
etc.
PERIFERICHE I/O
COMPONENTI STANDARD: • ingresso
• uscita
• memoria
• unità di elaborazioni dei dati
• controllo ALU
CONTROLLO
CPU
STAMPANTI
ALIMENTATORE