IL LINGUAGGIO DEL CALCOLATORE
Presentiamo un esempio di linguaggio macchina, cioè di quello
compreso direttamente dal calcolatore, per una
macchina come quella
vista precedentemente.
Un'istruzione è una sequenza di bit, dove una parte di
questi
bit definisce il codice operativo, mentre i rimanenti definiscono gli
operandi.
In questo caso
- istruzione lunga 16 bit
- codice operativo: 4 bit (al più 16 istruzioni)
- operandi:12 bit (lunghezza degli indirizzi della memoria)
Esecuzione di un'istruzione
L'attività del calcolatore consiste nel leggere ed eseguire le istruzioni del
programma (che si trovano in memoria centrale) a partire da un preciso
indirizzo.
L'esecuzione di un'istruzione si svolge in tre fasi, regolate dal clock:
-
Acquisizione dell'istruzione dalla memoria centrale (fase di fetch)
-
- RI <- PC
- RD <- MEM[RI]
- RIC <- RD
- PC <- PC +1
-
Interpretazione
- l'unità di controllo esamina il codice operativo
dell'istruzione in RIC
- esecuzione vera e propria
- differente per ogni istruzione (vedremo dopo), può modificare
anche il PC
Unità di misura per la velocità delle CPU
HERTZ = 1 ciclo per secondo
attualmente la velocità sono dell'ordine di MHz (Megahertz), o milioni di cicli
per secondo
PC: 33 Megahertz
CRAY Y-MP: 178 Megahertz
Principali istruzioni
loada
(loadb
): lettura della memoria
-
l'operando è un indirizzo di celle della memoria
il contenuto della cella individuata dall'operando viene copiato nel
registro A (B) (usando RI e RD)
storea
(storeb
): scrittura della memoria
-
l'operando è un indirizzo di celle della memoria
il contenuto del registro A (B) viene copiato
nella cella individuata dall'operando (usando RI e RD)
read
: lettura da una periferica
-
l'operando è un indirizzo di celle della memoria
un dato fornito dalla periferica
(presente nel registro RDP dell'interfaccia)
viene copiato nella cella individuata dall'operando
write
: scrittura su una periferica
-
l'operando è un indirizzo di celle della memoria
il contenuto della cella individuata dall'operando viene copiato
nel registro RDP dell'interfaccia
add
, dif
,
mult
, div
:
operazioni aritmetiche
- non hanno operandi
l'operazione viene eseguita sui dati presenti nei registri A e B, il
risultato viene messo in A, nel caso della divisione il resto viene messo in B
jump
: salto incondizionato
- determina quale istruzione eseguire al passo successivo
l'operando è un indirizzo di celle della memoria
il contenuto della cella individuata dall'operando viene copiato
nel registro PC
jumpz
: salto condizionato
- determina quale istruzione eseguire al passo successivo in dipendenza
da una condizione
l'operando è un indirizzo di celle della memoria
se il contenuto del registro A è 0, allora
il contenuto della cella individuata dall'operando viene copiato
nel registro PC, altrimenti non fa niente
halt
: fine
- fa terminare l'esecuzione del programma
Un programma consiste di una sequenza di istruzioni, quindi una sequenza di
sequenze di bit.
Linguaggio assembler
È quasi impossibile scrivere direttamente un programma in linguaggio
macchina, pertanto si usa qualcosa di più adatto agli umani, il cosidetto
linguaggio assembler.
- Le istruzioni sono individuate da codici memmonici (
loada
,
write
, ...)
- Gli indirizzi delle celle di memoria che contengono dati sono denotati
da nomi simbolici (nomi di variabili).
Le celle di memoria denotate da nomi simbolici usate in un programma
sono elencate all'inizio del medesimo.
- Gli indirizzi delle celle che contengono istruzioni sono denotati da
nomi simbolici scritti a sinistra delle istruzioni (etichette)
-
** commento
indica una linea di commento all'interno del programma
Esempio di programma assembler: sommare 10 volte un numero
Nel seguito assumiamo che alcune celle scelte a priori contengono dei
valori particolari, precisamente ZERO
, UNO
e
DIECI
contenenti
rispettivamente 0, 1 e 10.
Primo passo descrizione schematica dell'algoritmo
** leggo il numero e lo metto nella cella NUMERO
** metto 0 nella cella CONT
** (contatore del numero di volte che la somma è stata fatta)
** metto 0 nella cella SOMMA (contiene la somma corrente)
** mentre il contatore è minore di 10
** incremento di 1 CONT
** sommo NUMERO a SOMMA
** scrivo sull'output il contenuto di SOMMA
raffino realizzando il ciclo con i jump
** leggo il numero e lo metto nella cella NUMERO
** metto 0 nella cella CONT
** (contatore del numero di volte che la somma è stata fatta)
** metto 0 nella cella SOMMA (contiene la somma corrente)
** CICLO: incremento di 1 CONT
** sommo NUMERO a SOMMA
** se CONT è minore di 10, allora vado a CICLO
** scrivo sull'output il contenuto di SOMMA
programma in assemblerNUMERO, CONT, SOMMA
** leggo il numero e lo metto nella cella NUMERO
read NUMERO
** metto 0 nella cella CONT
** (contatore del numero di volte che la somma è stata fatta)
loada ZERO
storea CONT
** metto 0 nella cella SOMMA (contiene la somma corrente)
loada ZERO
storea SOMMA
** CICLO: incremento di 1 CONT
CICLO:
loada UNO
loadb CONT
add
storea CONT
** sommo NUMERO a SOMMA
loada NUMERO
loadb SOMMA
add
storea SOMMA
** se CONT è minore di 10, allora vado a CICLO
loada CONT
loadb DIECI
dif ** contiene 0 se CONT è uguale a 10
jumpz FINE
jump CICLO
** scrivo sull'output il contenuto di SOMMA
FINE: write SOMMA
halt
ESERCIZI
- Eliminare le istruzioni inutili, se ce ne sono, nel programma precedente.
- Scrivere un programma in linguaggio Assembler per calcolare l'elevamento a
potenza, sia la base che l'esponente vengono dati come input.
- Scrivere un programma in linguaggio Assembler che ritorna la somma di
tre numeri ricevuti in input.