Ing. Paolo Domenici
SISTEMI A MICROPROCESSORE
PREFAZIONE
Il corso ha lo scopo di fornire i concetti fondamentali dei sistemi a microprocessore in modo semplice e interattivo.
È costituito da una parte teorica e da una serie di esercitazioni.
Nella parte teorica vengono descritte sinteticamente le caratteristiche di un semplice elaboratore,
l’architettura interna del microprocessore, le principali istruzioni e la struttura di un programma.
Le esercitazioni si dividono in due parti:
nella prima vengono affrontati i problemi relativi allo scambio di dati fra CPU,
memoria e dispositivi di I/O,
nella seconda vengono scritti ed eseguiti semplici programmi in linguaggio macchina.
Le esercitazioni vengono effettuate mediante un programma di simulazione, realizzato utilizzando il
foglio elettronico Excel.
N.B.
Per un corretto funzionamento dei programmi di simulazione, è necessario impostare il numero
di iterazioni massimo pari a 5.
Per far ciò, una volta aperto il foglio elettronico Excel, seguire il seguente percorso:
STRUMENTI – OPZIONI – CALCOLO – NUMERO MAX. DI ITERAZIONI: 5.
(ing. Paolo Domenici)
SISTEMI A MICROPROCESSORE
INTRODUZIONE
I sistemi elettronici tradizionali, detti sistemi a logica cablata, sono costituiti soltanto dalla parte fisica
(hardware), cioè dal circuito stampato, dai componenti passivi e attivi ecc.
Essi sono in grado di svolgere soltanto la funzione per la quale sono stati progettati.
Per modificare tale funzione è necessario modificare o sostituire il dispositivo.
I sistemi a logica programmata, oltre alla parte hardware, sono dotati anche di una parte software, costituita da
un programma residente nella memoria di lavoro, cioè da una serie di istruzioni, senza la quale non sarebbero in grado
di funzionare.
I sistemi programmabili sono pertanto molto flessibili, adatti cioè a svolgere numerose funzioni, per modificare
le quali è sufficiente cambiare il programma, lasciando inalterata la struttura fisica.
*********
STRUTTURA DELL’ELABORATORE ELETTRONICO
Un elaboratore elettronico è un sistema programmabile, generalmente composto da tre unità
fondamentali: l’Unità Centrale (CPU), l’Unità di Ingresso/Uscita (I/O) e la Memoria, collegati
fra loro da tre bus: il bus dati, il bus indirizzi e il bus controlli.
La CPU (Central Processing Unit = unità centrale di elaborazione) è l’elemento principale
del sistema. Ha lo scopo di dirigere tutte le operazioni e di eseguire i calcoli.
E’ costituita dall’ Unità di Controllo (UC), dall’ Unità Logico – Aritmetica (ALU) e da
una serie di
Registri.
L’UC coordina tutti i trasferimenti dei dati fra i blocchi della CPU e genera i segnali di
controllo.
L’ ALU esegue le operazioni aritmetiche e logiche.
L’Unità di I/O permette lo scambio di informazioni fra la macchina e il mondo esterno.
La Memoria contiene la sequenza di parole binarie che costituiscono il programma.
Ogni dato, che può essere il codice di un’istruzione o un dato numerico, è memorizzato in una cella
(o locazione), individuata da un numero, detto indirizzo.
Quando la CPU deve leggere o scrivere un dato in una cella di memoria, invia il corrispondente
indirizzo attraverso il bus indirizzi. Un particolare circuito interno alla memoria provvederà a
selezionare la corrispondente cella, il cui contenuto sarà trasferito su un buffer a tre stati, che
costituisce l’interfaccia fra la memoria e il bus dati.
I Registri sono memorie temporanee, costituite da un insieme di flip-flop di tipo D, che ha lo scopo
di memorizzare i dati. I registri più comuni sono:
l’Accumulatore, che serve per contenere i risultati delle operazioni effettuate mediante l’ALU;
il Program Counter, che contiene l’indirizzo della prossima istruzione che deve essere eseguita;
il Registro degli Indirizzi, che costituisce l’interfaccia fra la CPU e il bus indirizzi, poiché contiene
l’indirizzo della cella di memoria o del dispositivo di I/O con cui la CPU deve scambiare
informazioni;
il Registro dei Dati, che costituisce l’interfaccia fra la CPU e il bus dati, poiché memorizza tutti i
dati che devono essere scritti o letti dalla memoria o dai dispositivi di I/O;
il Registro delle Istruzioni, in cui viene memorizzato il codice delle istruzioni che devono essere
eseguite;
il Puntatore di Stack, che contiene indirizzi relativi ad una particolare parte di memoria, chiamata
stack, in cui viene memorizzato temporaneamente il contenuto di alcuni registri (ad esempio il
contenuto del contatore di programma, quando viene eseguita una subroutine);
il Registro di Stato, che contiene informazioni sul risultato di un’operazione.
Oltre ai registri citati, ve ne sono altri di uso generale, che variano a seconda del tipo di CPU. Un
circuito integrato che implementa una CPU è detto Microprocessore.
*********
LETTURA DI DATI DALLA MEMORIA
La memoria di un sistema a microprocessore è costituita da un certo numero di celle in cui sono
memorizzate le informazioni, da un circuito di selezione e da un buffer a tre stati, necessario per
l’interfacciamento con il bus dati.
Per leggere un dato dalla memoria sono necessarie le seguenti operazioni:
1. Selezione della cella mediante mediante l’invio del corrispondente indirizzo attraverso il bus
indirizzi.
2. Selezione del chip di memoria mediante l’invio, attraverso una particolare linea del bus
controlli, di un segnale di abilitazione. Nel caso che stiamo esaminando, tale operazione
consiste nel porre il segnale MREQ/IORQ = 1.
3. Invio di un segnale di lettura attraverso il bus controlli.
Nel caso in esame si pone R/W = 1.
ESERCITAZIONE N° 1
Selezionare alcune celle di memoria e trasferire il relativo contenuto nel registro dei dati.
Osservazione:
Per semplicità di scrittura, i numeri si scrivono in codice decimale, anziché in codice binario, come
avviene nei microprocessori reali.
Eseguire la simulazione mediante il file Simulazione CPU1, da aprire con Excel.
*********
LETTURA DI DATI DAI DISPOSITIVI DI I/O
I dispositivi di I/O permettono alla CPU di effettuare lo scambio di informazioni con il mondo
esterno.
Per accedere ad un dispositivo di ingresso o di uscita, nel caso in cui non venga utilizzata la
mappatura di memoria, è necessario effettuare le seguenti operazioni:
1) inviare l’indirizzo del dispositivo con cui ci si vuole collegare;
2) inviare, mediante un’opportuna linea del BUS CONTROLLI, un segnale di abilitazione
dell’unità di I/O (nel caso in esame porre MREQ/IORQ=0);
3) inviare un segnale di lettura o scrittura (R/W).
ESERCITAZIONE N° 2
Effettuare lo scambio di dati fra CPU e unità di I/O.
Eseguire la simulazione mediante il file Simulazione CPU1, da aprire con Excel.
*********
SCRITTURA DI DATI NELLA MEMORIA
Per effettuare un’operazione di scrittura di dati nella memoria RAM si eseguono le stesse
operazioni relative alla lettura, ponendo però R/W = 0.
ESERCITAZIONE N° 3
Effettuare operazioni di scrittura e lettura nella memoria RAM.
Eseguire la simulazione mediante il file Simulazione CPU1, da aprire con Excel.
*********
PROGRAMMAZIONE DEL MICROPROCESSORE
Il microprocessore, per funzionare, ha bisogno di un programma, cioè di una serie di istruzioni
codificate mediante parole di 4, 8, 16 o più bit.
Le istruzioni si dividono in
ISTRUZIONI DI TRASFERIMENTO, ISTRUZIONI ARITMETICHE, ISTRUZIONI
LOGICHE, ISTRUZIONI DI CONTROLLO, ISTRUZIONI DI SALTO.
Ogni istruzione è formata da un codice operativo e da un operando.
I tipi più comuni di indirizzamento sono:
INDIRIZZAMENTO
INDICIZZATO.
IMPLICITO,
IMMEDIATO,
DIRETTO,
INDIRETTO,
Il microprocessore è in grado di riconoscere solo programmi scritti in linguaggio macchina, in cui
anche il codice operativo è costituito da un numero binario.
Poiché non è facile comprendere tale linguaggio, è stato ideato un linguaggio mnemonico, dello
Assembly, in cui, al codice operativo di ogni istruzione, è associata una parola inglese abbreviata, di
più semplice comprensione.
Particolari programmi, detti compilatori assembly, o assemblatori, provvederanno a tradurre il
programma assembly, detto programma sorgente, nel corrispondente programma in linguaggio
macchina, detto programma oggetto, che il microprocessore è in grado di riconoscere e di eseguire.
Le istruzioni di un programma assembly dipendono dal tipo di microprocessore, per cui faremo
riferimento ad un semplice microprocessore didattico, costituito dagli elementi essenziali ed avente
un set di istruzioni ridotto, che riportiamo nella seguente tabella:
LDA# n = carica nell’accumulatore il numero n.
È un’istruzione di trasferimento dati, con indirizzamento immediato, in quanto il numero n, che
costituisce l’operando, viene caricato, cioè memorizzato, nell’accumulatore.
Questa istruzione, tradotta in linguaggio macchina, occupa due celle di memoria: la prima contiene il
codice operativo, cioè il numero binario corrispondente alla sigla LDA#, mentre la seconda contiene
l’operando, cioè il numero n.
STA n = scarica il contenuto dell’accumulatore nella cella di indirizzo n.
È un’istruzione di trasferimento dati, con indirizzamento diretto, in quanto il numero n, che
costituisce l’operando, è l’indirizzo della cella di memoria in cui viene memorizzato il dato contenuto
nell’accumulatore.
(Si osservi che, al termine dell’operazione, l’accumulatore non viene azzerato, ma contiene ancora il
numero n).
Anche questa istruzione, come la precedente, occupa due celle di memoria.
ADD# n = somma il numero n al contenuto dell’accumulatore e scrivi il
risultato
ottenuto nell’accumulatore stesso.
È un’istruzione aritmetica con indirizzamento immediato, che occupa due celle di memoria.
Al termine di tale istruzione il contenuto dell’accumulatore viene modificato.
SUB# n = sottrai il numero n al contenuto dell’accumulatore e scrivi il
risultato
ottenuto nell’accumulatore stesso.
È un’istruzione aritmetica con indirizzamento immediato, che occupa due celle di memoria.
Al termine di tale istruzione il contenuto dell’accumulatore viene modificato.
IN n = legge
il dato presente nella periferica di ingresso di indirizzo n e lo trasferisce
nell’accumulatore.
È un’istruzione di trasferimento con indirizzamento diretto. Occupa due celle di memoria.
OUT n = invia il dato presente nell’accumulatore alla periferica d’uscita di indirizzo n.
È un’istruzione di trasferimento con indirizzamento diretto. Occupa due celle di memoria.
HLT = ALT.
È un’istruzione di controllo, con indirizzamento implicito. Questo significa che è costituita dal solo
codice operativo, senza operando. Per questo occupa una sola cella di memoria. La sua funzione è
quella di bloccare il microprocessore. Questa istruzione viene scritta al termine del programma.
JMP n = salta alla posizione di memoria di indirizzo n.
È un’istruzione di salto incondizionato, con indirizzamento diretto.
Quando il microprocessore incontra questa istruzione, non esegue quella successiva, ma salta a quella
avente indirizzo n, cioè a quella scritta nella cella di memoria numero n.
Occupa due celle di memoria.
JZ
n = salta alla posizione di memoria di indirizzo n solo se il contenuto dell’accumulatore è zero.
È un’istruzione di salto condizionato, con indirizzamento diretto.
Quando il microprocessore incontra questa istruzione, non esegue quella successiva, ma salta a quella
avente indirizzo n, cioè a quella scritta nella cella di memoria numero n, solo se il numero contenuto
nell’accumulatore è uguale a zero.
Occupa due celle di memoria.
Un programma assembly è costituito da una serie di istruzioni come quelle viste sopra, ognuna delle quali è preceduta
da una label, o etichetta, che corrisponde all’indirizzo della cella di memoria in cui è scritto il codice operativo
dell’istruzione stessa.
Ad esempio, se vogliamo caricare nell’accumulatore il numero 25, dovremo scriviere il seguente programma assembly:
0 LDA# 25
2 HLT
Nella cella di indirizzo 0 verrà scritto un numero binario corrispondente alla sigla LDA#.
Nella cella successiva, avente indirizzo 1, verrà scritto il numero 25, convertito in codice binario.
Nella cella di indirizzo 2 verrà invece scritto il numero binario corrispondente all’istruzione HLT.
Se vogliamo eseguire la somma di due numeri, dobbiamo caricare il primo nell’accumulatore e sommare ad esso il
secondo.
Supponiamo, ad esempio, di voler eseguire la somma dei numeri 25 e 48.
Il corrispondente programma è il seguente:
0 LDA# 25
2 ADD# 48
4 HLT
Supponiamo ora di voler memorizzare il risultato ottenuto nel precedente programma in una cella di indirizzo 100.
Il programma completo è il seguente:
0 LDA# 25
2 ADD# 48
4 STA 100
6 HLT
Supponiamo invece di voler visualizzare tale risultato su un display. Facendo riferimento al microprocessore didattico
su cui faremo le simulazioni, l’indirizzo del display è 1.
Dovremo scrivere il seguente programma:
0 LDA# 25
2 ADD# 48
4 OUT 1
6 HLT
Se vogliamo inviare alla CPU un numero, ad esempio il numero 25, utilizzando una tastiera, che, nel caso in esame ha
indirizzo 0, trasferirlo nella cella di indirizzo 100 e visualizzarlo sul display, dobbiamo scrivere il seguente programma:
0 IN 0
2 STA# 100
4 OUT 1
6 HLT
Analizziamo ora un esempio che richiede le istruzioni di salto.
Vogliamo scrivere un programma che legga ciclicamente un dato dalla tastiera, finché non venga digitato un codice
segreto (ad esempio il numero 45).
La prima istruzione deve essere un’istruzione di input, che carica nell’accumulatore il numero digitato.
Segue un’istruzione aritmetica, che effettua il confronto fra il numero presente nell’accumulatore e il numero 45.
Tale istruzione esegue la differenza fra i due numeri, che viene memorizzata nell’accumulatore.
Se i due numeri sono uguali, il numero contenuto nell’accumulatore è uguale a zero.
A questo punto è sufficiente un’istruzione di salto condizionato ad un indirizzo contenente l’istruzione HLT.
Se il contenuto dell’accumulatore è diverso da zero, tale salto non viene effettuato e il programma esegue l’istruzione
successiva, che consiste in un salto incondizionato all’inizio del programma.
Il listato corrispondente a tale programma è quello di seguito riportato:
0 IN 0
2 SUB# 45
4 JZ 8
6 JMP 0
8 HLT
ESERCITAZIONE N°4
Scrivere ed eseguire semplici programmi, come quelli sopra riportati,
mediante la seguente procedura:
a) Scrivere il programma in linguaggio assembly.
b) Tradurlo in linguaggio macchina, utilizzando la tabella riportata nel programma di simulazione.
c) Ricopiare il listato così ottenuto nella memoria ROM del sistema a microprocessore virtuale relativo al suddetto
programma.
d) Eseguire il programma.
Per l’esecuzione, procedere nel modo seguente:
• Resettare il sistema, ponendo RESET = 0.
• Riattivare il sistema, ponendo RESET = 1.
• Incrementare di una unità per volta l’indirizzo, per eseguire, passo-passo, le varie istruzioni.
(Per scrivere l’indirizzo delle celle di memoria con le quali ci si deve collegare, utilizzare l’apposita casella
riportata in basso).
L’esecuzione di alcune istruzioni richiedono operazioni supplementari, che sono indicate nelle righe scritte sotto il
titolo, in cui viene riportata una semplice descrizione delle operazioni svolte.
Osservazione:
Per semplicità di scrittura e di realizzazione, sono stati adottati alcuni accorgimenti, che non corrispondono ai sistemi
reali:
• I numeri si scrivono in codice decimale, anziché in codice binario.
• I dati non possono superare il valore 999, perché i numeri maggiori corrispondono ai codici operativi.
Eseguire la simulazione mediante il file Simulazione CPU2, da aprire con Excel.