L'esperienza comprata non conta
MICROPROCESSORI E MICROCONTROLLORI
… studiare, studiare ed ancora studiare,
è il solo modo di capire quanto possa
essere grande sia la propria ignoranza!
MICROPROCESSORE 8086-8088
Uno degli aspetti più importanti della programmazione di un
microprocessore è costituito dalla tecnica d’indirizzamento.
Per tecnica d’indirizzamento si intende il metodo di acquisizione
dei dati da elaborare.
L’indirizzo a 16 bit dell’operando può essere fornito alla CPU in
diversi modi, utilizzando cioè istruzioni differenti.
Il modo di indirizzamento dell’operando viene definito dall’op code.
Un’appropriata scelta della tecnica di indirizzamento comporta una
minore occupazione dello spazio di memoria.
Nella maggioranza dei microprocessori (a 8 bit) il codice operativo vero e proprio è
costituito da 6 bit, gli altri due sono dedicati alla definizione della tecnica di indirizzamento
dell’operando.
Nello Z80 invece il bit dedicato è uno solo, quindi molte istruzioni sono costituite da due
codici operativi: i modi di indirizzamento risultano di conseguenza in numero maggiore.
TECNICHE DI INDIRIZZAMENTO
Il microprocessore 8086/8088
L’8086, prima CPU a 16 bit commercializzata da Intel, ancora usata nel mondo industriale,
è un microprocessore potente, evoluto e piuttosto versatile.
Inizialmente l’ISA dell’8086 e dei primi suoi successori era poco ortogonale, ed è andato
migliorando con l’evolversi della famiglia.
Può indirizzare direttamente una memoria da 1 MB (1 milione di byte), a differenza dello
Z80 che può accedere a 64 KB.
È dotato di un set di istruzioni che permette di risolvere semplicemente qualsiasi problema
comprese la moltiplicazione e la divisione.
Per non deludere i molti utenti che avevano fatto grossi investimenti sui precedenti sistemi
utilizzanti microprocessore a 8 bit (8080 e 8085) e quindi allo scopo di creare con questi
una perfetta compatibilità, Intel ha costruito contemporaneamente l’8088, quasi identico
all’8086 con l’eccezione del bus dati esterno che è a 8 bit.
Pertanto quanto esposto in seguito è da ritenersi valido per entrambe le CPU e le eventuali
differenze tra le due saranno poste opportunamente in rilievo.
L’8086/8088 è un microprocessore in tecnologia HMOS a 40 pin con un clock da 5 e 8 MHz,
comunque non inferiore a 2 MHz.
Negli anni successivi, utilizzando la tecnologia CHMOS, Intel ha sviluppato una versione più
veloce di tutta la famiglia 86, commercializzandola con la sigla iAPX86.
Pur avendo un data bus a 16 bit e un address bus a 20 bit, l’8086 ha un numero di pin pari
a quello di una CPU a 8 bit.
Le tecniche che consentono di avere ugualmente un numero limitato di pin sono
fondamentalmente due: encoding e multiplexing.
L’encoding consiste nell’attribuire a un gruppo di pin un significato complessivo e non
individuale in modo tale che ad ogni configurazione corrisponda una certa funzione.
Un esempio di encoding è costituito dai pin s0, s1, s2: insieme rappresentano un codice di
stato che identifica un ciclo di bus.
Il multiplexing è invece una tecnica che attribuisce al pin un segnale diverso in istante
diverso.
Per esempio sui piedini contrassegnati dalle sigle AD0-AD15 si prelevano sia i bit dei dati
che quelli degli indirizzi.
L’8086/8088 può funzionare in due modi differenti: modo minimo e modo massimo.
Nel modo minimo il microprocessore lavora singolarmente mentre nel modo massimo può
funzionare in multiprocessing o in coprocessing.
Il multiprocessing è un sistema di organizzazione che prevede più microprocessori ognuno
dei quali elabora un proprio programma e utilizza le risorse globali dl sistema.
Il coprocessing, invece, è una tecnica che prevede oltre al microprocessore principale
(8086/8088) il coprocessore matematico 8087, in pratica un’altra CPU dedicata
unicamente alle operazioni matematiche.
Architettura interna
L’8086/8088 da un punto di vista funzionale è costituito essenzialmente da due
blocchi, come nella sottostante figura:
•
BIU (Bus Interface Unit), unità di interfaccia con il bus, chiamato anche processore
duale a 16 bit nell’8086 e a 8 bit nell’8088;
•
EU (Execution Unit) unità di esecuzione chiamato anche processore principale.
La EU decodifica ed esegue le istruzioni; la BIU provvede all’interfaccia tra il microproces-
-sore e l’ambiente esterno: preleva le istruzioni, legge e scrive in memoria e nei dispositivi
di I/O.
La caratteristica peculiare della BIU è quella di operare in modo asincrono con la EU; infatti
mentre questa esegue la fase di execute, il processore duale preleva le istruzioni succes-
-sive dalla memoria e crea una coda (di istruzioni) di tipo pipeline lunga 6 byte nell’8086
e 4 byte nell’8088.
Il tempo globale di esecuzione di un’istruzione può risultare notevolmente ridotto sia
perché alcune istruzioni sono eseguite completamente all’interno del microprocessore sia
perché il funzionamento dei due blocchi è parallelo.
La riduzione del tempo di esecuzione non è sempre vera poiché alcuni passi del program-
-ma, come ad esempio i salti, richiedono la cancellazione, ai fini di una nuova ricomposi-
-zione, dell’accodamento delle istruzioni stesse.
I registri
I registri interni al microprocessore, mostrati
nella figura a lato, sono tutti a 16 bit e pos-
-sono essere classificati come:
• registri generali;
• registri puntatori;
• registri indice;
• registri segmento;
• registro di stato.
I registri generali appartengono alla EU e
sono impiegati per memorizzare tempora-
-neamente i risultati intermedi delle elabo-
-razioni:
•
AX, Accumulator eXtended (accumulatore
esteso);
•
BX, Base eXtended (base esteso);
•
CX, Counter eXtended (contatore esteso);
•
DX, Data eXtended (dati esteso).
Ognuno può essere utilizzato sia come un
unico registro a 16 bit (in tal caso è indicato
nell’istruzione con la X) sia come una coppia
a 8 bit, come nella tabella a lato.
Ogni registro generale può essere usato per una qualsiasi
operazione anche se in particolare AX e DX sono dedicati
alla moltiplicazione, alla divisione e alle operazioni di I/O
per dati a 16 bit.
Insieme dei registri interni del
microprocessore 8086.
Registri generali della EU.
Byte alto
Byte basso
15…8
7…0
AX
AH
AL
BX
BH
BL
CX
CH
CL
DX
DH
DL
Se il formato dei dati è invece di un byte, i registri dedi-
-cati alle operazioni prima menzionate sono AH e AL.
Infine BX viene adoperato preferibilmente come memo-
-ria per l’indirizzo base nell’indirizzamento indiretto e CX come contatore.
I registri indice e i registri puntatori sono a 16 bit e, a differenza di quelli generali, non
possono essere utilizzati a 8 bit:
•
SP, Stack Pointer (puntatore dello stack);
•
BP, Base Pointer (puntatore della base);
•
SI, Source Index (registro indice sorgente);
•
DI, Destination Index (registro indice destinazione).
In questi quattro registri sono memorizzati gli offset utili per il calcolo degli indirizzi
fisici.
Lo Stack Pointer contiene l’offset dell’indirizzo fisico della locazione di memoria
accessibile dell’area stack.
Il Base Pointer contiene anch’esso l’offset dell’indirizzo fisico della locazione di memoria
dell’area stack, ma viene impiegato nel caso di trasferimento dati con indirizzamento
indiretto.
I registri SI e DI contengono gli offset degli indirizzi che riguardano i segmenti dei dati.
Il contenuto del Source Index viene assunto come offset per l’indirizzo sorgente del
segmento dei dati mentre il Destination Index come offset per l’indirizzo destinazione del
segmento dei dati.
Alla EU appartiene anche il soprastante registro dei flag , altrimenti noto come registro di
stato, il cui significato è individuale (bit per bit) e non complessivo: ogni flag infatti rappre-
-senta la condizione del risultato di un’operazione logica o aritmetica appena eseguita.
I flag di stato sono i seguenti:
•
CF (flag di riporto); è settato quando vi è un prestito o un riporto dal bit di peso supe-
-riore del risultato di una operazione aritmetica;
•
PF (flag di parità); è settato quando il risultato di una operazione contiene un numero
pari di 1;
•
AF (flag di riporto ausiliario); viene posto a 1 quando vi è un riporto dal byte di peso
inferiore a quello di peso superiore in un dato a 16 bit;
•
ZF (flag di zero); posto a 0 quando il risultato di una istruzione è 0;
•
SF (flag di segno); copia il bit di segno del risultato: 0 se il numero è positivo, 1 se
negativo;
•
OF (flag di overflow); se il flag e a 1, vuol dire che il risultato dell’operazione aritmetica
ha una estensione superiore alla lunghezza del registro che lo contiene
I rimanenti tre flag sono di controllo:
•
TF (flag di trappola); se è posto a 1, il microprocessore svolge un’operazione alla
volta nel modo di funzionamento a passo singolo;
•
IF (flag di abilitazione delle interruzioni); se è a 1 qualsiasi richiesta di interruzione
mascherabile viene accettata;
•
DF (flag di direzione); gli indirizzi vengono scanditi dal più basso al più alto se è a 1,
in direzione contraria se è a 0.
I registri di segmento e il puntatore alle istruzioni appartengono alla BIU.
•
IP (puntatore alle istruzioni); si tratta di un registro che indica l’offset dell’indirizzo
fisico della locazione di memoria contenente il primo byte dell’istruzione da puntare.
Il contenuto di IP non può essere modificato dalle istruzioni del programma ma può
essere salvato nell’area stack e da questa recuperata in un momento successivo.
Tutti i registri interni al microprocessore sono a 16 bit mentre il bus indirizzi esterno
ha un formato a 20 bit.
Il contenuto dei registri interni viene pertanto manipolato con una tecnica definita
segmentazione della memoria al fine di generare l’indirizzo fisico o effettivo della locazione
di memoria da puntare.
La memoria globale del sistema viene suddivisa in segmenti di 64 KB (216 byte) sovrap-
-ponibili totalmente o parzialmente.
Tutti i segmenti sono interamente selezionabili con un address bus a 16 bit chiamato
offset e contenuto in uno dei registri.
L’offset viene poi sommato in modo opportuno con un indirizzo variabile residente in un
registro segmento che rappresenta la partenza del segmento di memoria.
I registri di segmentazione della memoria sono quattro:
• CS (segmento codice);
• DS (segmento dati);
• SS (segmento stack);
• ES (segmento extra).
L’indirizzo fisico (o effettivo) di 20 bit è ottenuto, come mostra
la figura a alto, mediante la seguente formula:
indirizzo effettivo = 16 ∙ indirizzo di segmento + offset
Generazione dell’indirizzo
di sistema a 20 bit.