informatica a.a. 2009/2010 parte 2 l’elaboratore corso a: prof. stefano berardi stefano corso b:...
Post on 03-May-2015
216 Views
Preview:
TRANSCRIPT
Informatica A.A. 2009/2010
Parte 2L’Elaboratore
Corso A: Prof. Stefano Berardi http://www.di.unito.it/~stefano Corso B: Prof. Ugo de’ Liguoro http://www.di.unito.it/~deligu
John Von Neumann
2-Elaboratore
Budapest, 28 dicembre 1903 - Washington, 8 febbraio 1957
Indice Parte 2:l’Elaboratore
1. Architettura dell’elaboratore: la macchina di von Neuman
2. La memoria: registri, memoria centrale o RAM, memoria di massa
3. L’esecuzione di un calcolo: il ciclo fetch-execute
4. Assembly: un linguaggio di programmazione “a livello macchina”.
5. Linguaggi di programmazione di alto livello: C/C++, Java, ecc.. La Compilazione.
1. L’architettura di un calcolatore
Per meglio comprendere le nozioni C++ di “indirizzo”, “contatore di programma” e “istruzione di salto” è utile conoscere l’architettura di von Neuman che sta alla base dei moderni calcolatori.
Siamo fatti così!
CPU
input
output
RAM
Per confronto, descriviamo un “calcolatore umano”
Come si organizza un essere umano per eseguire un algoritmo? Ecco una possibile risposta.
2-Elaboratore
Carta da minuta per scrivere i risultati intermedi
Procedura: fai1...2…
Dati:a,b,c
Risultati: x,y,z
Scomponiamo il nostro “calcolatore umano”
Carta da minuta per scrivere i risultati intermedi
Procedura: fai1...2…
Dati:a,b,c
Risultati: x,y,z
Memoria
IngressoUscitaUnità di
calcoloControllo
• La memoria contiene sia i passi dell’algoritmo che dobbiamo eseguire (nel il foglietto con su scritto “procedura”), sia tutti i risultati iniziali, intermedi e finali (nella “carta da minuta”).
• L’ingresso contiene i dati iniziali del problema.
• Il controllo decide cosa fare ad ogni passo.
• L’unità di calcolo è la calcolatrice che stiamo usando. Le memorie dell’unità di calcolo (della calcolatrice nel nostro esempio) sono detti registri.
• L’uscita è il risultato del calcolo.
Le componenti del nostro “calcolatore umano”
La macchina di von Neumann
Memoria centrale o RAM
Unità di controllo
Unità di calcolologico
aritmetica(ALU)
Ingresso/Uscita(I/O)
CPU (le sue memorie sono dette registri)
istruzioni dati
Una macchina descritta da von Neuman ha le stesse componenti del nostro “calcolatore umano”
2. Memoria centrale (RAM)
e memoria di massaMemorie di massa:
una bibliotecaRAM: una postazione per la consultazione
Oltre alla memoria RAM, il computer ha la memoria di massa. È come una biblioteca che possiamo consultare nella memoria RAM.
Immagini della memoria centrale (RAM) e della memoria
di massa
Memorie di massa
Memoria centrale
Hard Disk RAM
Lenta ma molto
capiente e persistente
Veloce ma poco capiente
e non persistente
2-Elaboratore
La memoria centrale (RAM)
La memoria RAM è una sequenza lineare di bytes, ovvero di liste di otto cifre 0, 1. I bytes sono numerati con interi 0, 1, 2, …, detti indirizzi di memoria.Un byte o un gruppo di bytes nella RAM si può leggere come un intero tra 0 e 255, ma può rappresentare molte cose (tutte essenziali in programmazione):• una istruzione del linguaggio della macchina (per esempio: ADD)• un numero intero o reale • l’indirizzo di memoria di: una istruzione, oppure di un numero, oppure un’altro indirizzo.
Un’immagine della RAM come lista di bytes
0 0 1 0 0 0 1 1
0 1 1 0 1 0 0 0
0 1 1 0 0 0 0 1
…
0
1
2
Un byte ha sempre un valore (binario) tra 0 e 255: non esistono celle di memoria
“indefinite”
Come si accede alla RAM?
L’accesso a una cella della memoria RAM avviene interpretando ogni cifra 0, 1 dell’indirizzo della cella mediante le biforcazioni in un “albero”. L’accesso richiede tempo uguale per tutte le celle
2-Elaboratore
Un esempio di un gruppo di istruzioni contenute nella RAM
ADD800428884
012
k
...
... ADD(numero istr. somma) 800 428 884
ADD è il numero dell’istr. somma, i cui argomenti sono due memorie numerate 428 e 884, con risultato scritto nella memoria numero 800. Nota: sommare le memorie di numero 428 e 884 non significa sommare 428 e 884! Magari la
A fianco, vediamo 4 bytes consecutivi della RAM che contengono:
memoria numero 428 contiene 42 e la memoria numero 884 contiene 12. 800 non è il risultato ma il numero della memoria in cui scriviamo il risultato 54
3. Il ciclo di calcolo della macchina di von
NeumannOgni singolo calcolo richiede
tipicamente un ciclo di cinque passi:
1. “Fetch” istruzione (copia l’instruzione dalla RAM in un registro)
2. Decodifica istruzione
3. “Fetch” Dati (copia i dati dalla RAM in registri)
4. Esecuzione Istruzione, con risultato in un registro.
5. Copia del risultato all’indietro, nella RAM
2-Elaboratore
Il ciclo Fetch/Execute
2-Elaboratore
Come esempio vedremo come un passo del ciclo Fetch/Execute esegue la somma (42+12)
1.2.3.4.5.
Unità di controllo (CPU)
• Implementa il ciclo macchina direttamente attraverso i circuiti o hardware. I suoi circuiti recuperano un’istruzione dalla memoria ed eseguono altre operazioni del ciclo
1.un’istruzione tipica è per es.: ADD 800 428 884
2.quest’istruzione chiede che i numeri memorizzati negli indirizzi 428 e 884 siano sommati dalla ALU e che il risultato sia inserito nell’indirizzo 800
3.il passo “Fetch Dati” estrae i due valori; dopo aver effettuato la somma il passo Restituzione Risultato inserirà la somma nell’indirizzo 800
Unità Aritmetico/Logica ALU
• È parte della CPU.
• Esegue tutti i calcoli nei registri ma dispone di poca memoria (i soli registri). Generalmente la ALU è responsabile del passo del ciclo macchina denominato Esecuzione Istruzione
• Un circuito nella ALU può sommare due numeri. Ci sono anche circuiti dedicati alla moltiplicazione, al confronto di due numeri ecc.
• Le istruzioni di puro trasferimento dei dati da e verso la RAM non usano la ALU.
2-Elaboratore
Relazione tra ALU e RAM
• Il passo del ciclo macchina Fetch Dati recupera dalla RAM i valori necessari alla ALU (i valori degli operandi).
• Quando la ALU ha completato l’operazione, il passo Restituzione Risultato trasferisce il risultato (somma o prodotto o qualche altro valore) dalla ALU in un indirizzo di memoria della RAM specificato nell’istruzione
2-Elaboratore
Il Program Counter (PC)
• Per determinare l’istruzione successiva nell’esecuzione di un programma, il suo indirizzo è memorizzato in un registro della UC chiamato Program Counter (PC) o contatore di programma.
• Se (poniamo) le istruzioni occupano 4 byte di memoria, l’istruzione successiva dovrebbe essere PC + 4
• Il PC è incrementato di 4: quando il ciclo macchina ritornerà al passo Fetch Istruzione, il PC “indicherà” l’istruzione successiva 2-Elaboratore
Istruzioni di “salto” per il PC (Program
Counter)• In programmazione, è essenziale il fatto che una istruzione può includere l’indirizzo dell’istruzione successiva.
• Queste istruzioni sono dette “salti” o jumps. Il salto può essere incondizionato se avviene sempre, condizionato se avviene solo quando una certa condizione è vera.
• Quando eseguiamo una istruzione di “salto” il contatore di programma, invece di aggiungere 4 automaticamente, "salta" alla locazione specificata, magari a un miliardo di bytes di distanza.
2-Elaboratore
Un esempio: il calcolo di 42+12
• Il computer interpreta i nostri comandi, espressi nel suo linguaggio fatto di 0 e 1
• Prima che il ciclo macchina inizi, qualche locazione di memoria e il PC sono visibili nell’unità di controllo
• Vediamo come il ciclo Fetch/Execute calcola 42 + 12, supponendo che il due numeri si trovino nelle memorie numero 428 e 884, e che il risultato, 54, venga scritto nella memoria 800. Indichiamo sempre con ADD il numero dell’istruzione “somma”.
Lo stato del computer all’inizio dell’istruzione
ADD
Supponiamo PC=2200. Il controllo sta eseguendo l’istruzione 2200, che richiede di sommare le memorie numero 428 e 884, e di scrivere il risultato nella memoria 800. 2-Elaboratore
PC:2200
2200 ADD 800, 428, 884
Passo 1: Fetch istruzioni
• L’esecuzione comincia trasferendo dalla memoria a un registro dell’unità di controllo l’istruzione ADD, rappresentata da un numero, e contenuta nell’indirizzo 2200 specificato dal PC, quindi gli indirizzi 800, 428, 884.
2200 ADD 800, 428, 884
ADD 800, 428, 884
PC:2200
Passi 2,3: Decodifica/Fetch dati
• I bits dell’istruzione ADD, decodificati dal controllo, attivano un circuito della ALU capace di eseguire l’operazione di somma (al numero dell’istruzione associamo il circuito che esegue l’istruzione)
• Una volta fatto questo, il controllo incrementa il PC da 2200 a 2204, per preparare la lettura dell’istruzione successiva.
• Nel passo dopo, il controllo cerca gli argomenti dell’addizione, 42 e 12, nelle memorie RAM di numero 428 e 884, quindi li copia nei registri del circuito somma dentro l’unita’ logico-aritmetica.
2-Elaboratore
Il controllo copia l’operazione e i dati dell’operazione nell’ALU
2-Elaboratore
Circuito somma
[ ][ ][ ]
ADD 800, 428, 884
PC:2204
2200: ADD 800, 428, 884
Circuito somma
[42][12][ ]
ADD 800, 428, 884
PC:2204
2200:428:884:
ADD 800, 428, 8844212
Passo 4: Esecuzione istruzioni
Esecuzione Istruzione. • Finalmente arriviamo al passo in cui
sono effettivamente eseguiti i calcoli, la somma di 42 e 12 in questo caso.
• Non era possibile eseguire i calcoli nella RAM, che è solo capace di ricordare e ricopiare. È invece possibile eseguire i calcoli dopo aver copiato il numero dell’operazione e i suoi argomenti nell’unita’ logico-aritmetica ALU.
2-Elaboratore
2-Elaboratore
2-Elaboratore
Circuito somma
[42][12][ 54]
ADD 800, 428, 884
PC:2204
2200:428:884:800:
ADD 800, 428, 8844212
l’ALU inserisce il risultato della somma in un registro
Passo 5: Restituzione risultato
• Restituzione Risultato. L’unita’ logico-aritmetica non è capace di ricordare molti dati: per questo c’è la RAM.
• Il controllo deve quindi ricopiare il risultato della somma nella locazione di memoria RAM specificata dall’indirizzo 800
• Una volta concluso questo passo, il ciclo ricomincia
2-Elaboratore
2-Elaboratore
Circuito somma
[42][12][ 54]
ADD 800, 428, 884
PC:2204
2200:428:884:800:
ADD 800, 428, 884421254
l’ALU restituisce il risultato della somma nella RAM
4. Il linguaggio assembly
• La macchina vede le istruzioni come una lunga sequenza di “parole” o gruppi di 4 bytes.
• Ogni sistema operativo (per es., Windows), invece, ha un proprio linguaggio assembly, che rappresenta il linguaggio macchina usando lettere e numeri in luogo del codice binario (per es., ADD per la somma oppure JB per l’istruzione di salto condizionato).
• Ogni sistema operativo ha un programma (chiamato assembler) che converte il programma assembly in cifre binarie. Un programma assembly è scritto in un linguaggio di abbreviazioni di facile traduzione in binario.
Esempio di programma in assembly con un solo registro dati: AX COPY AX M0
L1 ADD AX M1
OUT AX
CMP AX M10
JB L1
Tra le istruzioni elencate sopra, è particolarmente importante l’istruzione JB L1 di “salto” del program counter all’indirizzo L1 di una istruzione anche molto lontana del programma quando una precedente condizione è vera.
Copia AX:=M0 Somma AX:=AX+M1 Stampa di AX
Confronto tra AX, M10“salto del contatore all’istruz. L1 se il confronto precedente è vero
Una CPU semplificata
Instruction Pointer (PC o IP)
Instruction Register (IR)
Condition flag (CF)
Accumulator (AX)
PC indirizzo istruzione da eseguire istruzione da associare a un circuito
Contiene “true” o “false”
Unico registro dati AX. Contiene il valore corrente del calcolo
2-Elaboratore
Un esempio di linguaggio AssemblyIstruzione Formato Azione
Copia dalla mem. COPY AX mem AX := mem
Copia nella mem. COPY mem AX mem := AX
Somma ADD AX mem AX := AX + mem
Sottrazione SUB AX mem AX := AX – mem
Moltiplicazione MUL AX mem AX := AX * mem
Divisione DIV AX mem AX := AX / mem
Confronto (assegna un booleano a CF)
CMP AX mem CF := TRUE se AX < mem CF := FALSE altrimenti
Salto incondizionato JMP label PC := label
Salto condizionato JB label PC := label se CF = TRUE
Salto condizionato JNB label PC := label se CF = FALSE
Input IN AX Inserisce l’ingresso in AX
Output OUT AX Stampa il contenuto di AX
In assenza di istruzioni particolari, all’indirizzo PC si assegna PC:=PC+1
Un programma ASSEMBLY
COPY AX M0
L1 ADD AX M1
OUT AX
CMP AX M10
JB L1
1. Copia in AX il contenuto di M0
2. Somma ad AX il contenuto di M1 sovrascrivendolo ad AX
3. Stampa il contenuto di AX
4. Confronta il contenuto di AX con quello di M10
5. Se al passo 4 AX < M10 allora fa saltare il contatore di programma all’istruzione L1
Le istruzioni ASSEMBLY per eseguire AX:=M0 e ripetere l’assegnazione AX=AX+M1 finche’ AX < M10
Trovate un simulatore per questo ASSEMBLY nel sito del corso 2-Elaboratore
5. Linguaggi di programmazione
• Programmare in assembly è complicato, perché, necessariamente, l’uso di istruzioni molto elementari trasforma in lunghe sequenze di codice anche delle semplici operazioni:
stampa a*b + d*c;
COPY AX aMUL AX bCOPY temp AXCOPY AX dMUL AX cADD AX tempOUT AX
Operazione
Codice assembly
2-Elaboratore
Linguaggi di programmazione• Per ovviare sono stati introdotti i
linguaggi di programmazione, lingue artificiali per la definizione di programmi, simili all’algebra e ad un rudimentale inglese:
Pascal, C, C++, Java, C#, … intermedie tra il linguaggio umano e
il linguaggio Assembly, che a sua volta deve venire tradotto in liste di 0, 1 (l’unico linguaggio che la macchina capisca!)
2-Elaboratore
Esempio di codice in un linguaggio d’alto livello
I programmi in C++, Java, ecc. hanno questo aspetto.
La compilazione
• Il codice di un linguaggio di alto livello, come il C/C++, non è immediatamente eseguibile.
• Prima occorre tradurlo in Assembler, creando un programma “eseguibile” (in Windows, un file “.exe”), poi in linguaggio macchina.
• Alla prima traduzione provvede il compilatore, alla seconda il sistema operativo.
• Due macchine con lo stesso sistema operativo capiscono lo stesso linguaggio Assembly, e quindi gli stessi file “eseguibili”, anche se il loro linguaggio macchina è diverso.
L’effetto della compilazione
total =num1+num1;
2-Elaboratore
ADD 20 20 24
00000010 10011000 10100000 00100000
Le tre forme principali di codifica del software: il linguaggio di programmazione, il linguaggio assembly (del sistema operativo) e il linguaggio macchina.
Linguaggio di programmazione
Linguaggio assembler
Rappresentazione binaria
Le fasi della compilazione
1. Fase 1. Si scrive il testo del programma, ad es. in C++, utilizzando un text editor: il risultato è il programma sorgente (file .cpp).
2. Fase 2. Questo file è dato in ingresso al compilatore, che ne controlla innanzitutto la correttezza sintattica (parsificazione).
3. Fase 3. Se ci sono errori, il compilatore genera un file di diagnosi (il .log); altrimenti lo traduce in codice machina: binario (in Unix) o eseguibile (in Windows: un file .exe).
Un file .exe si può trasferire da una macchina a un’altra con lo stesso sistema operativo.
2-Elaboratore
Le fasi della programmazione
Text editor
Parser
Traduttore
Ok?
compilatore
sorgente
logeseguibile
sì no
Fase 1
Fase 2
Fase 3
2-Elaboratore
Un ambiente integrato
• Un ambiente integrato unisce in un unico programma l’editor ed il compilatore (ed altro ancora). Noi usiamo il wxDev-C++:
http://wxdsgn.sourceforge.net/
2-Elaboratore
Quali errori può scoprire il compilatore?
Non esiste alcuna procedura automatica ed uniforme che
possa decidere se un programma è logicamente
corretto, né se una sua esecuzione produrrà un
risultato!
Alan M. Turing
Tuttavia possiamo descrivere formalmente la grammatica di un linguaggio di programmazione e
decidere se il testo di un programma rispetta la
grammatica data
Noam Chomsky
2-Elaboratore
Un circolo vizioso: chi compila il compilatore?
• I primi compilatori (gli assemblatori) furono scritti in linguaggio macchina!
• Ogni compilatore, una volta tradotto in un eseguibile, può essere usato per tradurre in un eseguibile il compilatore di un nuovo linguaggio più evoluto. È come se ci fosse una catena umana dai linguaggi più semplici a quelli più evoluti.
Assembly
C
Java
2-Elaboratore
Java
C
Assembly
Interpreti• Vale la pena accennare che non tutti
linguaggi sono compilati: alcuni si servono di un interprete, ossia di un programma che legge il sorgente riga per riga, ne riconosce le istruzioni ed esegue le azioni corrispondenti.
Un programma compilato non ha bisogno del
compilatore durante l’esecuzione;
un programma interpretato invece ha sempre bisogno
dell’interprete.2-Elaboratore
Architettura del calcolatore e C++• Le nozione centrali di ogni passo del ciclo di
calcolo sono: la nozione di indirizzo di memoria e di istruzione di salto.
• Nella sezione 3 vedremo come una variabile in C++ sia essenzialmente il contenuto di un indirizzo di memoria di una macchina di von Neumann.
• Una delle nozioni fondamentali del linguaggio C++, forse la più importante, è proprio la nozione di indirizzo di memoria.
• Nella sezione 4 vedremo, invece, come il C++ evita l’uso delle istruzioni di salto, rimpiazzandole con le istruzioni IF, WHILE, FOR, …
2-Elaboratore
Riepilogo
• Le parti principali di un calcolatore sono la memoria e la CPU;
• ciascun calcolatore “comprende” un unico linguaggio macchina;
• i programmi scritti in C/C++ (o in un altro linguaggio di alto livello) devono essere tradotti in linguaggio macchina da un compilatore;
• è l’esistenza dei compilatori (e degli interpreti) ciò che rende “poliglotti” i computer (in realta’, ogni computer comprende solo il proprio linguaggio macchina).
2-Elaboratore
top related