Sei sulla pagina 1di 84

S3Abacus Architetture/Asm .

doc - 1684Kb - 08/mar/2011 - 1 / 84

SISTEMI E INFORMAZIONE..............................2
Definizioni...............................................................................................2
Classificazione.......................................................................................3
AUTOMI A STATI FINITI.........................................................4
Reversibilit...........................................................................................................4
Raggiungibilit.......................................................................................................4
Indistinguibilit.......................................................................................................4
Stati d'equilibrio.....................................................................................................4
Uscite d'equilibrio..................................................................................................4
Minimizzazione......................................................................................................5
RAPPRESENTAZIONE E CODIFICA DELLINFORMAZIONE.........9
Notazioni e rappresentazioni posizionali...............................................9
Sistema di numerazione in base Due (BIN).......................................................10
Sistema di numerazione in base Otto (OCT).....................................................11
Sistema di numerazione in base Sedici (HEX)..................................................11
Trasformazioni tra sistemi Posizionali..................................................11
Raggruppamento di Bit.......................................................................................13
Contenitori binari..................................................................................14
Operazioni Bitwise..............................................................................................14
Maschere di bit....................................................................................................15
Numeri con segno................................................................................16
Numeri con parte frazionaria................................................................16
Rappresentazioni in eccesso 2n-1.....................................................................16
Standard IEEE 754.............................................................................................17
CODICI, COMUNICAZIONE, INFORMAZIONE.........................19
Codifiche numeriche............................................................................20
Codifica Numerica BCD......................................................................................21
Codifica Numerica Eccesso 3.............................................................................21
Codifica Numerica Aiken.....................................................................................21
Codifica Numerica Gray......................................................................................21
Codifiche Alfanumeriche......................................................................21
Codifica Alfanumerica BAUDOT.........................................................................21
Codifica Alfanumerica ASCII...............................................................................21
CODICI ED ERRORI............................................................23
Parit...................................................................................................................23
Parit incrociata..................................................................................................23
Codice di Hamming.............................................................................................24
Codici Ciclici - CRC.............................................................................................25
CheckSum...........................................................................................................26

ARCHITETTURE...............................................27
ARCHITETTURA DI VON NEUMANN.....................................28
Tassonomia di Flynn...........................................................................................28
Macchina di Von Neumann..................................................................28
Memoria...............................................................................................28
Tecnologie...........................................................................................................29
Bus.......................................................................................................29
Tecnologie...........................................................................................................30
Input/Output.........................................................................................30
Tecnologie...........................................................................................................31
Processore...........................................................................................31
Cisc, Risc, Crisc..................................................................................................32
Cache..................................................................................................................32
Prefetch, Pipeline, Superscalarit......................................................................32
Esecuzione Predicativa e Speculativa...............................................................33
Esecuzione Fuori ordine e VLIW........................................................................33
ARCHITETTURE INTEL.......................................................34
x-86......................................................................................................34
Intel 8086.............................................................................................................34
Registri................................................................................................................34
Indirizzamento.....................................................................................................35
IA-32.....................................................................................................35
Netburst, EM64T.................................................................................................35
MultiCore.............................................................................................................36
IA-64.....................................................................................................36
Tabella riassuntiva architetture Intel (2008).........................................37

ASSEMBLY X-86..............................................38
Istruzioni x-86.......................................................................................38
Registro Flags (PSW).........................................................................................40
Sintassi e indirizzamenti.....................................................................................41
x-86 e MsDos.......................................................................................41
Memoria..............................................................................................................42
Boot.....................................................................................................................42
Formato degli eseguibili e Rilocazione: EXE e COM.........................................42
API , Interruzioni Sw e Servizi............................................................................43
Video e tastiera con le Interruzioni Sw del Bios...................................44
Video e tastiera con le Interruzioni Sw di MsDos................................44
Terminare i programmi in MsDos.........................................................45
ASSEMBLY CON DEBUG....................................................46
Comandi...............................................................................................46
Esplorare la memoria...........................................................................46
Consultare I registri..............................................................................47
Scrivere un programma........................................................................47
S3Abacus Architetture/Asm .doc - 1684Kb - 08/mar/2011 - 2 / 84

Il programma pi corto del mondo......................................................................48


Video e tastiera...................................................................................................49
Strutture di controllo.............................................................................49
Editare un programma.........................................................................51
Area Dati e area Codice.......................................................................52
Allineamento........................................................................................53
ASSEMBLY CON TASM......................................................56
Struttura dei programmi.......................................................................56
Ciclo di vita di un programma..............................................................56
Ciclo di vita di un programma TASM....................................................57
Scrivere un programma EXE...............................................................59
Modelli di memoria...............................................................................60
Scrivere un programma COM..............................................................61

ASSEMBLY X-86 AVANZATO..........................63


MACRO............................................................................64
Macro costanti.....................................................................................................64
Macro di codice...................................................................................................65
Macro con parametri e etichette.........................................................................66
STACK.............................................................................67
PROCEDURE....................................................................70
Definizione di procedura.....................................................................................70
Meccanismo di chiamata....................................................................................71
Preservare i registri.............................................................................................71
PASSAGGIO DI PARAMETRI................................................73
VARIABILI LOCALI.............................................................75
Notazioni per il passaggio di parametri e le variabili locali................................76
DIRETTIVE PER LA PROGRAMMAZIONE E LIBRERIE.............78
Salti lunghi, direttiva JUMPS..............................................................................78
Duplicazione di etichette, direttiva LOCALS......................................................78
Librerie, direttive INCLUDE, PUBLIC ed EXTRN..............................................79
Makefile...............................................................................................................81
S3Abacus Architetture/Asm .doc - 1684Kb - 08/mar/2011 - 3 / 84

SISTEMI E INFORMAZIONE

DEFINIZIONI
Per affrontare la teoria dei Sistemi sono necessarie alcune nozioni matematiche:
- riduzione di espressioni di n-mo grado
- uso di matrici e calcolo della priorit
- calcolo derivate e integrali
- risoluzione equazioni differenziali

In generale un S i s t e m a una entit che riceve sollecitazioni e fornisce, come reazione ad esse, delle nuove condizioni.
In termini pi formali si dicono i n g r e s s i le sollecitazioni e u s c i t e le reazioni agli ingressi.

Gli elementi tipici per l' individuazione di un sistema sono:


-T un insieme ordinato e crescente di tempi;
-I insieme di n canali di ingresso;
- VI insieme dei valori per gli ingressi;
- U insieme di m uscite;
- VU insieme dei valori per le uscite;
- S insieme degli stati interni.
Servono poi due funzioni che possano descrivere l' andamento del sistema e, da questo, fornire l'andamento delle uscite:

La prima detta funzione di T r a n s i z i o n e : s(t) = f(t0,t,s(t0),in(t)[t0,...,t[)


La seconda detta funzione di T r a s f o r m a z i o n e : u (t) = g (t,s(t),i (t))
m m n

La situazione pu essere rappresentata da un diagramma funzionale:

i (t) s(t)
1

i 2(t)
u1 (t)
f( )
m u2 (t)
in(t) g()

um(t)

s(t0)

L'insieme T ordinato e rappresenta tutti i possibili istanti in cui deve essere analizzato il sistema. Esso pu essere finito o infinito ma sicuramente
limitato inferiormente da un valore detto t0 (tempo iniziale).
L'insieme I descrive tutte le possibili sollecitazioni autonome a cui il sistema soggetto; in altre parole potrebbe essere visto come l'insieme delle
variabili d'ingresso. E' opportuno, per ogni elemento di I (variabile) specificarne il campo di validit o l'insieme dei valori.
L'insieme VI composto da tutti i valori che possono assumere contemporaneamente gli elementi di I, quindi se la cardinalit di I n, l'insieme VI
rappresentato - in teoria - da tutte le possibili n-ple che si possono comporre.
Analoghi discorsi si applicano a U e VU, mentre per S si intende l'insieme di tutte le configurazioni interne che il sistema pu assumere durante
l'analisi.
Risulta particolarmente intuitivo che gli ingressi, gli stati e le uscite debbano dipendere dal tempo t, cio: i=i(t), s=s(t), u=u(t).
In particolare risulta intuitivo che saputi gli ingressi al tempo iniziale t0, saputo lo stato iniziale al tempo t0 e sapute le relazioni tra ingressi e stati per
il calcolo delle uscite, si possa conoscere senza dubbio sia l'uscita successiva (al tempo t 1) che lo stato successivo (al tempo t1); inoltre applicando
tali deduzioni, si pu estendere il principio ad un qualsiasi tempo t diverso da t0.
E' per questo motivo che le due relazioni funzionali f e g assumono la forma vista poco sopra.
S3Abacus Architetture/Asm .doc - 1684Kb - 08/mar/2011 - 4 / 84

E' da notare come t0 non sia espressamente solo il tempo iniziale dell'analisi, ma un qualsiasi tempo t per il quale siano noti i(t) e s(t).
Anche la notazione in(t), um(t) e gm(..) sono da intendersi come n-ple di valori di ingresso, m-ple di valori di uscita e m-ple di funzioni di
trasformazione, avendo generalizzato la numerosit di ingressi e uscite. Infatti se da n ingressi diversi il sistema offre m uscite diverse, la funzione
di traformazione in realt deve descrivere tutti gli m modi in cui gli n ingressi si trasformano nelle m uscite. Pertanto questi m modi sono le g m
funzioni di trasformazione diverse.

Le due funzioni fondamentali e sono da interpretare in modo consequenziale luna dallaltra e non contemporaneo, anche se la stessa
dipendenza da t di s(t) e di um(t) potrebbe far pensare diversamente.
Infatti la loro valutazione contemporanea induce ad uno sfasamento nellanalisi: la valutazione delle uscite attuali (al tempo t) dipende strettamente
dallo stato attuale (al tempo t) che pertanto deve essere gi conosciuto. Anche il diagramma funzionale riportato contiene questa inesattezza, infatti
le n entrate dellingresso in f() non sono le stesse che entrano poi in gm(), ma dovrebbero essere gli ingressi al tempo t precedente.
La corretta relazione tra le due funzioni si ottiene integrandole matematicamente: u m(t) = gm(t, f(t0,t,s(t0),in(t)[t0,...,t[),in(t))

Solo in base a questa considerazione linterpretazione delle due funzioni diviene coerente:
- lo stato che desidero conoscere, cio lo stato al tempo attuale t e quindi s(t) calcolabile con la funzione f solo se possibile conoscere lo stato
iniziale s(t0) e lintera evoluzione degli stati per tutti i tempi successivi fino a t escluso; si tratterebbe quindi di determinare tutti i vari s(t 1), s(t2), ...; ma
ci possibile solo se per ogni istante t0, t1, ..., conosco gli ingressi applicati, cio tutti gli ingressi applicati da t 0 fino a t escluso.
Pertanto la scrittura in(t)[0..t[ significa: tutti i valori degli n ingressi valutati a partire da t0 fino a t escluso.
Allora la formula descrive esattamente questo appena affermato.

- luscita al tempo attuale t non altro che una m-pla di valori, e quindi la si scrive: um(t); per poter calcolare ogni singolo valore della m-pla il
ragionamento sempre identico: necessario sapere quale lo stato al tempo t, cio s(t) e quale lingresso al tempo t, cio ln-pla specifica: i n(t).
Ma questo ci che rappresenta formalmente la formula .

In realt la potrebbe essere riscritta: sarebbe infatti sufficiente conoscere lo stato immediatamente precedente e lingresso (n-pla)
immediatamente precedente per conoscere lo stato attuale s(t); in altre parole la funzione di transizione potrebbe anche esprimersi:
s(t) = f(t0,t,s(tprec),in(tprecl))
Cionondimeno si preferisce la per evidenti scopi didattici, dato che costringe a ripensare alla storia passata del sistema.
Le presenze di t e sono esplicitate nelle due funzioni per mettere in evidenza la dipendenza dalla variabile indipendente t connaturata alla
dinamicit dei sistemi e la dipendenza assoluta dallistante iniziale di analisi - e quindi dallo stato iniziale del sistema - che cos fortemente
condiziona levoluzione di ogni sistema.

CLASSIFICAZIONE
I sistemi in generale possono essere suddivisi in categorie in base alla loro natura; si possono quindi distinguere tipi contrapposti di sistemi:

- Vari anti : sono tali quei sistemi per cui, al trascorrere del tempo, uno o pi parti costitutive del sistema si evolvono e quindi ne
modificano la struttura d'analisi. Se ad esempio in un sistema 'missile' la massa del missile viene considerata costante
durante l'analisi per esempio del calcolo della velocit e delle accelerazioni, che possono essere viste come funzioni di
trasformazione o transizione, tale assunzione risulta evidentemente falsa dato che la massa del missile diminuisce al
consumo di carburante.
In altre parole un parametro costitutivo del sistema dipende esplicitamente dal tempo e varia con esso.
-Invarianti: in contrapposizione, se le caratteristiche intrinseche del sistema rimangono costanti nel tempo e variano solo ingressi, stati
e uscite.
-Deterministici: sono tali quei sistemi in cui le grandezze d'analisi sono precisamente e univocamente determinate da relazioni
matematiche, grafiche o descrittive.
-Stocastici: in contrapposizione, quei sistemi per cui le grandezze caratteristiche dipendono da dati e analisi aleatorie e non
precisamente determinabili a priori (si pensi ai sistemi complessi delle economie, delle previsioni meteorologiche o dei
modelli atomici).
-Continui: sono tali quei sistemi per cui le caratteristiche fondamentali dipendono da quantit analogiche continue riferibili a numeri
Reali o Complessi.
-Discreti: in contrapposizione, quei sistemi governati da quantit finite ed enumerabili - in genere riferibili al dominio dei numeri
Naturali o Interi. Sono detti spesso anche sistemi digitali.
-Propri: se la funzione di trasformazione non dipende dai valori assunti dall' ingresso mentre si dicono I m p r o p r i se la funzione di
trasformazione dipende esplicitamente dai valori degli ingressi, cos come espresso nella definizione generale .
Per i sistemi propri quindi le due funzioni possono essere riscritte:
s(t) = f(t0,t,s(t0),in(t)[t0,...,t[) ' um(t) = gm(t,s(t)) '
S3Abacus Architetture/Asm .doc - 1684Kb - 08/mar/2011 - 5 / 84

AUTOMI A STATI FINITI


Un sottoinsieme dei sistemi generali rappresentato dagli A u t o m i , che possono essere definiti come Sistemi invarianti, deterministici, discreti in
cui VI e VU sono insiemi finiti.
Tra questi sono particolarmente significativi gli A u t o m i A S t a t i F i n i t i (AASF), cio automi in cui anche l'insieme S finito.
Di questi ultimi ci occuperemo in particolar modo mostrando metodi di analisi e metodi per l'individuazione delle funzioni di transizione e
trasformazione.
Dato che per i sistemi discreti - come gli automi - l'avanzamento del tempo implicito, si possono scrivere le funzioni tipiche omettendo la variabile
indipendente t e riportando le due forme, impropria e propria:

IMPROPRIO PROPRIO

s(t) = f(s(t0),in(t)[t0,...,t[) s(t) = f(s(t0),in(t)[t0,...,t[) '

um(t) = gm(s(t),in(t)) um(t) = gm(s(t)) '

Per gli automi a stati finiti, la versione Impropria viene detta Automa di MEALY, mentre la versione Propria detta Automa di MOORE.
L'analisi e la determinazione delle due funzioni g e f per un automa a stati finiti si realizza con la costruzione di un grafo particolare detto g r a f o
d e l l e t r a n s i z i o n i , sempre identificabile.
Lo schema costruttivo del grafo di transizione per un AASF ove gli insiemi tipici sono univocamente determinati si sintetizza nei seguenti passi:
1. Disposizione in aree circolari di tutti gli stati appartenenti a S;
2. A partire da uno stato qualsiasi - magari s0 - applicare tutti gli ingressi possibili (gli elementi di VI) e per ognuno disegnare un arco orientato
verso lo stato raggiunto, riportando l'ennupla d'ingresso e l'emmupla dell'uscita relativa con la notazione i 1,i2,..in/u1,u2,..,um.
3. Naturalmente una regola fondamentale, che al termine della costruzione deve essere assolutamente rispettata, consiste nella completa
mancanza di due coppie identiche di n-ple d'ingresso che, da uno stesso stato, conducono a due stati differenti ovvero che originano due
dfferenti m-ple di uscite.
Un altro sistema per descrivere il funzionamento di un AASF (determinazione di f e g) ben descritto dalla t a b e l l a d i f u n z i o n a m e n t o , che
consiste in una tabella cartesiana ove sulle ascisse sono riportati tutti i possibili ingressi (elementi di VI), sulle ordinate tutti i possibili stati (elementi
di S) e sugli incroci, ordinatamente, uscita e stato successivo determinati dai valori d'incrocio.
Tale metodo risulta particolarmente pesante quando VI ampio ma sufficientemente efficace per automi in cui VI limitato.
Sia la tabella di funzionamento che il grafo di transizione riassumono esplicitamente per gli AASF le funzioni f e g tipiche per la completa
determinazione di un sistema.
Esse in alcuni casi possono anche essere scritte in notazioni matematiche, anche se ci non risulta cos efficace come i metodi suddetti.
Proseguendo nell'analisi degli AASF particolarmente interessante introdurre alcune nozioni relative a stati e uscite, nozioni che in una qualche
misura si possono generalizzare anche per i sistemi continui.

REVERSIBILIT
Un automa si dice Reversibile se, dato un qualsiasi stato sa S e un qualsiasi valore i VI, esiste e unico uno stato sb S tale per cui vera sa = f(sb,
i)
Per verificare questa propriet su un automa dato sufficiente verificare che invertendo tutti i versi degli archi del grafo di transizione si ottenga
ancora un automa (cio non si infranga la regola 3.)

RAGGIUNGIBILIT
Uno stato s2 Raggiungibile dallo stato s1 se esiste un a sequenza di ingressi che applicati a s1 consentono di arrivare a s2.
Se la propriet estensibile a qualsiasi coppia di stati di un automa esso si dice Connesso, altrimenti Non Connesso.

INDISTINGUIBILIT
Due stati s1 e s2 sono Indistinguibili se tutte le coppie ingresso/uscita applicabili a s1 sono le stesse rilevabili su s2.

STATI D'EQUILIBRIO
Uno stato s d'Equilibrio per l'automa se esiste una sequenza di ingressi tali da mantenere l'automa sempre nello stato s.

USCITE D'EQUILIBRIO
Una uscita u di un automa d'Equilibrio se esiste uno stato s e una sequenza di ingressi tale per cui l'uscita dell'automa risulti essere sempre u.
Naturalmente le definizioni di cui sopra implicano situazioni di immediata intuizione che per ora non espliciteremo, attendendo che possano essere
messe in evidenza dagli esempi riportati.
La propriet dell'Indistinguibilit invece torna immediatamente utile per introdurre un metodo che semplifichi la costruzione di un grafo delle
transizioni per un automa qualsiasi.
Come ci si render ben presto conto, la costruzione dei grafi di transizione, pur semplice, spesso conduce a diagrammi molto ricchi di stati e archi,
ingenerando confusione e dilungando sensibilmente l'analisi.
Dopo aver costruito un grafo complesso e ricco di stati si rende necessario pensare se il modello ottenuto sia il pi semplice possibile e spesso la
risposta negativa. Esiste infatti un metodo di analisi dei grafi che consente di semplificarli senza perderne le caratteristiche. Tale metodo detto di
m i n i m i z z a z i o n e e si basa sulla eliminazione metodica degli stati equivalenti (ovvero indistinguibili) eventualmente presenti in un modello.
S3Abacus Architetture/Asm .doc - 1684Kb - 08/mar/2011 - 6 / 84

MINIMIZZAZIONE
Dopo aver disposto completamente il grafo di transizione iniziale e quindi aver esplicitamente descritto tutti gli stati (es. s0,..,sn) e applicato tutti i VI
ad ogni stato avendole associate alle proprie VU, seguire i seguenti passi:
1. Indicare con P0 l'insieme di tutti gli stati (prima partizione P1);
2. Individuare tutti i gruppi di stati nei quali applicando i VI si ottengono le stesse VU; per ipotesi immaginiamo che si formino i gruppi di stati
nominati G1, G2, ..., Gi, ognuno dei quali contiene stati che a partire dai medesimi ingressi offrono medesime uscite (stati indistinguibili).
3. Questi i gruppi di stati rappresentano la seconda partizione P2;
4. Per ogni stato individuare tutti i possibili stati di arrivo (applicando gli ingressi ad ogni stato) e formare una tabella che ad ogni stato associ
l'identificazione del gruppo di P2 - cio ai Gj - a cui si arrivati.
5. Identificare quindi i nuovi gruppi della partizione P3 raggruppando tutti gli stati che giungono alle stesse sequenze di Gj descritte al punto
precedente. Questa sar la nuova partizione P3.
6. Ripetere i passi 3. e 4. fino a ottenere partizioni identiche notando l'impossibilit di proseguire.
7. A questo punto supponiamo che gli elementi dell'ultima partizione siano k, con k i n e chiamiamoli Q1,Q2,..,Qk (analoghi ai G1,G2,...,Gi visti
in precedenza); essi determinano k stati generali dei quali, per ogni ingresso, si pu determinare sia l'uscita (osservando la partizione P1) sia lo
stato generale a cui passare (osservando l'ultima partizione ottenuta).
Questo nuovo automa perfettamente equivalente a quello dato.

ESEMPI DI AUTOMI
Esempio 1.
Analizziamo in questo caso solo sistemi discreti, cio automi a stati finiti cominciando da un sistema
costituito da un distributore di lattine.
Il sistema contiene n lattine, possiede un ingresso per inserire una moneta, una uscita per la lattina e una
per la restituzione della moneta.
Gli insiemi tipici risultano essere:

T = {t0,t1,...,tn}
I = {M}; dove M st per moneta e pu assumere i valori 1 e 0 (moneta IN, moneta OFF)
VI = {1,0}; naturalmente sono singoletti, dato che il canale unico;
U = {L,R}; con L si indica l'uscita lattina (0 o 1) e con R la restituzione (0 o 1);
VU = {<1,0>,<0,0>,<0,1>}; manca il caso in cui resa sia la lattina che la moneta;
S = {s0,...,sn}; indica il riempimento del sistema (s0=vuoto)

Allora il grafo si costruisce:


1 / <1,0> 1 / <1,0> 1 / <1,0> Come si pu notare sono stati riportati tutti gli stati
(agli stati intermedi sono stati sostituiti i quadratini di
sospensione) e ad ogni stato sono applicati tutti gli
ingressi possibili;
S0 Sn-1 Sn

1 / <0,1> 0 / <0,0> 0 / <0,0>


0 / <0,0>
Le funzioni f e g si possono anche esplicitare in:
f = ; si=si-1 se ingresso=1 e i0
si=si se ingresso=1 o se i=0;

g = ; ui=<1,0> se ingresso=1 e i0
ui=<0,0> se ingresso=0
ui=<0,1> se ingresso=1 e i=0

Esempio 2.
Sia dato un ascensore che si muove su 3 piani, con un pulsante per piano per la chiamata e un pulsante
interno per indicare la destinazione.
Naturalmente necessario stabilire alcune regole per determinare il comportamento del sistema tipo indicare
la priorit dei pulsanti (detti PP e PA) e introdurre altre ipotesi di funzionamento (le uscite possono
essere la direzione D (alto o basso o fermo) e la velocit V (0,1,2).
Tali ipotesi devono essere poste dall'analizzatore del sistema se non espressamente indicate.

Pertanto:

T = {t0,t1,...,tn}
I = {PP,PA}; PP=0,1,2,3; PA=0,1,2,3
VI = {<0,0>,<0,1>,<0,2>,<0,3>,<1,0>,...,<3,3>}
U = {D,V}; D=0,a,b; V=0,1,2
VU = {<0,0>,<a,1>,<a,2>,<b,1>,<b,2>}
S = {P1,P2,P3}
S3Abacus Architetture/Asm .doc - 1684Kb - 08/mar/2011 - 7 / 84

0,2/a,1
Nel grafo sono state messe in evidenza ed esplicitate solo le
1,2/a,1
transizioni del primo stato P1, riportando tutti i possibili
2,0/a,1
2,2/a,1 P2 valori per gli ingressi (coppie), mostrandone le uscite e
3,2/a,1 riportandone le transizioni.

0,0/0,0
0,1/0,0
1,0/0,0
1,1/0,0 P1
2,1/0,0
3,1/0,0

0,3/a,2 P3
1,3/a,2
2,3/a,2
3,0/a,2
3,3/a,2

In vari casi si nota come la priorit scelta tra i due ingressi sia pi alta per il pulsante nell'ascensore
(PA) cio il secondo valore della coppia (Es. la coppia <3,1> su P1 ferma l'ascensore su P1 dando l'uscita
<0,0>).
Si nota anche che nessun ingresso applicato su P1 pu generare l'uscita <b,...> dato che l'ascensore si trova
al piano pi basso.

Naturalmente analoghe analisi con l'applicazione di tutte le coppie di ingresso devono essere eseguite anche
per P2 e P3.

In questo caso non particolarmente efficace rappresentare f e g con notazioni matematiche.


Esempio 3.
Una categoria abbastanza significativa di automi rappresentata dagli automi riconoscitori.
Si debba implementare un automa che acquisisce in ingresso simboli binari e debba emettere un segnale tutte
le volte che riconosce una sequenza di ingresso pari alla codifica binaria del simbolo '1' in ASCII
(=30h=00110000b).

Gli insiemi tipici:


T = {t0,t1,...,tn}
I = {IB}; che indica Input Binario, con valori 0,1;
VI = {1,0};
U = {R}; Riconoscimento, valevole ACK (riconosciuto), NACK o STBY (in riconoscimento)
VU = {ACK,STBY,NACK};
S = {S0,R1,R2,R3,R4,R5,R6,R7}; indica le fasi di riconoscimento.

1/NACK Il grafo riportato in grado di riconoscere la sequenza indicata


0/STBY 0/STBY
(00110000) solo in alcuni casi; infatti, ipotizzando lo stato iniziale
1/NACK in S0, una sequenza di ingressi del tipo:

0/ACK S0 R1 R2
1/STBY
0/NACK
1/NACK
0/NACK
R7 R3
1/STBY
0/STBY 1/NACK 1/NACK
1/NACK

R6 R5 R4

0/STBY 0/STBY
11100110000101...
viene correttamente analizzata dall'automa che segnala ACK nel momento giusto.
Sempre con stato iniziale in S0, una sequenza del tipo:
10001100001011...
non viene segnalata, dato che al terzo zero ricevuto l'automa si ritrova in S0, perdendo sincronismo con la
sequenza da riconoscere.

Si noti come l'uscita segnali una fase di riconoscimento in corso con il valore STBY.

La corretta implementazione dell'automa impone alcune correzioni sulle transizioni che riportiamo in seguito.
S3Abacus Architetture/Asm .doc - 1684Kb - 08/mar/2011 - 8 / 84

1/NACK
0/STBY 0/STBY 0/NACK

1/NACK
S0 R1 R2

0/ACK 1/STBY
1/NACK 0/NACK

R7 R3
1/STBY
0/STBY
1/NACK 1/NACK 1/NACK

R6 R5 R4

0/STBY 0/STBY
Questa seconda versione individua tutte le sequenze richieste senza sbagliare nessun riconoscimento e senza
perderne alcuno.
Le modifiche consistono nel far ritornare l'automa allo stato corretto dopo ogni NACK, evitando di farlo
sempre partire da capo.
Si notino le differenze di comportamento sugli stati R2, R3, R7.
S3Abacus Architetture/Asm .doc - 1684Kb - 08/mar/2011 - 9 / 84

Esempio 4.
Vediamo ora come si pu minimizzare un automa con il metodo delle partizioni.
Sia dato il seguente automa per mezzo del grafo:
0/0

S6 0/0 S4
0/0 1/0
1/0
S7 S0

0/0 1/0

0/0 1/0 1/0


1/1
S3 S1
1/1 0/0
0/0
1/0
S5 S2

0/0

Evidentemente gli stati sono otto (S0,...,S7) con un solo canale di ingresso che pu valere 0 o 1 e
analogamente, un solo canale per le uscite che pu valere 0 o 1.
A priori non si pu affermare che l'automa riprodotto non sia riducibile (minimizzabile), ma basta osservare
gli stati S0 e S4 per verificare che sono Indistinguibili.
Infatti ogni valore dell'ingresso su S0 genera le stesse uscite che gli stessi valori per l'ingresso generano
su S4 (0/0; 1/0).
L'automa minimizzabile. Utilizziamo il metodo delle partizioni.

Passo 1.
P0 = (S0, S1, S2, S3, S4, S5, S6, S7);

Passo 2.
Per determinare i gruppi Gj della seconda partizione P1, applichiamo ad ogni membro di P0 gli ingressi e
valutiamo le uscite:
S0= 0-0 1-0
S1= 0-0 1-1
S2= 0-0 1-0
S3= 0-0 1-0
S4= 0-0 1-0
S5= 0-0 1-1
S6= 0-0 1-0
S7= 0-0 1-0
Individuiamo quindi i due gruppi G1=(S0,S2,S3,S4,S6,S7) e G2=(S1, S5) che compongono la partizione P1.

Passo 3.
Al gruppo G1 di P1 e al gruppo G2 di P1 applichiamo gli ingressi e costruiamo la tabella delle transizioni
sui gruppi Gj:
Gruppo G1 Gruppo G2
S0, 0-1= G1-G2 S1, 0-1= G1-G1
S2, 0-1= G1-G2 S5, 0-1= G1-G1
S3, 0-1= G1-G1
S4, 0-1= G1-G2
S6, 0-1= G1-G2
S7, 0-1= G1-G1

Passo 4.
Individuiamo quindi i sottogruppi Q1=(S0,S2,S4,S6), Q2=(S3,S7) e Q3=(S1,S5) che compongono la P2.

Passo 5.
Come al passo 3., applichiamo ad ogni sottogruppo gli ingressi:
Gruppo Q1 Gruppo Q2 Gruppo Q3
S0, 0-1= Q1-Q3 S3, 0-1= Q2-Q1 S1, 0-1= Q1-Q2
S2, 0-1= Q1-Q3 S7, 0-1= Q2-Q1 S5, 0-1= Q1-Q2
S4, 0-1= Q1-Q3
S6, 0-1= Q1-Q3
Notiamo che non si ottengono altri sottogruppi, quindi il metodo di partizione si interrompe.

Passo 6. 0/0

Q1
0/0 1/0
1/0
Q2

0/0
1/1

Q3
Si individuano quindi tre stati differenti equivalenti a Q1, Q2, Q3 di cui si conoscono le transizioni e le
uscite per ogni valore di ingresso, infatti:
Q1 e I=0: U=0 (da uno stato qualsiasi di Q1) e transizione in Q1 (vedi P2);
Q1 e I=1: U=0 (da uno stato qualsiasi di Q1) e transizione in Q3 (vedi P2)
S3Abacus Architetture/Asm .doc - 1684Kb - 08/mar/2011 - 10 / 84

Q2 e I=0: U=0 (da uno stato qualsiasi di Q2) e transizione in Q2 (vedi P2)
Q2 e I=1: U=0 (da uno stato qualsiasi di Q2) e transizione in Q1 (vedi P2)
Q3 e I=0: U=0 (da uno stato qualsiasi di Q3) e transizione in Q1 (vedi P2)
Q3 e I=1: U=1 (da uno stato qualsiasi di Q3) e transizione in Q2 (vedi P2);
S3Abacus Architetture/Asm .doc - 1684Kb - 08/mar/2011 - 11 / 84

Esempio 5.
E' dato un file di testo, formattato tipograficamente, giustificato con spazi a sinistra, numero di pagina,
intestazione, e caratteri di controllo.
Si deve ottenere un file di testo ASCII, non formattato, con una sola riga al posto dei salti pagina, senza
spazi a sinistra, eliminando tutti gli eventuali spazi di giustificazione tra le parole.
Si ricorda che un salto riga descritto dai due caratteri ascii sequenziali CR/LF (13,10); indichiamo con ^
i caratteri di controllo.

T = {...}
I = {file originale}
VI = {0..255} {[A..Z], [10], [13], [32], [^]} dove [A..Z] indicano gli ASCII [32..125]
U = {file da ottenere}
VU = {0, 255, Null}
S = ...

In Turbo Pascal questo si realizza con un ARRAY di


A..Z/A..Z
32/32 32/Null BOOLEAN, un elemento dell'array per ogni stato.
OK A..Z/A..Z SP

A..Z/A..Z 32/Null ^/Null


10/Null ^/Null
LF/Null
10/Null
A..Z/Null
SP/Null
^/Null 13/Null ^/Null
LF ^
13/Null A..Z/A..Z
10/Nullll 13/Null
13/Null
^/Null
10/Null

10/Null
CR Riga 13/Null
32/Null
10/Null
32/Null
CR/CR

Per indicare lo stato attuale si pone a TRUE l' elemento (FALSE in caso contrario); si avranno quindi 6
istruzioni IF per ogni stato che selezioneranno le valutazioni opportune degli ingressi e determineranno
uscite e transizioni.
Aggiungere uno stato molto facile: basta aggiungere un blocco di 6 IF.

Al trascorrere del tempo, e al variare degli ingressi, ogni sistema significativo modifica il suo stato (o i
suoi stati). La configurazione che assumono gli stati di fondamentale importanza per lo studio del sistema.
Tale configurazione detta, genericamente, movimento.

Come al solito il diagramma a fianco, rappresenta per gli automi a stati finiti l'equivalente della funzione
di Trasformazione e, se riportante anche le uscite (come in questo caso) esso sintetizza anche la funzione di
Trasferimento.

Simulazione per l' automa (filtro-file):

Tempi Ingressi Stati Uscite


t0 a OK a
t1 n OK n
t2 32 OK 32
t3 32 SP Null
t4 13 SP Null
t5 10 CR Null
t6 ... LF ...
... ... ... ...

La colonna degli stati rappresenta quello che, per sistemi continui, chiameremo Movimento.
S3Abacus Architetture/Asm .doc - 1684Kb - 08/mar/2011 - 12 / 84

RAPPRESENTAZIONE E CODIFICA
DELLINFORMAZIONE

NOTAZIONI E RAPPRESENTAZIONI POSIZIONALI


Un sistema di numerazione linsieme delle convenzioni che si debbono seguire per descrivere ed operare sul concetto primitivo di numero. Il
concetto originale unico ed stato assiomatizzato da tempo, ma il modo in cui esprimerlo, che potremmo associare ad una lingua non unico
(come uniche non sono le lingue con le quali si pu operare sulle cose).
Il sistema di numerazione adottato universalmente il sistema decimale, ovvero in base 10, introdotto verso il 1200 dalla cultura araba; tale sistema
detto p o s i z i o n a l e .
Il sistema in uso precedentemente nella nostra cultura era quello romano di tipo additivo ed era basato sull'insieme dei simboli: I,V,X,L,C,D,M (es.
MCMXCII=1992).
Questo sistema, oltre ad essere scarsamente leggibile poich ogni cifra per essere decodificata costringe sempre ad un calcolo, non permette di
utilizzare i sistemi di calcolo veloci per le operazioni sulle cifre, ad esempio quando si volessero applicare le quattro operazioni aritmetiche.
I sistemi posizionali al contrario risultano pi compressi e veloci oltrech intuitivi nella decodifica - si pensi solo al fatto che una cifra con un numero
maggiore di simboli di unaltra indica direttamente il fatto di esserne maggiore. Essi sono inoltre adatti per effettuare calcoli aritmetici veloci.
Le caratteristiche di un qualsiasi sistema di numerazione posizionale sono:

- Base, e cio il numero di simboli utilizzabili per rappresentare una cifra qualsiasi;
- Set di simboli, cio linsieme dei simboli utilizzabili;
- Peso del simbolo, cio la posizione che ogni simbolo assume allinterno di una qualsiasi cifra adottando una numerazione che parte da zero per il
simbolo pi a destra nella rappresentazione.

Esistono anche sistemi di numerazione misti, cio che utilizzano il sistema decimale allinterno di classi di numeri suddivise in base ad una seconda
base detta secondaria, come il sistema sessaggesimale per la numerazione degli angoli.
Spesso risulta pi comodo e veloce esprimere i numeri in una base diversa da 10, pertanto necessario possedere una certa pratica nel
manipolare direttamente i numeri in diverse basi. Dato per che il sistema di riferimento quello a base 10 sar sempre utile sapere anche
trasformare numeri da una base diversa da dieci alla base di riferimento.
In sostanza vedremo come operare direttamente su sistemi di numerazione in diverse basi e, sempre, sapere trasformare ogni risultato parziale in
base 10 e viceversa.
Risulta fin da ora intuitivo che, essendo la logica elettronica ed informatica basata su due soli stati spesso rappresentabili in ultima istanza con due
livelli di tensione, un sistema di numerazione particolarmente utile sar il sistema in base 2 o binario.
Per analoghe considerazioni si vedr come utili saranno anche quei sistemi che utilizzano basi direttamente connesse alla base 2 e cio sistemi di
numerazione la cui base una potenza di due (sistemi di numerazione in base 4, 8 e 16).

Indichiamo con il termine n u m e r o il concetto generale ed intuitivo di numero, a prescindere dalla sua rappresentazione;
Indichiamo con c i f r a la rappresentazione in simboli di un numero in un determinato sistema posizionale;
Si ricorda che per s i m b o l o si intende uno qualsiasi dei simboli appartenenti al set di simboli di un determinato sistema posizionale.

Si pu dire quindi che un determinato numero rappresentato dalla cifra 101 nel sistema di numerazione posizionale in base dieci utilizzando i
simboli 1 e 0 della base decimale.
Ogni cifra quindi dovr essere dotata di una specificazione che indichi il sistema di numerazione in cui espressa, dato che purtroppo gli insiemi di
simboli utilizzati dalle diverse basi di numerazione spesso coincidono.
Dato che si analizzeranno pi frequentremente i sistemi in base dieci, in base due, in base otto, e in base sedici, utilizzeremo rispettivamente le
lettere D, B, O, e H (Hex) per indicare i sistemi di numerazione; pertanto la cifra di poco fa si scriver:
(101)D , mentre le cifre (101)B , (101)O , (101)H rappresenteranno altri tre diversi numeri nelle basi due, otto e sedici.

La rappresentazione di numeri in un sistema posizionale di base generica N composta da n simboli sempre traducibile con uno stesso algoritmo;
infatti data una cifra qualsiasi composta da una sequenza di k simboli S, e assegnati i pesi ad ogni simbolo si ottiene sempre:
k
Sk... S2S1S0 N Si n N
iN

i0

ESEMPIO: RAPPRESENTAZIONE DECIMALE

Data la cifra 143 in base 10, verificare la formula .


Per la cifra data gli ingredienti di sono:
k=2;
N=D
n=10; quindi:
(0) (1) (2)
(143)D 310
( )D D 410
( )D D 110
( )D D (3 * 1 4 * 10 1 * 100)D (143)D

Data la cifra 123 in base 4, verificare la formula .


Per la cifra data gli ingredienti di sono:
k=2;
N=Q
n=4; quindi:
(0)Q (1)Q (2)Q
(123)Q 3(10)Q 2(10)Q 1(10)Q (3 * 1 2 * 10 1 * 100)Q (123)Q
S3Abacus Architetture/Asm .doc - 1684Kb - 08/mar/2011 - 13 / 84

Naturalmente la formula generalizzabile per rappresentazioni di cifre con parte frazionaria, avendo cura di pesare i simboli a partire da -1 per il
simbolo immediatamente posto dopo la virgola.

ESEMPIO: RAPPRESENTAZIONE DECIMALE DI CIFRA CON VIRGOLA

Data la cifra 234,31 in base 10, verificare la .

( )(D3)D 110
, )D 210
(34312 ( )(D2)D 310
( )(D1)D 410
( )(D0)D ( )(D1)D (2 * 103 1 * 102 3 * 101 4 * 100 3 * 101
310
= (2 * 0,001 1 * 0,01 3 * 0,1 4 * 1 3 * 10)D (34312
, )D

Il sistema di numerazione posizionale a noi noto il sistema a base dieci. Ci significa che il set di simboli utilizzati per la rappresentazione dei
numeri composto da dieci simboli: 0,1,2,3,4,5,6,7,8,9.
I numeri sono quindi rappresentati da cifre che, a partire dal primo numero, lo zero, associano in sequenza i simboli formando dieci
rappresentazioni da un simbolo.
Per i numeri successivi la rappresentazione si comporr di due simboli, il primo dei quali sar il secondo simbolo (1) e il secondo simbolo sar
progressivamente la successione dei dieci simboli nello stesso ordine in cui si erano disposti per la rappresentazione a un solo simbolo.
Questo meccanismo quindi si ripete progressivamente e si otterranno via via rappresentazioni con tre, quattro, cinque, ..., simboli in sequenza.
Tale regola, che per tutti implicita, consente anche di effettuare i calcoli aritmetici semplici - addizione, sottrazione, moltiplicazione e divisione -
utilizzando sostanzialmente il solo accorgimento del riporto e del prestito, dato che moltiplicazioni e divisioni sono riconducibili rispettivamente a
addizioni e sottrazioni ripetute.
Le stessa regole di formazione delle cifre e di calcolo tra le cifre si applicano pari pari in ogni altra rappresentazione di numeri in altre
basi.

SISTEMA DI NUMERAZIONE IN BASE DUE (BIN)


In questo caso i simboli utilizzati per descrivere i numeri e costruirne le rappresentazioni (cifre) sono due: 0 e 1.
Per quanto detto precedentemente, la costruzione delle rappresentazioni dei numeri quindi sar la seguente:
0,1,10,11,100,101,110,111,1000,1001, ..., tutte rappresentazioni in base 2 e quindi pi precisamente:
(0)B , (1)B , (10)B , (11)B , (100)B , (101)B , (110)B , (111)B , (1000)B , (1001)B , ...

Naturalmente eseguire i calcoli i base due pu non essere immediatamente intuitivo;il fatto che 1+1 faccia 10 non proprio naturale anche se
proprio cos dato che 10 in binario rappresenta il numero due, come si pu verificare dalla sequenza sopra riportata.
Il gioco dei riporti e dei prestiti si riduce quindi ad una conoscenza pratica dellaritmetica binaria in cui, ad esempio:
0-1 = -1 OPPURE 1 con prestito 1 dalla cifra a sinistra;
1+1 = 10 OPPURE 0 con riporto 1 sulla cifra a sinistra;
1+1+1+1+1 = 101 OPPURE 1 con riporto 10 sulle cifre a sinistra.

La somma e la sottrazione quindi si riducono in una opportuna gestione dei riporti e dei prestiti.
La moltiplicazione risulta essere molto semplice dato che le singole moltiplicazioni tra cifre binarie sono banali:
0*0=0; 0*1=0; 1*1=1.
Anche la divisione risulta semplice dato che il divisore se inferiore al dividendo sta una volta (Q=1) o se superiore sta zero volte (Q=0) e quindi il
ricalcolo del resto dopo la moltiplicazione per 1 o per 0 diventa immediato: basta eseguire una sottrazione binaria.

ESEMPIO: CALCOLI BINARI


Si calcoli (101001)B + (11110)B. Si calcoli (110110)B : (1001)B.
r _______ - -
1 0 1 0 0 1 + ( 41 ) + 1 1 0 1 1 0 : 1 0 0 1 = 1 1 0
1 1 1 1 0 = ( 30 ) = 1 0 0 1
-------------- -------- -------
1 0 0 0 1 1 1 ( 71 ) - 1 0 0 1
1 0 0 1
Si calcoli (101011)B * (111001)B. -------
1 0 1 0 1 1 * - 0 0 0 0
1 1 1 0 0 1 =
----------- Quindi Q=110 e R=000
1 0 1 0 1 1
0 0 0 0 0 0 - Si calcoli (110011)B : (1000)B.
0 0 0 0 0 0 - - _______ - -
1 0 1 0 1 1 - - - 1 1 0 0 1 1 : 1 0 0 0 = 1 1 0 . 0 1 1
1 0 1 0 1 1 - - - - 1 0 0 0
1 0 1 0 1 1 - - - - - -------
----------------------- - 1 0 0 1
1 0 0 1 1 0 0 1 0 0 1 1 1 0 0 0
-------
Si calcoli (10000)B meno (1)B. - 0 0 1 1 0 0
1 0 0 0
p p p p
-------
1 0 0 0 0 -
- 1 0 0 0
1 =
---------
Quindi Q=110.011 e R=000
1 1 1 1
Si calcoli (111100)B : (111)B.
S3Abacus Architetture/Asm .doc - 1684Kb - 08/mar/2011 - 14 / 84

_____ - - -
1 1 1 1 0 0 : 1 1 1 = 1 0 0 0 . 1 0 0 1 1 0 0 0.1 0 0 1 *
1 1 1 1 1 1 =
----- ---------------
- - - 1 0 0 0 1 0 0 0 1 0 0 1
1 1 1 1 0 0 0 1 0 0 1 -
------- 1 0 0 0 1 0 0 1 - -
- - - 1 0 0 0 -------------------
1 1 1 1 1 1 0 1 1.1 1 1 1 +
------- 0.0 0 0 1 =
- - - 1 -------------------
1 1 1 1 0 0.0 0 0 0
Quindi Q=1000.1001 e R=0.0001, infatti:

SISTEMA DI NUMERAZIONE IN BASE OTTO (OCT)


In questo caso i simboli utilizzati per descrivere i numeri e costruirne le rappresentazioni (cifre) sono otto: 0,1,2,3,4,5,6,7. Pertanto non potranno
aversi rappresentazioni del tipo (1769)O, dato che il simbolo 9 non fa parte del set del sistema ottale.
Per quanto detto precedentemente, la costruzione delle rappresentazioni dei numeri quindi sar la seguente:
(0)O , (1)O , (2)O , (3)O , (4)O , (5)O , (6)O , (7)O , (10)O , (11)O , ...

Anche in questo caso bisogna tener presente laritmetica ottale che prevede prestiti e riporti opportuni:
6+2 = 10 OPPURE 0 con riporto 1 sulla cifra a sinistra
4+10+7 = 23 OPPURE 3 con riporto di due sulla cifra a sinistra

Spesso si eseguono calcoli in base ottale facendo a mente le trasformazioni in decimale degli operandi, trovando il risultato in decimale e quindi
riconvertendo il risultato in ottale.
Ancora meglio eseguire i caloli direttamente in ottale facendo uso delle tabelline di +, - e * riportate in ottale in modo da non confondere i riporti.

ESEMPI: CALCOLI OTTALI


Calcolare (5327)O + (321)O. 2 4 5 3
5 3 2 7 + 1 0 6 7 -
3 2 1 = ---------
------- 1 3 3 4 3
5 6 5 0
Calcolare (715206)O - (31777)O
Calcolare (275)O * (37)O 7 1 5 2 0 6 -
2 7 5 * 3 1 7 7 7 =
3 7 = -----------
------ 6 6 3 2 0 7

SISTEMA DI NUMERAZIONE IN BASE SEDICI (HEX)


In questo caso i simboli utilizzati per descrivere i numeri e costruirne le rappresentazioni (cifre) sono sedici e il sistema anche detto Esadecimale:
0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F.
Come di norma, la sequenza numerica di rappresentazione sar:

(0)H , (1)H , (2)H , (3)H , (4)H , (5)H , (6)H , (7)H , (8)H , (9)H , (A)H , (B)H , (C)H , (D)H , (E)H , (F)H ,(10)H , (11)H , ...

Anche in questo caso potrebbe essere utile disporre di tabelline per il calcolo esadecimale, relativamente alle operazioni aritmetiche.

ESEMPIO: CALCOLI IN ESADECIMALE


Calcolare (A701)H + (FFB)H : 1 6 8 5 6
A 7 0 1 +
F F B = Calcolare (FAC0)H * (21C)H :
------- F A C 0 *
B 6 F C 2 1 C =
-------
Calcolare (1A001)H meno (37AB)H : B C 1 0 0
1 A 0 0 1 - F A C 0 -
3 7 A B = 1 F 5 8 0 - -
--------- -------------
2 1 0 E D 0 0

TRASFORMAZIONI TRA SISTEMI POSIZIONALI


Lalgoritmo che a partire dalla rappresentazione di un numero in una data base N composta da n simboli, fornisce la rappresentazione dello stesso
numero in una diversa base M composta da m simboli si pu enunciare a passi:

S3Abacus Architetture/Asm .doc - 1684Kb - 08/mar/2011 - 15 / 84

0. Costruire una tabella biunivoca con le rappresentazioni dei simboli nella base maggiore associate alle rappresentazioni delle cifre della base
minore.
1. Considerare la cifra data come dividendo, la base di destinazione come divisore, effettuare la divisione (nella base di partenza) con i numeri
rappresentati nella base di partenza.
2. Considerare il quoziente Q e il resto R della divisione; indicare con indice progressivo a partire da zero il resto R e ripetere il passo 1.
utilizzando Q come dividendo.
3. Procedere fino a quando Q coincide con zero.
4. Considerare i resti Ri indiciati. La nuova rappresentazione si ottiene disponendo i resti R i secondo lindice che rappresenter il peso e
traducendo eventualmente ogni resto Ri con la tabella di cui al punto 0.

Quando si avessero cifre decimali con parte frazionaria, si pu applicare un ulteriore algoritmo da applicare sulla parte frazionaria, del tutto
autonomo e che consente di ottenere la parte frazionaria nella base desiderata:

1. Considerare la cifra frazionaria nella base di partenza e moltiplicarla per la base di destinazione espressa nella base di partenza.
2. Si ottiene una cifra in cui si nomina la parte frazionaria F e la parte intera I indiciandola a partire da -1.
3. Ripetere i passi 1. e 2. fino a ottenere F=0 o fino a quando richiesto.
4. La cifra frazionaria richiesta nella base di destinazione si ottiene dalle parti intere Ii in cui lindice i il peso.

ESEMPIO: TRASFORMAZIONE DI CIFRE TRA BASI

Trasformare la cifra 123,625 espressa in base dieci nellequivalente espressa in base due.
Parte Intera
Passo 0.
La tabella diventa:
DEC BIN
0 0
1 1
2 10
3 11
4 100
5 101
6 110
7 111
8 1000
9 1001

Passo 1. e 2.
123 DIV 2 Q:61 R0:1
61 DIV 2 Q:30 R1:1
30 DIV 2 Q:15 R2:0
15 DIV 2 Q: 7 R3:1
7 DIV 2 Q: 3 R4:1
3 DIV 2 Q: 1 R5:1
1 DIV 2 Q: 0 R6:1

Passo 3.
La rappresentazione equivalente binaria della parte intera: (123)D = (R6R5R4R3R2R1R0)B = (1111011)B

Parte Frazionaria
Passo 1. e 2.
0,625 * 2 = 1,25 F:0,25 I-1:1
0,25 * 2 = 0,50 F:0,5 I-2:0
0,5 * 2 = 1,0 F:0 I-3:1

Passo 3.
La rappresentazione equivalente binaria della parte frazionaria: (0,625)D = (I-1I-2I-3)B = (0,101)B

Totale
In totale allora: (123,625)D = (1111011,101)B

Trasformare la cifra 101010 espressa in base due nellequivalente espresso in base dieci.
Parte Intera
Passo 0.
La tabella, come prima, diventa:
DEC BIN
0 0
1 1
2 10
3 11
4 100
5 101
6 110
7 111
8 1000
9 1001
S3Abacus Architetture/Asm .doc - 1684Kb - 08/mar/2011 - 16 / 84

Passo 1.
Attenzione, la base di destinazione, dieci, in binario vale 1010!

101010 DIV 1010 Q:100 R0:10 [=2]


100 DIV 1010 Q:0 R1:100 [=4]

e, pertanto, (101010)B = (42)D

Come si pu facilmente notare quando la base di partenza diversa da dieci, lalgoritmo costringe ad usare, per le divisioni, laritmetica della
base (diversa da dieci) che non sempre risulta essere ben conosciuta, o almeno non quanto laritmetica decimale.
In effetti esiste una via alternativa per passare da una base N (10) ad una base M (10) che consiste nel passaggio intermedio alla base dieci.
Infatti esiste un algoritmo piuttosto semplice per trasformare una cifra espressa in una base N (10) alla cifra equivalente in base dieci:
k
Sk... S2S1S0 N (Si)D n D
i D

i0
Allora, dalla base dieci alla base M (10) di destinazione si pu effettivamente adottare lalgoritmo che implica lutilizzazione dellaritmetica
decimale.

ESEMPI: TRASFORMAZIONI DA BASI N10 A BASE DIECI


Trasformazioni BIN DEC = 28225
(11010)B = (x)D
x = 0*20 + 1*21 + 0*22 + 1*23 + 1*24 = (713,52)O = (x)D
= 0*1 + 1*2 + 0*4 + 1*8 + 1*16 = x = 2*8-2 + 5*8-1 + 3*80 + 1*81 + 7*82 =
= 0 + 2 + 0 + 8 + 16 = = 2/64 + 5/8 + 3 + 8 + 7*64 =
= 26 = 459,65625

(101,11)B = (x)D Trasformazioni HEX DEC


x = 1*22 + 0*21 + 1*20 + 1*2-1 + 1*2-2 = (A01F)H = (x)D
= 1*4 + 0*2 + 1*1 + 1*(1/21) + 1*(1/22) = x = 15*160 + 1*161 + 0*162 + 10*163 =
= 4 + 0 + 1 + 0,5 + 0,25 = = 15 + 16 + 0 + 40960 =
= 5,75 = 40991

Trasformazioni OCT DEC (1F,2A)H = (x)D


(67101)O = (x)D x = 15*160 + 1*161 + 2*16-1 + 10*16-2 =
x = 1*80 + 0*81 + 1*82 + 7*83 + 6*84 = = 15 + 16 + 2*(1/16) + 10*(1/256) =
= 1 + 0 + 64 + 3587 + 24576 = = 31,1640625

ESEMPI: TRASFORMAZIONI DA BASE 10 A BASE N10


Trasformazione DEC BIN 3674 | 2 0,65625 * 8 = 5,25
(1045,123)D = (x)B 459 | 3 0,25 * 8 = 2,0
57 | 1
1045 | 1 0,123 * 2 = 0,246 7 | 7
522 | 0 0,246 * 2 = 0,492 0 |
261 | 1 0,492 * 2 = 0,984
130 | 0 0,984 * 2 = 1,968 x = 7132,52
65 | 1 0,968 * 2 = 1,936
32 | 0 0,936 * 2 = ... Trasformazione DEC HEX
16 | 0 (40991,615)D = (x)H
8 | 0
4 | 0 0,615 * 16 = 9,84
2 | 0 0,84 * 16 = 13[D],44
1 | 1 40991 | 15 = F 0,44 * 16 = 7,04
0 | 2561 | 1 0,04 * 16 = 0,64
x =10000010101,00011 160 | 0 0,64 * 16 = 10[A],24
10 | 10 = A 0,24 * 16 = 3,84
Trasformazione DEC OCT 0 | 0,84 ...
(3674,65625)D = (x)O
x = A01F,9D70A3

RAGGRUPPAMENTO DI BIT
I sistemi di numerazione in base potenza di due, come ad esempio il sistema Ottale o il sistema Esadecimale posseggono una propriet particolare
nei confronti del sistema Binario. Molto probabilmente la stessa propriet valida tra basi analoghe (es. base 3 e basi 9, 12, ecc..).
La propriet consiste in questo:
Si considerino una base opportuna N, in modo che k : 2k = n e si decodifichino in binario tutti gli n simboli della base N in modo da ottenere n
rappresentazioni binarie da k simboli binari ognuna (riempiendo eventualmente con zeri).
Allora data una qualsiasi cifra in base N, si ottiene la rappresentazione binaria di quella cifra sostituendo ad ogni simbolo della cifra la
corrispondente codifica binaria
S3Abacus Architetture/Asm .doc - 1684Kb - 08/mar/2011 - 17 / 84

ovvero
Data una cifra binaria qualsiasi, si possono raggruppare i bit in gruppi da k elementi, a partire da destra; si ottiene la rappresentazione in base N
sostituendo ai gruppi il rispettivo simbolo in base N.
Se si fosse in presenza di cifre dotate di parte frazionaria, il raggruppamento della parte frazionaria deve partire immediatamente dopo la virgola.
Questa curiosa ma estremamente utile propriet anche detta del r a g g r u p p a m e n t o d i b i t .

ESEMPI: RAGGRUPPAMENTO DI BIT


Siano ad esempio le tabelle di decodifica:
BIN OCT BIN HEX BIN HEX
0 000 0 0000 8 1000
1 001 1 0001 9 1001
2 010 2 0010 A 1010
3 011 3 0011 B 1011
4 100 4 0100 C 1100
5 101 5 0101 D 1101
6 110 6 0110 E 1110
7 111 7 0111 F 1111

Sia data la cifra (7630)O quindi si ottiene:


7 6 3 0 Sia data (11001.01011)B, pertanto:
111 110 011 000, cio (7630)O = (111110011000)B 11 001 010 110
3 1 2 6, cio: (11001.01011)B = (31,26)O
Sia data la cifra (5A,6)H, quindi si ottiene: oppure
5 A 6 1 1001 0101 1000
0101 1010 0110, cio (5A,6)H = (1011010,011)B 1 9 5 8, cio: (11001.01011)B = (19,58)H

CONTENITORI BINARI
Allinterno delle macchine digitali le informazioni sono sempre rappresentate numericamente, anche le informazioni di natura non numerica come ad
esempio parole ed immagini.
Evidentemente esistono modi specifici per interpretare linformazione numerica di volta in volta come numero, numero con segno, numero con parte
decimale, lettera alfanumerica, immagine, ecc...
Linsieme di tali modi di interpretazione detto anche codifica e rappresentazione dellinformazione.
Un aspetto che in ogni caso necessario mettere in evidenza che la rappresentazione numerica generale pi spesso utilizzata per rappresentare
le informazioni rispetto alle macchine digitali la rappresentazione binaria o in generale rappresentazioni in basi potenze di due (base Otto e base
Sedici).
Unaltra considerazione che opportuno ricordare sempre che i contenitori digitali delle informazioni numeriche sono sempre ben definiti in
dimensione, in genere misurati con gruppi da otto bit detti B y t e (due simboli esadecimali).
Altre misurazioni tipiche sono il N i b b l e (4 bit ovvero un simbolo esadecimale) o la P a r o l a , detta spesso anche Word, contenente in genere 16 bit
(4 simboli esadecimali).
Unaltra questione terminologica che spesso si accompagna a queste, riguarda il riferimento ai bit di maggior peso in un contenitore, indicati con la
sigla M S B (Most Significant Bit) o il riferimento ai bit di minor peso, indicati con L S B (Low Significant Bit).
La limitatezza intrinseca con la quale si rappresentano le informazioni a livello digitale implica un paio di considerazioni:
- assegnato un certo numero n di bit per la rappresentazione di una informazione, sempre possibile definire un campo di validit per la
rappresentazione, definito dal numero di bit assegnati.
- le rappresentazioni di numerosi numeri allinterno di un contenitore a n bit presenteranno alcuni zeri MSB per completare il contenitore.

Se ad esempio si stabilisce un contenitore da n=8 bit per rappresentare numeri naturali, il campo di validit del contenitore - in questo caso il byte -
va da 0 a 255, infatti la prima rappresentazione possibile evidentemente (00000000) B=(0)D e lultima invece: (11111111)B = (255)D.
Inoltre si pu notare come il numero (7)D, che possiede una rappresentazione binaria in (111)B, in questo caso si rappresenter in (00000111)B.
Si deve notare che se un contenitore provvisto di n bit, i l c a m p o d i v a l i d i t (range) per quel contenitore vale da 0 a 2n -1
Si deve anche considerare poi la situazione per cui una operazione, ad esempio di somma, tra due numeri contenuti nello stesso contenitore,
potrebbe originare un numero con una rappresentazione che utilizza un numero di bit superiori a quelli previsti.
In questo caso si parla di t r a b o c c a m e n t o (overflow) e si pu operare un troncamento dei bit fuoriusciti mantenendo solo i bit allinterno del
contenitore.
A scanso di equivoci sar necessario dora in poi specificare sempre il contenitore per una data rappresentazione, soprattutto per quanto riguarda le
operazioni sui bit che introduciamo ora.

OPERAZIONI BITWISE
Le operazioni a livello di bit (bitwise) si effettuano conoscendo a memoria le rispettive tabelline binarie che coincidono con le tavole di verit gi
viste in logica matematica. Esse sono:

|NOT | |AND | | OR | |XOR


--+--- ------- ------- -------
0 | 1 0|0| 0 0|0| 0 0|0| 0
1 | 0 0|1| 0 0|1| 1 0|1| 1
1|0| 0 1|0| 1 1|0| 1
1|1| 1 1|1| 1 1|1| 0

Se gli operandi non avessero lo stesso numero di bit necessario allineare loperando con minor numero di bit giustapponendo degli zeri.
Esistono anche operazioni miste, cio con un argomento binario e uno decimale, il cui risultato binario.
S3Abacus Architetture/Asm .doc - 1684Kb - 08/mar/2011 - 18 / 84

- SHR (spostamento a destra " b shr n " )


Si tratta di spostare a destra di n posizioni i bit del 1 argomento. I bit LSB naturalmente scompaiono, mentre se loperazione si riferisce ad un
contenitore specifico si sostituiscono gli spazi vuoti con degli 0.
- SHL (spostamento a sinistra " b shl n " )
Si tratta di spostare a sinistra di n posizioni i bit del 1 argomento. Se loperazione si riferisce ad un contenitore specifico si sostituiscono gli spazi
vuoti con degli 0 e i bit MSB man mano scompaiono.
Inoltre si possono ricordare anche operazioni analoghe a queste per sempre riferite a contenitori, dette rotazioni:
- ROR (rotazione a destra " b ror n " )
Analogo a shr, con laccortezza di di far rientrare a sinistra i bit espulsi a destra.
- ROL (rotazione a sinistra " b rol n " )
Analogo a shl, con laccortezza di di far rientrare a destra i bit espulsi a sinistra.

ESEMPIO: OPERATORI SUI BIT


NB. Le cifre sono tutte binarie.
Eseguire NOT(1001);
NOT(1001)=110 oppure, se riferito al byte: 11110110

Eseguire (1001) AND (111);


1001 AND 111 = 1, oppure se riferito al byte: 00000001

Eseguire (1001) OR (111);


1001 OR 111 = 1111, oppure se riferito al byte: 00001111

Eseguire (1001) XOR (111);


1001 XOR 111 = 1110, oppure se riferito al byte: 00001110

Eseguire (1001) SHR (3);


1001 SHR 3 = 0001, oppure se riferito al byte: 00000001

Eseguire (1001) SHL (3);


1001 SHR 3 = 1001000, oppure se riferito al byte: 01001000

Eseguire (00001001) ROR (3);


00001001 ROR 3 = 00100001

Eseguire (00001001) ROL (3);


00001001 ROL 3 = 01001000

Calcolare le seguenti espressioni:


1. (x)B = (34)H SHR 3 = (110100)B SHR 3 = (000110)B
Oppure se riferito a Byte:
(x)B = (34)H SHR 3 = (00110100)B SHR 3 = (00000110)B

2. (x)H = (3F1)H SHL 1 = (1111110001)B SHL 1 = (11111100010)B = (7E2)H


Oppure se riferito a Parola:
(x)H = (3F1)H SHL 1 = (0000001111110001)B SHL 1 = (0000011111100010)B = (07E2)H

Le operazioni a bit Shr e Shl possono essere utilizzate per dividere o moltiplicare per potenze di 2.
In particolare lo Shr divide e restituisce il quoziente (parte intera) della divisione per 2 n, dove n il secondo argomento dell'operazione.
Lo Shl moltiplica e restituisce il prodotto della moltiplicazione per 2 n, dove n il secondo argomento dell'operazione.

MASCHERE DI BIT
Spesso quando si utilizzano informazioni numeriche risulta utile riuscire a sapere se un dato bit di peso n vale zero o uno, oppure necessario
saper mettere a zero o a uno un determinato bit di peso n allinterno di una quantit numerica.

Per leggere il valore del bit di peso n in una configurazione X sufficiente creare un valore dappoggio Mn con uguale numero di bit presenti in X,
porre a 1 il solo bit di peso n e tutti i rimanenti a zero. Ora possibile verificare il bit n-mo di X con loperatore AND, cio:
- se X AND Mn diverso da zero, allora il bit n-simo di X vale 1, altrimenti vale zero.

Per scrivere a 1 il bit n-mo di un valore X invece sufficiente costruire come prima Mn e utilizzare loperatore OR:
- X OR Mn da come risultato ancora X con il bit n-mo sicuramente settato a 1.

Per scrivere a zero il bit n-mo di X invece si nega Mn (ottenendo ad esempio Qn) e si utilizza lAND:
- X AND Qn da come risultato sicuramente X con il bit n-mo a zero.

Si noti che per costruire il valore Mn sufficiente considerare che Mn = 2n.

ESEMPIO: PROPRIET SPOSTAMENTI E MASCHERE DI BIT


Si verifichi che (7)D SHL 2 coincide con (28)D.
(7)D SHL 2 = (111)B SHL 2 = (11100)B = (24+23+22)D = (16+8+4)D = (28)D
Verificare il valore del bit 3 di (26)D.
S3Abacus Architetture/Asm .doc - 1684Kb - 08/mar/2011 - 19 / 84

(26)D = (11010)B; Mn = (01000)B; (11010) AND (01000) = (01000) 0; il bit 3 di (26)D vale 1.
Settare a 1 il bit 3 di (33)D.
(33)D = (100001)B; Mn = (001000)B; (100001) OR (001000) = (101001)
Settare a 0 il bit 4 di (26)D.
(26)D = (11010)B; Qn = (01111)B; (11010) AND (01111) = (01010)

NUMERI CON SEGNO


Ora ci si pone il problema della rappresentazione di numeri con segno, dato che una macchina digitale non possiede il simbolo - e comunque oltre
ad identificare tali rappresentazioni numeriche bisogna anche essere in grado di utilizzarle per le varie operazioni.

Il problema questo: avendo a disposizione uno dei contenitori descritti pi sopra, come possibile rappresentare in modo efficiente numeri con
segno? cio distinguere ad esempio -37 da + 37 dato che la loro rappresentazione binaria assoluta la medesima?
E necessario porre una convenzione di rappresentazione, in modo tale che quando la macchina informata di tale convenzione riguardo una
configurazione binaria essa possa comportarsi di conseguenza.
Naturalmente la convenzione non pu che utilizzare ancora solo i simboli zero e uno, magari disposti con oculatezza.
E anche evidente che se un contenitore di ordine n pu contenere 2n configurazioni di bit di valore assoluto, lo stesso contenitore dovr ora
contenerne la met di segno positivo e laltra met di segno negativo, considerando lo zero avente uno dei due segni.

La convenzione la seguente:
- I numeri positivi mantengono la consueta rappresentazione limitatamente a n-1 bit, badando di mantenere a zero il bit MSB;
- I numeri negativi si ottengono dal rispettivo positivo complementandolo a due in binario.
Loperazione di complementazione a 2 di un numero binario si ottiene facilmente negando il numero e aggiungendo uno.
Consideriamo un contenitore a 4 bit;
numeri positivi: numeri negativi:
0001 = +1 -1 = C2(0001) = (1110)+1 = 1111
0010 = +2 -2 = C2(0010) = (1101)+1 = 1110
0011 = +3 -3 = C2(0011) = (1100)+1 = 1101
0100 = +4 -4 = C2(0100) = (1011)+1 = 1100
0101 = +5 -5 = C2(0101) = (1010)+1 = 1011
0110 = +6 -6 = C2(0110) = (1001)+1 = 1010
0111 = +7 -7 = C2(0111) = (1000)+1 = 1001

Rimangono ora le due sole configurazioni 0000 e 1000 che si decide di assegnare la prima allo zero e la seconda al -8, dato che come si pu
notare, tutti i numeri positivi possiedono il MSB a zero e i numeri negativi a uno.
La ragione per cui si usa la complementazione a due per la rappresentazione dei numeri negativi risiede nella propriet che la somma tra due
numeri con segno risulta essere perfettamente algebrica (se si tronca il traboccamento) e quindi nei vari microprocessori non necessario
realizzare un circuito apposta per la differenza dato che basta il sommatore.
Si pu generalizzare questa convenzione ad un contenitore di n bit e quindi affermare che il campo di validit per numeri con segno vale:
-2n ... +2n -1

ESEMPI: OPERAZIONI CON COMPLEMENTAZIONE


Eseguire su 4 bit: Leggendo le codifiche direttamente dalla tabella:
1. (+4)D + (-3)D (0100)+(1101) = (0001) = (+1)D
2. (-2)D + (+5)D (1110)+(0101) = (0011) = (+3)D
3. (+5)D + (-8)D (0101)+(1000) = (1101) = (-3)D
4. (-1)D + (-4)D (1111)+(1100) = (1011) = (-5)D

Naturalmente se si decidesse di sommare algebricamente -1 a -8 oppure +2 a +7 il risultato non sarebbe corretto e si parla rispettivamente di
u n d e r f l o w e di o v e r f l o w generato dalloperazione. queste situazioni sono rilevate generalmente senza alcun problema dalle macchine digitali.

NUMERI CON PARTE FRAZIONARIA


Lo stesso problema di rappresentazione si ripropone a maggior ragione per numeri con parte frazionaria. in questo caso la classica
rappresentazione in virgola mobile consistente di m a n t i s s a per base elevata ad esponente del tipo mbe (es. 6,68183103 = 0,668183104
= 66818310-2 ) pu essere utilizzata per formalizzare la rappresentazione in v i r g o l a m o b i l e n o r m a l i z z a t a in cui la mantissa tale per
cui: 1/b < m < 1.
Nell'esempio precedente la forma in virgola mobile normalizzata diventa: 0,668183*10 4
Ad esempio, dovendo rappresentare il valore binario 11010,111 (26,875 decimale), la sua virgola mobile normalizzata binaria diventa:
0,1101011110101 (cio 0,8398425), che in una rappresentazione a 16 bit pu diventare:

mantissa esponente
1 1 0 1 0 1 1 1 0 0 0 1 0 1

dove i simboli rappresentano i bit di segno di mantissa ed esponente


Nellesempio entrambi i simboli sarebbero stati a zero dato che la parte esponenziale in genere rappresentata in complemento a due, mentre la
mantissa in modulo e segno.
Il numero di bit dedicati alla mantissa detta p r e c i s i o n e della rappresentazione e il numero di bit destinati all'esponente detto o r d i n e d i
g r a n d e z z a della rappresentazione.
Inoltre, siccome il primo bit dopo il segno della mantissa sempre a 1, esiste la convenzione di darlo per scontato, recuperando quindi una
posizione di precisione (c o n v e n z i o n e d e l b i t n a s c o s t o ).
S3Abacus Architetture/Asm .doc - 1684Kb - 08/mar/2011 - 20 / 84

RAPPRESENTAZIONI IN ECCESSO 2 N-1

Prima di introdurre i dettami dello standard che dal 1980 disciplina la convenzione di rappresentazione dei numeri in virgola mobile, introduciamo un
secondo tipo di rappresentazione dei numeri negativi in formato binario.
Dato un contenitore a m bit, si definisce rappresentazione di numeri n e g a t i v i i n e c c e s s o 2 m-1 la rappresentazione che si ottiene quando, dato
un qualsiasi numero con segno s in notazione decimale ad esempio, si rappresenta quel numero in binario con la forma binaria standard di:
s + 2m-1

ESEMPIO: RAPPRESENTAZIONI IN ECCESSO 8


Se si parla di eccesso 8 significa che il contenitore vale 4 (infatti 24-1 = 8).
Iniziamo la rappresentazione a partire da zero:
0, allora si considera 0 + 8 = 8, la cui rappresentazione binaria 1000, quindi 0 -> 1000
+1, allora si considera +1 + 8 = 9, la cui rappresentazione binaria 1001, quindi +1 -> 1001
+2, allora si considera +2 + 8 =10, la cui rappresentazione binaria 1010, quindi +2 -> 1010
...
+7, allora si considera +7 + 8 =15, la cui rappresentazione binaria 1111, quindi +7 -> 1111

Evidentemente non possibile rappresentare +8, dato che +8+8=16 che non rappresentabile su 4 bit.
Si passa ai numeri negativi, e quindi si inizia con meno uno:
-1, allora si considera -1 + 8 = 7, la cui rappresentazione binaria 0111, quindi -1 -> 0111
-2, allora si considera -2 + 8 = 6, la cui rappresentazione binaria 0110, quindi -2 -> 0110
...
-8, allora si considera -8 + 8 = 0, la cui rappresentazione binaria 0000, quindi -8 -> 0000

Si noti come la rappresentazione eccesso 2m-1 identica alla rappresentazione in complemento due se si
invertono i bit di segno.

STANDARD IEEE 754


Il documento I E E E 7 5 4 prima di tutto classifica le rappresentazioni rispetto alla grandezza dei contenitori e quindi prevede:
- rappresentazione con p r e c i s i o n e s e m p l i c e a 32 bit
- rappresentazione con p r e c i s i o n e d o p p i a a 64 bit
- rappresentazione con p r e c i s i o n e e s t e s a a 80 bit

Naturalmente la rappresentazione dellIEEE tratta numeri reali in virgola mobile normalizzata utilizzando la convenzione del bit nascosto della
mantissa (primo bit della mantissa considerato di default a 1 e quindi non riportato nella rappresentazione), la quale, non essendo completa, viene
chiamata s i g n i f i c a n t e .
Inoltre la normalizzazione in base 2 adottata prevede sempre una cifra intera a 1 binario (cio le normalizzazioni binarie adottate sono della forma
1,bbbbb.... invece che della forma standard 0,bbbbb...); pertanto il bit nascosto non sar la prima cifra dopo la virgola ma il bit a 1 sempre presente
nella parte intera.

Esaminando lo standard in precisione semplice, la disposizione degli elementi allinterno dei 32 bit la seguente:
segno esponente significante

1 8 23

Esaminando lo standard in precisione doppia, la disposizione degli elementi allinterno dei 64 bit la seguente:
segno esponente significante

1 11 52

In precisione estesa i tre campi S,E,M valgono 1,15 e 64.

Le convenzioni utilizzate sono le seguenti:


il bit di segno, che indica il segno globale del numero in virgola mobile, 0 per i numeri positivi e 1 per quelli negativi;
lesponente espresso in eccesso 127 (precisione semplice) o in eccesso 1023 (precisione doppia)
il significante quasi sempre in virgola mobile normalizzata con bit nascosto.
eccezioni:
i. se lesponente vale 0 e il significante vale 0, allora il numero complessivo vale 0 a prescindere dal bit di segno;
ii. se lesponente vale 0 e il significante da 0, il numero complessivo denormalizzato;
iii. se lesponente ha tutti i bit a 1, cio il massimo valore positivo concesso in eccesso 128 o 1024, e il significante vale 0, il numero
complessivo vale infinito ();
iv. se lesponente ha tutti i bit a 1, cio il massimo valore positivo concesso in eccesso 128 o 1024, e il significante 0, il numero
complessivo un NAN (Not a Number) cio ad esempio diviso .

Va da s che un numero in virgola mobile normalizzata non potr avere esponente con tutti zeri o con tutti uno. Infatti si usa leccesso 127 (1023) e
non leccesso 128 (1024) per evitare le due configurazioni di esponente con tutti i bit uguali.
S3Abacus Architetture/Asm .doc - 1684Kb - 08/mar/2011 - 21 / 84

Un numero denormalizzato tale quando lesponente vale 0 e il significante 0; in questo caso si da come convenzione che lesponente vale 2-127
(o 2-1023) e il significante ridiventa una mantissa non essendoci pi il bit nascosto. In questo caso si ottengono rappresentazioni fino a 2 -150 (o 2-1075)
che allontanano lunderflow.

ESEMPIO: RAPPRESENTAZIONI IN PRECISIONE SEMPLICE IEEE 754


Vediamo la rappresentazione del numero 1,5 in precisione semplice.
Trasformato in binario si ottiene: (1,1)B.
Normalizzato: 1,1 100 (attenzione: 10B = 2D !)
Mantissa: 11000000
Significante: 10000000 (tolto il primo bit)
Esponente: (0)B = (0)D, quindi in eccesso 127: (0+127)D = (127)D = (01111111)B
Segno: 0
(00111111110000000000000000000000)B IEEE754 = (1,5)D
(3 F C 0 0 0 0 0 )H IEEE754 = (1,5)D

Vediamo la rappresentazione per 128,5.


Binario: 10000000,1
Normalizzato: 1,00000001 10111
Mantissa: 100000001
Significante: 00000001
Esponente: (111)B = (7)D, quindi in eccesso 127: (7+127)D = (134)D = (10000110)B
Segno: 0
(01000011000000001000000000000000)B IEEE754 = (128,5)D
(4 3 0 0 8 0 0 0 )H IEEE754 = (128,5)D

Per 1 si ottiene 3F800000


per 0,5 si ottiene 3F000000.
S3Abacus Architetture/Asm .doc - 1684Kb - 08/mar/2011 - 22 / 84

CODICI, COMUNICAZIONE, INFORMAZIONE


Le rappresentazioni numeriche su diverse basi che si sono studiate in precedenza sono necessarie per poter far funzionare le macchine digitali, le
quali possiedono unit intelligenti basate solo sullaritmetica binaria. Possiamo affermare che le rappresentazioni numeriche su diverse basi sono
parte integrante e interna alle macchine digitali (i calcolatori).
In questo capitolo invece si prendono in considerazione vari modi per rappresentare linformazione, e quindi non necessariamente i numeri.
Qualche malinteso potrebbe sorgere dato che anche i numeri sono informazione, ma, come ci insegna lesperienza, ne rappresentano solo una
parte. Ad esempio una qualsiasi frase tratta dallesperienza quotidiana rappresenta informazione: Dove ti rechi oggi pomeriggio?; questa frase
informazione, ma non contiene numeri. Cionoindimeno molta informazione utilizza numeri al suo interno, senza i quali non significherebbe nulla:
Oggi vado a scuola alle 8 e 30. Il fatto che avremmo potuto esprimere la stessa informazione con: Oggi vado a scuola alle otto e trenta per ora
non sar considerato.
Fondamentale invece la considerazione per cui linformazione ha senso di esistere solo se pu essere veicolata, cio trasferita a qualcuno che sia
diverso da chi la detiene.
Ci significa che linformazione prevede necessariamente la comunicazione e viceversa.
Il problema della codifica e dei codici per linformazione strettamente collegato alla comunicazione.

La comunicazione un processo che si instaura tra due o pi entit, umane o materiali (es. le macchine digitali), che ha lo scopo di trasferire
informazione.
Il processo quindi prevede almeno due soggetti, che possono essere chiamati t r a s m e t t i t o r e e r i c e v i t o r e i quali possono scambiarsi
vicendevolmente i ruoli: il trasmettitore pu diventare ricevente e viceversa. Loggetto della comunicazione invece rimane gi individuato e coincide
con linformazione stessa.
I due soggetti della comunicazione per poter comunicare devono possedere alcuni requisiti indispensabili:
a. un linguaggio in comune (per rappresentare linformazione)
b. un dispositivo per realizzare il linguaggio
c. alcune regole condivise per saper comunicare (per non interferirsi durante la comunicazione)
d. un canale di trasmissione in comune
Abbiamo omesso lapparato ricevente dato che possiamo pensarlo assolutamente integrato nel dispositivo di realizzazione della trasmissione di cui
al punto b.

Questi requisiti sono sempre presenti in ogni forma di comunicazione, dalla comunicazione tramite il l i n g u a g g i o n a t u r a l e tra uomini, alla
comunicazione automatizzata che avviene tra due calcolatori elettronici.
Nel linguaggio naturale si possono individuare le componenti che abbiamo elencato in:
- soggetti della comunicazione: due persone;
- oggetto della comunicazione: un concetto, una frase, ecc...;
- linguaggio della comunicazione: lingua in uso nella comunit a cui appartengono le persone;
- dispositivo della comunicazione: linsieme di cervello, orecchie, lingua e corde vocali posseduto dalle persone;
- regole della comunicazione: es. chiedere la parola e non sovrapporsi, sincronizzando automaticamente ascolto e parlato;
- canale della comunicazione: laria, che consente la propagazione delle onde sonore di cui composto il suono emesso dalla voce.

In una comunicazione automatizzata tra macchine invece potremmo individuare:


- soggetti: due calcolatori;
- oggetto: un qualsiasi insieme di concetti in genere detti dati ;
- linguaggio: una convenzione qualsiasi su come organizzare i bit;
- dispositivo: una scheda di interfaccia;
- regole: un insieme di regole che sincronizza le fasi della comunicazione e che in gergo viene detto protocollo;
- canale: un cavo oppure onde elettromagnetiche (radio), infrarosso, ecc...

ARGOMENTI DI QUESTA SEZIONE SARANNO SOLTANTO:

- il linguaggio di organizzazione dei dati, anche detto c o d i f i c a d e l l e i n f o r m a z i o n i


- alcune regole di sincronizzazione della comunicazione; in particolare quelle volte a individuare gli errori nel processo di comunicazione, detto
anche g e s t i o n e e r r o r i .

Per quanto ci riguarda useremo come unit minima di informazione il bit, cio la possibilit di un sistema di assumere solo due possibili stati che si
indicano in genere con 0 e 1. Linformazione quindi sar identificata con la rappresentazione di dati tramite sequenze di bit.
Se si individuano allora un numero M di dati che saranno oggetto di informazione, la rappresentazione di questa informazione in formato binario -
cio tramite sequenze di bit - potr essere possibile se ad ogni dato tra gli M dati disponibili associabile una differente sequenza di bit.
Se ad esempio si dovesse gestire linformazione basata sulle 26 lettere dellalfabeto inglese, sar necessario individuare 26 configurazioni di bit
differenti per rappresentare ogni singola lettera. In questo caso la quantit di informazione M vale 26. La codifica delle M (=26) informazioni
differenti (=abcdefghijklmnopqrstuvwzxy) avviene associando ad ogni dato (cio ad ogni singola lettera) una sequenza di bit differente in modo
che, data una lettera qualsiasi si possa immediatamente individuare la sua codifica binaria e, data una codifica binaria sia immediatamente possibile
individuare il suo dato (la lettera).
In altre parole, un insieme di potenza M pu essere misurato (interscambiabile) con un insieme di M configurazioni binarie (e viceversa).
Chiarito questo fatto generale, giunge spontaneo porsi il problema: assegnata una quantit di informazione da rappresentare e definita M, quante
cifre binarie (bit) sono necessarie per effettuare le configurazioni che dovranno rappresentare gli M dati?
Il passo successivo riguarda l'individuazione del numero di cifre binarie (N) necessarie per esprimere M informazioni.
Ci deriva dalla relazione seguente per la quale, assegnato M, il valore N si ricava:

N = log2 M (se M potenza esatta di 2)

oppure

N = INT(log2M)+1 (se M non potenza esatta di 2)

con INT() che significa: parte intera di ( ).


S3Abacus Architetture/Asm .doc - 1684Kb - 08/mar/2011 - 23 / 84

ESEMPIO: RAPPRESENTAZIONE OTTIMALE DI INFORMAZIONE

Si debba rappresentare linformazione contenuta nellinsieme delle lettere dellalfabeto inglese.


Le lettere dellalfabeto inglese sono 26, cio M=26;
M non una potenza esatta di due, infatti (24=1626 e 25=3226); allora si utilizza la formula:
N = INT(log2M)+1 con M=26;
N = INT(log226)+1;
N = INT(4.701)+1;
N = 4+1 = 5;
Quindi servono sequenze da 5 bit per rappresentare 26 informazioni differenti
Una possibile codifica delle 26 informazioni potrebbe essere:

a - 00000 f - 00101 k - 01010 p - 01111 u - 10100 x - 11001


b - 00001 g - 00110 l - 01011 q - 10000 v - 10101
c - 00010 h - 00111 m - 01100 r - 10001 w - 10110
d - 00011 i - 01000 n - 01101 s - 10010 z - 10111
e - 00100 j - 01001 o - 01110 t - 10011 x - 11000
Naturalmente rimangono 32-26 = 6 configurazioni da 5 bit inutilizzate.

Si debba rappresentare linformazione relativa ai nominativi degli abitanti di Parma, stimati in 175000 unit
Il dato M quindi vale 175000; siccome 175000 non una potenza esatta di 2 (), si usa la formula:
N = INT(log2M)+1 con M=175000;
N = INT(log2175000)+1;
N = INT(17.41)+1;
N = 17+1 = 18;

Allora con un contenitore da 18 bit si possono rappresentare, con una codifica opportuna, tutti gli abitanti
di Parma.

CODIFICHE NUMERICHE
Come si diceva poco fa, linformazione composta variamente sia di concetti numerici, sia di concetti alfabetici; spesso necessario effettuare
comunicazioni il cui oggetto solo informazione numerica, mentre in altri casi bisogna poter comunicare sia dati numerici che dati alfabetici che, in
una parola, sono detti alfanumerici.
Per questo motivo si distingue tra C o d i f i c h e N u m e r i c h e e C o d i f i c h e A l f a n u m e r i c h e .

La codifica numerica riassume una serie di regole e propriet per rappresentare con configurazioni di bit i simboli numerici decimali da 0 a 9 o, in
qualche caso, i numeri esadecimali da 0 a F.
Le propriet generiche delle configurazioni di bit rappresentanti simboli numerici si possono riassumere:
Distanza di Hamming
Autocomplementazione (solo codifica numerica)
Pesatura (solo codifica numerica)
Ridondanza

La D i s t a n z a d i H a m m i n g tra due configurazioni data dal numero di bit differenti di ugual peso presenti nelle due configurazioni;
La propriet di A u t o c o m p l e m e n t a z i o n e tra due configurazioni si valuta solo quando i simboli numerici rappresentati sono complemento a 9 (o
a F); in questo caso lautocomplementazione presente se le due configurazioni corrispondenti sono complemento a 1 (una la negazione
dell'altra);
La caratteristica della P e s a t u r a rispettata se esiste un algoritmo che applicato ad una configurazione di bit consente di ottenere il simbolo
rappresentato mediante somme di valori sempre uguali per ogni posizioni (sommati o meno a seconda del valore 0 o 1 del bit);
La R i d o n d a n z a in una codifica si ottiene se il numero di configurazioni di bit ottenibili (N) per rappresentare M informazioni superiore al numero
di informazioni, cio se 2N > M.

ESEMPI DI PROPRIET DEI CODICI

Esempio di distanza di Hamming


codifica1: 10101010
codifica2: 10100001
^ ^^
La distanza di Hamming tra le due codifiche vale 3 dato che i bit di ugual peso cambiano tre volte.

Esempi di autocomplementazione
codifica simbolo 3: 0011
codifica simbolo 6: 1100
Le due configurazioni sono complementanti infatti: 3+6=9 e le codifiche sono negate

codifica simbolo 4: 0011


codifica simbolo 6: 1100
Le due configurazioni non sono complementanti infatti (4+69);

codifica simbolo 3: 0011


codifica simbolo 6: 1101
Le due configurazioni non sono complementanti infatti pur essendo 6+3=9, i bit non sono invertiti.
S3Abacus Architetture/Asm .doc - 1684Kb - 08/mar/2011 - 24 / 84

Esempio di pesatura
codifica simbolo 3: 0011, se pesi b3=2, b2=4, b1=2,b0=1 si ottiene 0*2+0*4+1*2+1*1=3;
codifica simbolo 6: 1100, se pesi b3=2, b2=4, b1=2,b0=1 si ottiene 1*2+1*4+0*2+0*1=6;
codifica simbolo 1: 0000, non esiste algoritmo per ottenere 1 da 0000 !

Vediamo ora alcuni tra i pi utilizzati codici numerici e le loro propriet complessive

BCD
b3 b2 b1 b0
CODIFICA NUMERICA BCD 0
1
0
0
0
0
0
0
0
1
2 0 0 1 0
La codifica numerica BCD (B i n a r y C o d e d D e c i m a l ) quella che si ottiene trasformando in 3 0 0 1 1
binario le 10 cifre decimali e considerandone la configurazione a 4 posti (siccome M=10, 4 0 1 0 0
N=log2M+1, cio 4). 5 0 1 0 1
6 0 1 1 0
- Il codice BCD sicuramente pesato (b0=1; b1=2; b2=4; b3=8);
7 0 1 1 1
- ridondante (infatti esistono 6 configurazioni inutilizzate); 8 1 0 0 0
- la distanza di Hamming massima tra due configurazioni adiacenti 4 (tra 7 e 8); 9 1 0 0 1
- non autocomplementante (es. 0 e 9 non hanno i bit invertiti) e cos via

ECCESSO 3
b3 b2 b1 b0
CODIFICA NUMERICA ECCESSO 3 0
1
0
0
0
1
1
0
1
0
2 0 1 0 1
La c o d i f i c a n u m e r i c a E c c e s s o 3 si ottiene da quella BCD iniziando a codificare lo 0 con il 3 0 1 1 0
3
BCD e proseguendo analogamente. 4 0 1 1 1
- Il codice Eccesso 3 non pesato; 5 1 0 0 0
- ridondante (infatti esistono 6 configurazioni inutilizzate); 6 1 0 0 1
7 1 0 1 0
- la distanza di Hamming massima tra due configurazioni adiacenti 4 (tra 9 e 0);
8 1 0 1 1
- autocomplementante (ogni configurazione di cifre complemento a 9 ha i bit corrispondenti 9 1 1 0 0
invertiti)

AIKEN
b3 b2 b1 b0
CODIFICA NUMERICA AIKEN 0
1
0
0
0
0
0
0
0
1
2 0 0 1 0
la c o d i f i c a n u m e r i c a A i k e n si ottiene considerando che il peso dei bit assegnato b3=2, 3 0 0 1 1
b2=4, b1=2, b0=1; 4 0 1 0 0
- Il codice numerico Aiken sicuramente pesato; 5 1 0 1 1
- ridondante (infatti esistono 6 configurazioni inutilizzate); 6 1 1 0 0
7 1 1 0 1
- la distanza di Hamming massima tra due configurazioni adiacenti 4 (tra 9 e 0);
8 1 1 1 0
- autocomplementante (ogni configurazione di cifre complemento a 9 ha i bit corrispondenti 9 1 1 1 1
invertiti)

GRAY
b3 b2 b1 b0
CODIFICA NUMERICA GRAY 0
1
0
0
0
1
1
1
0
0
2 0 1 1 1
La c o d i f i c a n u m e r i c a G r a y si ottiene considerando che la distanza tra una configurazione e 3 0 1 0 1
la
successiva (e la precedente) sempre e solo 1. 4 0 1 0 0
In realt il codice usato per rappresentare 16 simboli a partire dalla prima configurazione per lo 0 5 1 1 0 0
che possiede la forma 0000; il codice Gray a 10 simboli l'eccesso 3 del codice gray a 16 simboli 6 1 1 0 1 (si
7 1 1 1 1
scartano le configurazioni di 0,1,2,D,E,F).
8 1 1 1 0
- Il codice numerico Gray non pesato; 9 1 0 1 0
- ridondante (infatti esistono 6 configurazioni inutilizzate);
- la distanza di Hamming massima tra due configurazioni adiacenti 1;
- non autocomplementante.

CODIFICHE ALFANUMERICHE
CODIFICA ALFANUMERICA BAUDOT
Il c o d i c e B a u d o t stato uno dei primi codici alfanumerici ad essere implementato (serviva per gestire la comunicazione tra telescriventi); si
tratta di un codice a 5 bit per una codifica totale di 32 informazioni; in realt due configurazioni sono dedicate per la decodifica delle successive
(11111=LTR; 11011=NUM) in modo tale da poter interpretare le configurazioni in un modo (LTR=lettera) se anticipate dal blocco LTR o in un altro
(NUM=numero) se anticipate dal blocco NUM.
In tutto quindi si codificano 60 informazioni.

CODIFICA ALFANUMERICA ASCII


Si tratta del codice pi utilizzato nel mondo dei calcolatori (A m e r i c a n S t a n d a r d C o d e I n t e r c h a n g e I n f o r m a t i o n ) e si tratta di un codice
standard di 7 bit (128 informazioni) e pseudostandard a 8 bit (256 informazioni). Il codice ASCII esteso a 8 bit di norma usato sulle macchine PC
detto P C - 8 . Tra le categorie di informazioni codificate allinterno del codice ASCII ricordiamo:
simboli di controllo di trasmissione (da 0 a 6 e da 21 a 23)
S3Abacus Architetture/Asm .doc - 1684Kb - 08/mar/2011 - 25 / 84

simboli di controllo di stampa (da 7 a 15)


simboli di controllo dispositivi (dal 17 al 20)
simboli numerici e alfanumerici (dal 32 al 127)
simboli grafici e tipografici (dal 128 al 255)
S3Abacus Architetture/Asm .doc - 1684Kb - 08/mar/2011 - 26 / 84

CODICI ED ERRORI
Una caratteristica tipica della comunicazione con codifica delle informazioni la possibilit di gestire in fase di ricezione eventuali errori dovuti a
disturbi incontrati dai dati durante la comunicazione. Infatti quando linformazione si trova sul mezzo di trasmissione (cavi, aria, onde
elettromagnetiche) pu subire, in varie misure, interferenze che modificano il contenuto dei bit.
Sintetizzando: succede piuttosto spesso che il trasmettitore trasmette il dato A correttamente, durante la comunicazione eventuali disturbi mutano il
dato in B e quindi il ricevitore riceve B.
Per affrontare politiche di controllo, prevenzione e verifica di errori di trasmissione si possono analizzare e studiare vari aspetti della costruzione dei
codici e delle codifiche.
In questo senso si pu operare per costruire c o d i c i r i v e l a t o r i di errore, mediante i quali possibile stabilire se un dato ricevuto o non
corretto; oppure si possono costruire c o d i c i c o r r e t t o r i di errore mediante i quali si riesce ad individuare l'errore presente nel dato e a
correggerlo automaticamente.
In tutti i casi i codici costruiti in tal senso devono per forza di cose essere r i d o n d a n t i (cio devono contenere pi informazione di quella
strettamente necessaria per il dato da trasmettere), in modo da trasmettere nellinformazione supplementare le informazioni utili per la rilevazione
e/o la correzione dell'errore.

PARIT
Una tecnica molto utilizzata nel campo delle comunicazioni quella di dotare ogni codifica - eventualmente ogni gruppo specificato di codifiche - di
un bit supplementare che vale:
0 se il numero di bit a 1 nella codifica dispari o 1 se il numero di bit a 1 presenti allinterno della codifica pari (p a r i t D I S P A R I )
ovvero
0 se il numero di bit a 1 presenti allinterno della codifica pari o 1 se il numero di bit allinterno della codifica dispari (p a r i t P A R I ).

ESEMPIO: PARIT
Dato da trasmettere: 10000001;
n. di bit a 1: 2; il bit di parit PARI 0; in totale: 10000001(0).

Dato da trasmettere: 10000011;


n. di bit a 1: 3; il bit di parit PARI 1; in totale: 10000011(1).

Oppure

Dato da trasmettere: 10000001;


n. di bit a 1: 2; il bit di parit DISPARI 1; in totale: 10000001(1).

Dato da trasmettere: 10000011;


n. di bit a 1: 3; il bit di parit DISPARI 0; in totale: 10000011(0).

Corredare di controllo di parit un codice significa che il trasmettitore e ricevitore si mettono daccordo a priori sul tipo di parit - Pari o Dispari -, e il
trasmettitore, una volta deciso di inviare una codifica (es. 10000001), calcola il bit di parit della codifica (in questo caso per parit Pari il bit di parit
vale 0) e invece di inviare la codifica originale, invia una nuova codifica in cui compare al primo (o allultimo) posto il bit di parit. Il trasmettitore
quindi spedir: 100000010 (parit pari).
Il ricevitore, che sa di questa convenzione, prende in considerazione la parte di codifica depurata dal bit di parit, ne calcola il bit di parit e lo
confronta con il bit di parit ricevuto.
Il ricevitore quindi potr ricevere, a seconda dei casi:
a) dato corretto, cio 100000010. Egli considerer solo 10000001, ne calcoler il bit di parit (0) e lo confronter con quello ricevuto (0)
deducendo che il dato ricevuto corretto.
b) dato errato, ad esempio 100000110. Egli considerer solo 10000011, ne calcoler il bit di parit (1) e lo confronter con quello ricevuto (0)
deducendo che il dato ricevuto errato.

Naturalmente il metodo di semplice parit offre un sistema per rivelare un errore e non esente da problemi di doppi errori (in cui la parit persiste)
e nel caso in cui lerrore dovesse modificare proprio il bit di parit.
In altri termini il ricevitore riesce solo a stabilire con certezza un errore (quando il controllo di parit non torna), ma non in grado di essere certo
della validit del dato (quando il controllo di parit risulta corretto).

PARIT INCROCIATA
Con la p a r i t i n c r o c i a t a si suggerisce un sistema per rivelare ed individuare (quindi correggere) eventuali errori. Si tratta di applicare la parit
ad un gruppo di dati sia in senso orizzontale (come gi visto prima) detta p a r i t T r a s v e r s a l e , sia in senso verticale, detta p a r i t
Longitudinale.
Tali parit devono quindi essere spedite; la prima assieme ai bit della codifica a cui si riferisce, la seconda come blocco finale al termine della
sequenza. Naturalmente tutto ci verificabile solo su gruppi specificati a priori di codifiche.

ESEMPIO: PARIT INCROCIATA


Vediamo di spedire ad esempio l'informazione ERRORE!! utilizzando ASCII a 7 bit con parit pari incrociata:

informazione ascii 7 bit parit INFORMAZIONE TRASMESSA


trasversale
S3Abacus Architetture/Asm .doc - 1684Kb - 08/mar/2011 - 27 / 84

E 1 0 0 0 1 0 1 1 1 1 0 0 0 1 0 1
R 1 0 1 0 0 1 0 1 1 1 0 1 0 0 1 0
R 1 0 1 0 0 1 0 1 1 1 0 1 0 0 1 0
O 1 0 0 1 1 1 1 1 1 1 0 0 1 1 1 1*
R 1 0 1 0 0 1 0 1 1 1 0 1 0 0 1 0
E 1 0 0 0 1 0 1 1 1 1 0 0 0 1 0 1
! 0 1 0 0 0 0 1 0 0 0 1 0 0 0 0 1
! 0 1 0 0 0 0 1 0 0 0 1 0 0 0 0 1
0 0 0 1 1 1 0 1
0 0 1 1 1 0 1 0
parit longitudinale

Se ad esempio ci fosse un errore di trasmissione nel b0 della lettera O, cio se il ricevente ricevesse 0
invece di 1, facendo i propri conti scoprirebbe che il b0 di parit longitudinale ricevuto sarebbe dovuto
essere 0 (mentre invece 1) e contemporaneamente il b7 della lettera O (parit trasversale) dovrebbe
essere a 0 (invece a 1).
Il ricevente, scoprendo l'incongruenza di b0 Parit Longitudinale e b7 Parit Trasversale, pu dedurre che il
bit errato proprio il b0 della lettera O.

Naturalmente anche in questo caso la parit incrociata fallisce se ci sono errori doppi o se l'errore riguarda proprio le informazioni di parit. Come
prima il ricevitore ha solo certezza quando il controllo di parit incrociata fallisce (ha la certezza dellerrore).

CODICE DI HAMMING
Il c o d i c e d i H a m m i n g consente di aggiungere ad un codice dato, una serie di bit in ogni codifica che consente di rilevare errori singoli e multipli
e, in qualche caso, di autocorreggerli.
Naturalmente non sempre possibile, anche con la codifica di Hamming, poter rilevare o correggere lerrore. In particolare, data la codifica
originale, se la distanza minima di Hamming 2, possibile solo una codifica autorilevante; affinch la codifica sia anche autocorrettiva,
necessario che la distanza minima di Hamming tra le configurazioni sia 3.

Il numero di bit supplementari (k) necessari per dotare un codice a n bit con la codifica di Hamming, si calcola ricordando la r e l a z i o n e d i
Hamming:
n 2k-k-1
dove:
n = numero di bit del codice dato;
k = numero di bit da aggiungere ad ogni codifica per ottenere il nuovo codice rilevatore e correttore;

In questo modo, a partire da un codice a n bit se ne otterr uno a (n + k) bit.

Le fasi per la costruzione del codice sono:


1. Creare una codifica valida con distanza di Hamming opportuna (esempio: 2 o 3) determinando quindi n;
2. Individuazione di k mediante la relazione di Hamming;
3. Scrivere una sequenza vuota di bit di lunghezza j=n+k numerando ogni posizione da sinistra a destra partendo da 1; trascrivere il valore della
posizione riportata anche nella sua forma binaria.
4. Assegnare ai k bit aggiuntivi - chiamati Xi =1...k - le posizioni graduali a potenze di due;
(Es. se k=3; X1 va in posizione 1; X2 va in posizione 2; X3 va in posizione 4); scrivere le descrizioni (o i contenuti) dei bit del codice (detti B i =1...n)
nelle posizioni lasciate libere dagli Xi;
5. Determinare i valori di controllo per ogni X i, individuando le posizioni in cui l'unico bit a 1 della posizione binaria di X i presente nelle rimanenti
posizioni; sommando tutti i bit delle posizioni di controllo (senza riporti) si ottengono i valori per X i

Per il controllo e la verifica:


7. Individuare k cifre binarie dette G i =1...k formanti il numero binario G, dove ogni Gi ottenuto come somma dei bit (senza riporto) di controllo per
Xi compreso se stesso; l'indice i determina la posizione della cifra binaria in G;
8. Se G=0, il codice non contiene errori, se G0, esso indica, in binario invertito, la posizione del bit errato.

ESEMPIO DI CODIFICA DI HAMMING


Costruire il codice di Hamming per la codifica BCD dei simboli numerici.

fase 1.
n=4; infatti la codifica BCD ha bisogno di soli 4 bit: 0=0000; 1=0001; 2=0010; 3=0011; ... ;9=1001

fase 2.
k=3 (infatti se k = 2, n >22-2-1 cio 4 > 1, mentre con k = 3, n =23-3-1, cio 4 = 8-3-1)

fase 3.
Il codice sar formato da j bit: j = n+k = 4+3 = 7;
posizioni decimali: 1 2 3 4 5 6 7
posizioni binarie: 001 010 011 100 101 110 111

fase 4.
X1 X2 B1 X3 B2 B3 B4
- X1 controlla le posizioni 3,5,7 (X1 in posizione 001; le altre posizioni che hanno quel bit a 1 sono 011
(pos. 3), 101 (pos. 5), 111 (pos. 7).
S3Abacus Architetture/Asm .doc - 1684Kb - 08/mar/2011 - 28 / 84

- X2 controlla le posizioni 3,6,7 (X2 in posizione 010; le altre posizioni che hanno quel bit a 1 sono 011
(pos. 3), 110 (pos. 6), 111 (pos. 7).
- X3 controlla le posizioni 5,6,7 (X3 in posizione 100; le altre posizioni che hanno quel bit a 1 sono 101
(pos. 5), 110 (pos. 6), 111 (pos. 7).

fase 5.
Caso simbolo 3=0011 (B1=0; B2=0; B3=1; B4=1)
1 2 3 4 5 6 7
X1 X2 0 X3 0 1 1
X1 = 0+0+1 = 1;
X2 = 0+1+1 = 0;
X3 = 0+1+1 = 0;
pertanto:
1 0 0 0 0 1 1

Controllo:
Ipotesi: spedito 3, ricevuto corretto (1000011)
Determino G = G3 G2 G1 (k=3);
G1 = bit pos1+ bit pos3+ bit pos5+ bit pos7 = 1+0+0+1 = 0;
G2 = bit pos2+ bit pos3+ bit pos6+ bit pos7 = 0+0+1+1 = 0;
G3 = bit pos4+ bit pos5+ bit pos6+ bit pos7 = 0+0+1+1 = 0;
G=000; allora risultato corretto.

Ipotesi: spedito 3, ricevuto sbagliato (1010011)


Determino G = G3 G2 G1 (k=3);
G1 = bit pos1+ bit pos3+ bit pos5+ bit pos7 = 1+1+0+1 = 1;
G2 = bit pos2+ bit pos3+ bit pos6+ bit pos7 = 0+1+1+1 = 1;
G3 = bit pos4+ bit pos5+ bit pos6+ bit pos7 = 0+0+1+1 = 0;
G=011; allora risultato scorretto con errore in pos 3 (011=3).

CODICI CICLICI - CRC


Il metodo dei C o d i c i C i c l i c i (C R C , ovvero C y c l i c R e d u n d a n t C o d e s ) consente di aggiungere a una codifica consueta un numero di bit
supplementare i quali sono in grado di rilevare la presenza di eventuali errori.
A differenza del controllo di parit, se il controllo CRC del ricevitore ha esito positivo si ha la certezza della correttezza del dato e, come prima, in
caso di fallimento del controllo CRC si ha ancora la certezza della scorrettezza del dato.

Data quindi una codifica a n bit, se il calcolo del CRC necessita di k bit, si ottiene una codifica totale composta da (n+k) bit.
Di seguito vediamo le fasi per determinare la codifica dotata di CRC.
Se la sequenza da considerare - cio la codifica, che chiameremo A - contiene n bit:
1. Si considera una nuova sequenza a piacere di k bit (k<n) detta polinomio generatore (G), nel quale il bit pi significativo deve essere 1.
2. Si considera una sequenza di k-1 bit tutti a zero detta G e una nuova sequenza T formata da A giustapposta a G': T'=AG'.
3. Si effettua quindi una divisione tra T' e G in modulo 2 (*) e si ottiene il resto R (con R avente j bit, jk);
4. Si costruisce G'' ottenuto come G' OR R.
5. A questo punto si costruisce T come AG''. T il codice da trasmettere con CRC.

Per il controllo si effettuano le seguenti fasi:


6. Si effettua la divisione in modulo 2 tra T ricevuto e G
7. Se il resto nullo, il codice ricevuto corretto; altrimenti contiene un errore.

Naturalmente la scelta dei polinomio generatore, essendo praticamente libera, si standardizzata su alcuni valori tipici che riportiamo di seguito
(per codifiche complesse formate da un numero molto alto di bit):
CRC_16: 1100000000000101
CRC_CCITT: 1000100000100001
CRC_32: 10000010011000001000111011011001

(*) Le divisioni binarie modulo due sono estremamente pi semplici delle divisioni binarie consuete e pertanto estremamente facile implementarle
in circuiti logici e svolgerle via hardware. Le differenze con la divisione standard sono due:
a. Il divisore sta nel dividendo quando il numero di bit significativi del dividendo pari al numero di bit del divisore (es. 1000 mod2 1101 = 1 !)
b. La differenza per ottenere il resto si effettua con lo XOR e non con la normale sottrazione.

ESEMPIO DI CODIFICA CICLICA


Costruire il CRC per il dato A=1000001 (n=7);

fase 1.
Scelgo G=10001 (k=5)

fase 2.
Allora G'=0000 e quindi T'=AG'=10000010000;

fase 3.
Divisione in modulo 2:
T' : G
10000010000 : 10001 = 1000101
10001
----10100
S3Abacus Architetture/Asm .doc - 1684Kb - 08/mar/2011 - 29 / 84

10001
--10100
10001
--101
Individuo quindi R=101

fase 4.
Costruisco G'' = G' OR R
G'' = 0000 OR 0101 = 0101

fase 5.
Calcolo T con CRC = AG'' = 10000010101

Controllo:
Ipotesi: spedito T come sopra, ricevuto corretto (10000010101)
fase 6.
Effettuo divisione in modulo 2 (T:G):
10000010101 : 10001 = 1000101
10001
----10101
10001
--10001
10001
-----
Il resto nullo, perci ricezione corretta;

Ipotesi: spedito T come sopra, ricevuto scorretto (10000110101)


fase 6.
Effettuo divisione in modulo 2 (T:G):
10000110101 : 10001 = 10001110
10001
----11101
10001
-11000
10001
-10011
10001
---10
Il resto non nullo (10), perci la ricezione scorretta;

CHECKSUM
Spesso, oltre a gestire una codifica che prevede il controllo direttamente sulle singole o su poche configurazioni, possibile, e di fatto molto diffuso,
corredare uninsieme numeroso di configurazioni con qualche nuova configurazione di puro controllo.
In genere queste configurazioni aggiuntive sono poste al termine della sequenza originale di configurazioni, la quale detta in gergo f r a m e ; la
parte aggiuntiva invece, che serve solo per il controllo della integrit del frame, detta C o d a o T a i l o F C S (Frame Control Sequence).
Spesso quindi il frame corredato da una coda che pu contenere ad esempio il CRC calcolato sullintero frame o, molto pi semplicemente, una
configurazione speciale detta C h e c k S u m (letteralmente: somma di controllo).
La configurazione di CheckSum quindi non altro che la somma - logica o aritmetica o calcolata in altro modo ancora - delle varie codifiche
contenute nel frame.
Il calcolo di checksum pi diffuso prevede la somma aritmetica di tutte le configurazioni del frame ottenuta troncando i traboccamenti (rispetto al
contenitore originale delle codifiche del frame). Una sequenza composta da frame+CheckSum costituisce un codice rivelatore di errore, ed anche
detto controllo dellerrore orientato al byte.
La tecnica del calcolo di CheckSum utilizzata spesso nelle comunicazioni seriali tra dispositivi e per frame relativamente poco numerosi (< 100
byte). Era usata, inoltre, nella prima versione di protocollo XMODEM.

ESEMPIO DI CHECKSUM DI UN FRAME

Sia dato un frame composto dai seguenti byte (Hex): 01 A3 74 9C

Si noti come il contenitore originale dei dati del frame sia il byte. La sua CheckSum calcolata con somma
aritmetica ed esclusione del traboccamento (rispetto al byte) vale:

CheckSum = 01 + A3 + 74 + 95 = (1)1D = 1D

Allora lintera sequenza (frame+coda) sar: 01 A3 74 9C 1D

Se il ricevitore ricevesse una sequenza con il secondo byte errato (es. A4 invece di A3), ricalcolando la
CheckSum per proprio conto e confrontandola con la CheckSum ricevuta, si accorgerebbe che la sequenza
presenta almeno un errore.
S3Abacus Architetture/Asm .doc - 1684Kb - 08/mar/2011 - 30 / 84

ARCHITETTURE

La storia del calcolatore elettronico ha inizio in epoca moderna, gi a partire dalla met del 1600, in Francia, con B . P a s c a l , che ide il primo
dispositivo manuale di calcolo aritmetico. Il primo tentativo di calcolatore programmabile fu invece ad opera del britannico C . B a b b a g e , i cui
programmi furono scritti dalla programmatrice Ada Lovelace. Si deve attendere per il 900 per avere il primo effettivo calcolatore programmabile a
rel, probabilmente lo Z 1 del costruttore statunitense Zuse (1936). Il pi significativo calcolatore elettronico invece fu l E n i a c degli statunitensi
Eckert-Mauchley (1944), da cui si svilupp la moderna tecnologia dei calcolatori elettronici, dopo la svolta dell I a s di J . V o n N e u m a n n (1952)
che introdusse, tra le altre innovazioni, luso della numerazione binaria. In seguito, un impulso fondamentale alla tecnologia costruttiva fu
linvenzione del circuito integrato in silicio da parte del premio Nobel R . N o y c e (1958, poi fondatore di Intel), che apr la strada ai calcolatori di
t e r z a g e n e r a z i o n e , dopo la generazione delle valvole e quella dei transistor.
La struttura tipica di un calcolatore elettronico assume quindi la forma attuale in base ad almeno due svolte tecnologiche fondamentali, un modello
costruttivo storico riconducibile allo scienziato austriaco J. Von Neumann (a r c h i t e t t u r a d i V o n N e u m a n n ) risalente agli anni 40/50 e
linvenzione del microprocessore da parte del tecnico italiano F . F a g g i n (microprocessore I n t e l 4 0 0 4 ), risalente al 1971.
Dai primi anni 70 le tecnologie che hanno fatto sviluppare i calcolatori elettronici hanno subito una evoluzione costante e prendono il nome di
Architetture hardware, allinterno delle quali il calcolatore elettronico assume le sue caratteristiche di base.
Attraverso lo schema dellarchitettura di Von Neumann vediamo di chiarire i componenti base di un calcolatore elettronico, le loro interazioni e quindi
i principi del funzionamento.
S3Abacus Architetture/Asm .doc - 1684Kb - 08/mar/2011 - 31 / 84

ARCHITETTURA DI VON NEUMANN


TASSONOMIA DI FLYNN
Tra le varie classificazioni che nel tempo sono state formulate circa la fisionomia dei calcolatori, una sopravvissuta con successo, data la sua
semplicit e sinteticit (t a s s o n o m i a d i F l y n n , 1972). Essa si basa su due concetti chiave: sequenze di istruzioni e sequenze di dati, a seconda
che il calcolatore sia in grado di gestire solo una sequenza o pi sequenze nello stesso tempo.
Si hanno quindi le seguenti tipologie di calcolatori, in base alle combinazioni:
S I S D : Single Instruction, Single Data, il modello originale, che equivale alla macchina di Von Neumann.
S I M D : Single Instruction, Multiple Data, modello in cui alcune singole istruzioni possono computare pi sequenze di dati.
M I S D : Multiple Instruction, Single Data, modello senza alcuna implementazione reale
M I M D : Multiple Instruction, Multiple Data, modello in cui pi unit di calcolo agiscono su pi sequenze di dati nello stesso tempo.
In effetti, per capire la classificazione, bisognerebbe considerare un istante di tempo come unit, e quindi verificare se, in quella unit di tempo
congelata, operano una o pi istruzioni su una o pi sequenze di dati.

MACCHINA DI VON NEUMANN


Il modello di Von Neumann (m a c c h i n a d i V o n N e u m a n n ), circa la struttura e le funzioni di un calcolatore, mette in chiaro che il funzionamento
della macchina deve basarsi sul concetto di programma da eseguire, ovvero stabilisce con chiarezza le funzioni tipiche del s o f t w a r e (sw,
programmi, cio sequenze di istruzioni per ottenere risultati) e dellh a r d w a r e (hw, macchina, cio unit che esegue il software e ottiene i risultati).
Questo concetto fu mutuato dagli studi teorici del britannico A . T u r i n g (macchina di Turing).
Per avvicinare la parte software a quella hardware, Von Neumann stabilisce anche che il sistema di codifica dellinformazione da usare deve essere
quello su b a s e b i n a r i a , cio il sw deve essere rappresentato con codice in base due, cosicch per lhardware sia pi immediato decodificare i
programmi, basandosi sulle differenze di potenziale elettrico a due livelli.
Da un punto di vista funzionale, quindi, Von Neumann propone una struttura di tipo modulare, e non compatta come in passato: diverse unit con
compiti specifici devono interagire tra loro in modo sincronizzato tramite un modulo di collegamento.
Quindi il modello di Von Neumann per il calcolatore prevede le seguenti unit funzionali:
P r o c e s s o r e , cio lunit di calcolo che esegue le istruzioni del sw
M e m o r i a , cio il contenitore del software e dei dati
I n p u t / O u t p u t , cio i moduli attraverso i quali fornire sw e dati (Input) o raccogliere i risultati (Output)
B u s , cio lelemento di interconnessione comune delle suddette unit funzionali.

Bisogna ricordare che tale modello sopravvissuto praticamente intatto fino alla realizzazione di moderni calcolatori. Lultimo calcolatore che
implementa il modello di Von Neumann in modo completo lIntel 80486 (1989). In questo caso la macchina di Von Neumann una macchina
puramente S I S D .
In seguito il modello fu aggiornato, ma solo relativamente alla scomposizione dei due flussi di programma e dati, che furono gestiti in modo separato
dal modello successivo denominato A r c h i t e t t u r a H a r v a r d . Inoltre i moderni calcolatori contengono istruzioni e unit di calcolo che fanno
pendere il modello SISD di Von neumann verso modelli misti SISD-SIMD, come si vedr pi oltre.

MEMORIA
La Memoria, detta M e m o r i a P r i n c i p a l e , un contenitore di celle ordinato. Nelle celle di memoria vengono immesse o lette le istruzioni del
software e i dati di Input e di Output. Ogni cella ampia un b y t e e ogni cella possiede un i n d i r i z z o (address) proprio.
Gli indirizzi delle celle partono da zero e lindirizzo dellultima cella coincide con il numero totale di celle (+1, dato che gli indirizzi partono da zero),
ed definito s p a z i o d e g l i i n d i r i z z i o s p a z i o d i i n d i r i z z a m e n t o .
Lampiezza dello spazio di indirizzamento fisico di una Memoria principale determinato dallampiezza del Bus Indirizzi (cfr. Bus).
Il valore nella cella di Memoria viene conservato fintanto che la Memoria alimentata da corrente, cosicch la Memoria un tipo di m e m o r i a
v o l a t i l e , cio perde i suoi contenuti tutte le volte che la macchina viene spenta.
S3Abacus Architetture/Asm .doc - 1684Kb - 08/mar/2011 - 32 / 84

La Memoria realizzata in gran parte in tecnologia R a m (Random Access Memory) che, per non perdere il contenuto, deve essere sempre
rinfrescata con un segnale elettrico a frequenza costante per tutto il tempo in cui il sistema alimentato ( r e f r e s h ).
I bit nelle celle di RAM, infatti, sono dei micro condensatori ed per questo che questo tipo di Ram nota anche come D R a m (Dynamic Ram).
I contenuti delle celle di DRam vengono aggiornate continuamente durante il funzionamento del calcolatore (con nuovi programmi e dati). Il
processo di lettura e scrittura delle celle di DRam non immediato ma necessita di un tempo tecnico detto t e m p o d i a c c e s s o .
Il tempo di accesso alla memoria Ram decisamente alto rispetto ai tempi presenti nelle attivit di un calcolatore (es. il tempo dellesecuzione delle
istruzioni nel processore). Questa situazione detta c o l l o d i b o t t i g l i a d i V o n N e u m a n n .

Allinterno della memoria di sistema deve per trovare posto una speciale area che non perde i valori dopo lo spegnimento. Infatti il sistema, per
potersi avviare (fase di B o o t s t r a p ), deve immettere sul Bus le istruzioni iniziali per configurare i dispositivi di base come video e tastiera (fase di
P O S T o Power On Self Test)) e caricare i programmi del Sistema Operativo da una memoria secondaria come ad es., un disco.
Questarea riservata allinterno delo spazio di indirizzamento, pur conservando la struttura tipica di Indirizzo e Cella, ed denominata,
genericamente, B I O S (Basic Input/Output System).

TECNOLOGIE
Per contrastare il ritardo cronico nella gestione della memoria DRam, si pu realizzare la Ram con tecnologia statica S R a m (Static Ram), dove ai
microcondensatori si sostituiscono micro flip-flop. La SRam per molto costosa e occupa troppo spazio a parit di cella, pertanto il suo uso
limitato a speciali memorie di transito - tra Memoria e Processore - denominate memorie C a c h e (cfr. Cache).
Le memorie Dram vengono prodotte in banchi di dimensione fissa e montati sulla piastra madre del calcolatore su schede D I M M (Dual In-line
Memory Module) a due facce. La tecnologia pi diffusa (2008) la cosiddetta D D R 2 S D R a m (Double Data Rate Synchronous Dynamic Ram).

Le regioni di Memoria che contengono il BIOS sono realizzate in R o m (Read Only Memory), cio una tecnologia che consente alle celle di
mantenere il contenuto anche in assenza di alimentazione, cio a sistema spento. Il codice e i programmi contenuti in maniera non volatile nella
memoria centrale sono detti F i r m w a r e (Fw).
Buona parte della Memoria Rom realizzata, in realt, con tecnologia E p r o m o E e p r o m , cio memorie con tecnologie che, pur mantenendo i dati
nelle celle quando manca lalimentazione, possono essere riprogrammate (valori memorizzati in C M O S R a m ), cioe sostituite con nuovi valori
attraverso procedure speciali.
In questo modo le caratteristiche di avvio e alcune caratteristiche funzionali del sistema possono essere modificate e/o aggiornate tramite la
modifica dei parametri durante il Setup del Bios o la sostituzione effettiva di tutto il Bios tramite speciali procedure di configurazione.

BUS
Il Bus lunit di interconnessione tra i moduli del modello di Von Neumann. Esso si presenta come un fascio ordinato di linee, ognuna delle quali
pu assumere il significato di un bit, cio di un valore binario. Si dice che i moduli Processore, memoria e Input/Output si affacciano sul Bus, ovvero
essendovi collegati, possono leggere o modificare i valori presenti sulle linee che lo compogono.

Gran parte dellattivit di un calcolatore elettronico si riduce, infatti, a trasferimenti (di informazione) tra i moduli: trasferimenti che vedono il
Processore come soggetto (M a s t e r ), Memoria e I/O come oggetti (S l a v e ) e il Bus come veicolo: da Processore a Memoria, da Memoria a
Processore, da Processore a I/O e da I/O a Processore (i casi di trasferimento tra I/O e Memoria sono visti come un caso speciale, per ora).
Considerando come soggetto master il Processore, una operazione che trasporta un dato dal Processore alla Memoria (o allI/O) detta operazione
di s c r i t t u r a (Write), mentre se il verso opposto (da Memoria o I/O verso il Processore) loperazione detta di l e t t u r a (Read).
Per gestire i trasferimenti il Bus scomponibile in tre sottoinsiemi ordinati di linee, denominati A d d r e s s B u s (ABus) o Bus Indirizzi, D a t a B u s
(DBus) o Bus dei dati e C o n t r o l B u s (CBus) o Bus di controllo.

In questo modo, se si stabiliscono alcune linee del CBus in modo opportuno, es. prevedendo una linea che specifica la direzione del trasferimento
(Memoria-Processore o I/O-Processore), una che specifica il verso del trasferimento (lettura o scrittura) e una che indica se il trasferimento
completato, il trasferimento di una certa quantit di informazione (sul DBus) pu essere inviato nel posto giusto (allindirizzo sullAbus) in modo
completamente sincronizzato (tramite le linee sul Cbus).
S3Abacus Architetture/Asm .doc - 1684Kb - 08/mar/2011 - 33 / 84

Considerando che il Bus possiede un proprio orologio che ne scadenzia in modo costante le operazioni nel tempo in Mhz ( c l o c k d i B u s ), si
usano le seguenti linee di controllo (sul Cbus) per gestire i trasferimenti: I / O - M e m , R / W , W a i t (la convenzione vuole che la sigla sottolineata
indichi valore di bit a 0). La linea Wait (attesa) indica trasferimento completato (1) o trasferimento in corso (0), situazione che mostra il collo di
bottiglia di Von Neumann: i tempi di accesso alla Memoria sono pi lunghi dei tempi di elaborazione del Processore.

La quantit delle linee dellAbus e del DBus, non necessariamente coincidenti, dipendono dalle caratteristiche specifiche del Processore e,
comunque, sono quasi sempre potenze di due (4, 8, 16, 32, 64 linee, anche se in alcuni Processori troviamo 20, 36 o 80). In generale la dimensione
dellAbus specifica la quantit di memoria raggiungibile dai programmi (spazio di indirizzamento fisico) e si calcola elevando 2 al numero di linee
dellABus. La dimensione del Dbus, invece, rappresenta il grado di parallelismo del Processore, ovvero la massima quantit di dati che in grado di
elaborare in un solo trasferimento di Bus.

ESEMPIO: TRASFERIMENTI SUL BUS


Si voglia indicare lo stato del Bus al completamento del trasferimento del valore 23 alla cella di indirizzo 17 della Memoria, su un Bus con 8 linee di
DBus, 8 linee di Abus e 3 linee di controllo.
Indicare la sequenza dei valori binari delle linee del Bus.

Prima di tutto si trasformano i valori decimali in binario, riempiendo i risultati al byte (cio aggiungendo tanti zeri a sinistra fino a ottenere sequenze
di 8 bit).
(23)D = (10111)B = (00010111)B (valore da trasferire)
(17)D = (10001)B = (00010001)B (indirizzo di Memoria di destinazione)
I/O-Mem = 0 (indica la direzione Processore-Memoria)
R/W = 0 (indica verso di scrittura)
Wait = 1 (indica operazione completata)

In definitiva:

DBus ABus CBus


76543210 76543210 I/O-Mem R/W Wait
00010111 00010001 0 0 1

TECNOLOGIE
Allinterno della scheda madre (motherboard) di un calcolatore abbastanza complicato isolare la sezione del bus di sistema.
In effetti linsieme di circuiti, linee e chip dedicati al bus di sistema viene indicato con il termine complessivo di C h i p S e t , che viene fornito e
montato in base alle specifiche del processore utilizzato.
Il Chipset realizza, tra laltro, il Bus di sistema tramite linterconnessione di due aree distinte normalmente denominate N o r t h B r i d g e , (che si
occupa della connessione Processore-Memoria) e S o u t h B r i d g e (dedicato alle connessioni tra Processore e sezione di I/O).
Le tecnologie con cui viene realizzato il Bus di sistema sul classico PC Intel x-86 si sono evolute dallo standard I S A (Dbus a 8 bit e clock a 8,33
MHz), allo standard E I S A (Dbus a 16 bit e clock a 8,33 MHz), allo standard P C I (Peripheral Component Interconnect, Dbus a 32 bit e clock a 33
MHz).
Nel tempo sono comparsi bus interni dedicati per veicolare i dati della scheda video e del processore, a partire dal V E S A fino al pi recente A G P .
Allo stato attuale (2008) la tecnologia di bus pi diffusa il P C I a 32 bit, 33MHz e 133MBytes/ e il P C I - X (32-64bit, 66MHz, da 528Mbytes/s a
1035 Mbytes/s).
Levoluzione pi recente in termini di tecnologie di Bus il P C I E x p r e s s , per ora utilizzato come sostituto di AGP come bus dedicato per le
schede video. Altri tipi di bus hanno avuto alterne fortune commerciali, tra cui Microchannel, lo SCSI e il PMCIIA dedicato ai dispositivi portatili.

INPUT/OUTPUT
La sezione di Input/Output (I/O) di un calcolatore dedicata allacquisizione dei dati e programmi, e alla rappresentazione degli stessi in varie
forme, dal video alla stampa a valori memorizzati su M e m o r i e S e c o n d a r i e (tutti i tipi di memorie di massa, dal DVD allHard Disk al PenDrive).
Concettualmente la sezione di I/O ancora rappresentabile come un contenitore, del tutto analogo alla Memoria, anche se dotato di uno spazio di
indirizzamento (spazio degli indirizzi di I/O) molto pi ridotto. Ogni dispositivo periferico, di Input o di Output, possiede un proprio range di indirizzi di
I/O riservato (indirizzi di I/O, detti anche r e g i s t r i d i I / O o porte di I/O) allinterno dello spazio di indirizzamento di I/O.
Qualche volta alcuni dispositivi, magari che necessitano di grandi spazi di I/O, usano indirizzi di Memoria invece di indirizzi di I/O. In questo caso si
parla di dispositivi m a p p a t i i n M e m o r i a .
La sezione di I/O dispone tuttavia di almeno unaltra modalit fondamentale per consentire la gestione delle attivit di I/O con le attivit generali del
Bus, ovvero linee di sincronizzazione dedicate denominate linee di I n t e r r u z i o n e . Per gestire i segnali di interruzione, sul CBus sono
implementati normalmente due segnali tipici (I N T R e I N T A ) che segnalano, rispettivamente, la richiesta di una interruzione e il suo
completamento. Con un segnale di interruzione, il dispositivo periferico chiede al Processore di sospendere temporaneamente la sua esecuzione
per eseguire una parte di codice che lo riguarda, sottoforma di routine associata a quella interruzione ( I S R , Interrupt Service Routine). Questo
molto importante per quellI/O denominato a s i n c r o n o , ovvero che pu intervenire senza preavviso e in ogni momento (es. il mouse).
In realt i calcolatori prevedono anche speciali modalit di trasferimento di I/O che evitano di occupare il Bus di sistema e il Processore, veicolando i
valori di I/O direttamente verso (e dalla) Memoria, mediante tecniche denominate D M A (Direct Memory Access) o di B u s M a s t e r i n g . In questi
casi ampie quantit di informazioni vengono spostate sul Bus senza impegnare il Processore.

La circuiteria dedicata ad affacciarsi sul Bus di sistema, a rendere disponibili i propri indirizzi di I/O, a sincronizzarsi con i trasferimenti tramite il
CBus e a condividere le proprie linee dedicate di Interruzione e/o DMA, detta S c h e d a C o n t r o l l e r del dispositivo.
Molti dispositivi di I/O sono i n t e r n i al calcolatore, cio hanno la scheda controller integrata nel ChipSet della scheda madre (es. Tastiera, scheda
di rete e scheda video). Anche speciali elementi di I/O dedicati al controllo dei trasferimenti di I/O sono integrati nel ChipSet, come ad esempio il
dispositivo di controllo delle Interruzioni (Interrupt Controller) e di gestione del DMA (DMA Controller).
Con lintroduzione della tecnologia P C I per il Bus di sistema (che gestisce anche i collegamenti con lI/O tramite il SouthBridge) viene a risolversi
lannosa questione della esatta distribuzione dei registri dedicati di I/O e della gestione dedicata delle linee di sicronizzazione dellI/O (es,. le linee di
interruzione e i canali DMA). Infatti, essendo tutti indirizzi, linee e canali privati e dedicati, essi devono essere ben separati e distribuiti tra le diverse
schede controller installate sul sistema.
S3Abacus Architetture/Asm .doc - 1684Kb - 08/mar/2011 - 34 / 84

Prima del bus PCI, infatti, ogni scheda controller doveva essere configurata a mano (tramite jumper modificabili sulla scheda controller) per
specificarne gli indirizzi di I/O, il n. di interruzione e il canale DMA in modo coerente con eventuali altre schede controller presenti sul sistema, per
evitare conflitti.
Attualmente il bus PCI consente di utilizzare una tecnica denominata P l u g & P l a y per la quale BIOS, Sistema Operativo e FW residente sulla
scheda controller stabiliscono, allavvio del calcolatore (o nel momento dellinstallazione a caldo di un dispositivo), indirizzi, canali e linee
completamente separati per ogni scheda controller presente sul sistema, eliminando la possibilit di conflitti e evitando operazioni di configurazione
manuale da parte dellutente.
In definitiva un trasferimento di I/O avviene, sul Bus, con le stesse modalit di un trasferimento standard, avendo cura di segnalarne correttamente
la direzione sulla linea IO/Mem del CBus.

TECNOLOGIE
Altri elementi di I/O o periferiche, quelli opzionali o comunque gestibili come componenti dallutente, sono detti e s t e r n i e si connettono al Bus
tramite sistemi standard che vengono resi disponibili attraverso appositi connettori.
Tra questi ricordiamo le connessioni dirette al Bus di sistema tramite i cosiddetti S l o t (s l o t P C I o s l o t I S A - E I S A ), sui quali lutente pu
connettere direttamente (ma a calcolatore spento) una scheda controller di I/O (es. una seconda scheda di rete o schede di I/O dedicate).
Praticamente sempre disponibili sono le connessioni I D E - E I D E per Hard Disk (conosciute anche con il nome A T A - A T A 2 ) e/o dispositivi DVD
(che utilizzano lo standard A T A P I su IDE-EIDE).
Le connessioni di questo tipo constano di due connettori IDE-EIDE su piastra madre (primario e secondario) a cui collegare due dispositivi (un
Master e uno Slave selezionabili tramite jumper sulle periferiche) a scelta tra Hard Disk e dispositivi DVD
In alternativa, questi dispositivi possono avvalersi di una pi recente tecnologia di connessione, di tipo S A T A (Serial ATA), per Hard Disk di nuova
generazione collegabili anche a caldo.
Tra gli standard di connessione pi diffusi ricordiamo lo standard U S B , il F i r e w i r e (o IEEE 1394) e lE t h e r n e t 8 0 2 . x .
In ribasso altri standard storici di I/O tipo porte seriali Rs232, parallele Centronics e seriali PS/2, progressivamente implementate tramite standard
pi moderni (tipicamente convertitori USB).
USB e Firewire sono modi di connessione dellI/O molto utilizzati, sia per lampia larghezza di banda (480 Mbit/s per USB 2.0, 400 Mbit/s per
Firewire), sia per la possibilit di installare a caldo i dispositivi che se ne servono. Inoltre forniscono anche una certa quantit di corrente sullo
stesso cavo dati, cos da rendere molti dispositivi del tutto autonomi anche dallalimentazione. In entrambi i casi USB e Firewire consentono
connessioni multiple in catena, tramite Hub nel caso di USB, direttamente in modo passante per Firewire.

PROCESSORE
Un Processore un singolo circuito integrato in grado di effettuare operazioni decisionali, di calcolo o di elaborazione dell'informazione; il
microprocessore principale di un computer viene chiamato processore o C P U (Central Processor Unit).
Il Processore pu essere visto come suddiviso in tre unit funzionali, lU n i t d i C o n t r o l l o (UC), larea dei R e g i s t r i , lA L U (Unit Aritmetico-
Logica).
LUC si affaccia sul Bus, lo arbitra impostando i valori sulle linee Abus, Dbus e CBus, legge il Dbus e il CBus, legge dalla Memoria (e dallI/O) i dati o
li aggiorna in Memoria (o nellI/O) dopo aver compiuto operazioni.
I Registri contengono i dati letti dallUC sul Bus per predisporli allesecuzione delle istruzioni che avverranno nellALU; oppure contengono i risultati
delle operazioni compiute dallALU in attesa di essere passasti allUC e quindi sul Bus.
LALU lunit di esecuzione effettiva del Processore, allinterno della quale si trovano m i c r o p r o g r a m m i cablati direttamente in hardware, scritti
nel cosiddetto m i c r o c o d i c e con relative m i c r o i s t r u z i o n i .

Ogni processore viene progettato con un set di istruzioni specifico denominato I S A (I n s t r u c t i o n S e t A r c h i t e c t u r e o I n s t r u c t i o n S e t ), in


corrispondenza di ognuna delle quali implementato un preciso microprogramma in ALU.
Ogni istruzione dellISA contraddistinta da un numero specifico, denominato O p e r a t i o n C o d e (Op. Code) e ogni istruzione dotata di Op. Code
necessita di un numero preciso e definito di parametri che, assieme allOp.Code, determinano la l u n g h e z z a d e l l i s t r u z i o n e (in byte).
Un registro speciale del Processore, detto P r o g r a m C o u n t e r (PC), si incrementa della lunghezza dellistruzione appena eseguita.

Il Processore tipico quindi agisce secondo una rigida sequenza di passi che si ripetono fino allarresto della macchina:

Fetch: lUC pone sullAbus il valore del registro Program Counter, imposta lettura da Memoria e carica lop.code ivi memorizzato
D e c o d e : lUC, a partire dallOp.Code appena letto, determina la lunghezza dellistruzione, cio la quantit di parametri di cui necessita quindi
attiva una fase intermedia di caricamento degli operandi (O p e r a n d F e t c h ) che si trovano necessariamente e in modo ordinato agli
indirizzi adiacenti a quello dellOp.Code. Gli operandi caricati andranno a depositarsi nei Registri.
E x e c u t e : viene avviato il microprogramma relativo allOp.Code attuale, che usa i propri parametri correttamente memorizzati nei registri. La
frequenza in base alla quale vengono eseguiti i microprogrammi regolata dal c l o c k d i C P U (frequenza del Microprocessore).
Store: al termine della fase di Execute gli eventuali risultati, posti nei Registri, vengono scritti sul Bus dallUC, o verso la Memoria, o verso lI/O.

Il ciclo del Processore qui descritto termina, in effetti, consultando il segnale INTR per capire se il controller di una periferica ha richiesto una
interruzione, ovvero la sospensione temporanea dellesecuzione per servire il codice associato alla interruzione pendente.

Ogni singola istruzione dellISA di un Processore contraddistinta da un proprio Op.Code, una determinata lunghezza (in base al numero di
operandi che utilizza) e un preciso numero di cicli di Bus per il suo completamento (compresi tra il Fetch, il Decode e lo Store). Il tempo di effettiva
S3Abacus Architetture/Asm .doc - 1684Kb - 08/mar/2011 - 35 / 84

esecuzione del microprogramma influisce relativamente sulla durata dellistruzione, essendo il clock di CPU di almeno un ordine di grandezza
superiore al clock di Bus.
Questa considerazione riassume il cosiddetto collo di bottiglia dellarchitetura CISC (cfr. Cisc, Risc, Crisc), causato da una fase di Decode molto
lunga e onerosa a causa della quantit di istruzioni dellISA e della loro complessit e variet in termini di numero di operandi.
Ovviamente lo schema semplificato. Ad esempio un microprocessore reale contiene, oltre allALU, una F P U (Float Point Unit) per i calcoli in
virgola mobile e varie unit di calcolo per istruzioni complesse (es. per calcoli vettoriali), ma il modello di riferimento rimane piuttosto simile.

CISC, RISC, CRISC


Il modello di processore appena descritto contiene microprogrammi e microcodice, cio si dice che un microprocessore a interprete. In altre
parole, ogni istruzione dellISA deve essere decodificata (Decode), quindi dotata degli operandi che richiede (Operand Fetch) e, infine, avviata alla
fase di esecuzione (Execute) che richiede lavvio di uno specifico microprogramma. Tutto questo significa che ogni singola istruzione di unISA del
genere ha un d a t a p a t h a pi cicli. Il data path il percorso dei dati allinterno del Processore, attraverso lattuale istruzione, e i suoi cicli sono
scanditi dal clock della CPU.
Questi tipi di ISA sono denominate C I S C (Complex Instruction Set Code). Le architetture CISC possiedono quindi un set di istruzioni molto ampio,
istruzioni di grandezza variabile e molto specifiche con corrispondente fase di Decode complessa, un data path a pi passi. Si tratta di architetture
che facilitano la portabilit del sw, dato che linsieme dei microprogrammi (o interprete del processore) pu essere trasportato su processori pi
recenti, e quindi sono processori adatti per essere programmati anche in A s s e m b l y (cfr. Assembly x-86)
Al contrario, una architettura R I S C (Reducted Instruction Set Code), possiede un data path a singolo passo. Il set di istruzioni di una architettura
RISC limitato, contiene istruzioni di lunghezza costante (con un numero di operandi fisso), con fase di Decode breve e senza microprogrammi da
eseguire nel processore: ogni istruzione eseguita direttamente in hardware con pochi cicli di clock. In questo modo una elaborazione RISC appare
nettamente pi veloce (almeno di un ordine 10). In sostanza una istruzione CISC - con molti passi nel data path - equivale a numerose istruzioni
RISC con data path singolo. Per questo i programmi per ISA RISC sono molto pi lunghi di un analogo programma per ISA CISC. Tutto ci implica
maggiori difficolt per la portabilit del software e maggiore complessit dei compilatori. I calcolatori RISC non sono, infatti, programmabili in
Assembler, causa la mancanza di istruzioni ISA di alto livello.
Nessuna delle due architetture ideale.
Piuttosto la tendenza attuale limplementazione di processori su base CISC - come descrive il modello di Von Neumann, dotati di sottosistemi
interni basati su RISC, soprattutto dedicati alla computazione delle istruzioni semplici (e pi comuni) dellISA adottata. In questo caso si parla di
architetture C R I S C (Complex-Reducted Instruction Set Code).

Il modello SISD/CISC dellarchitettura di Von Neumann si scontra con un paio di problemi che ne limitano, strutturalmente, la performance.
Una singola istruzione su singolo dato eseguita nellunit di tempo un limite oramai inaccettabile. Molte delle soluzioni per incrementare le
prestazioni di un calcolatore tendono a parallelizzare lesecuzione.
Questo il limite di una architettura SISD.
Cos come il cronico ritardo con cui si accede alla Memoria (clock del Bus, sullordine dei MHz), rispetto alla velocit di esecuzione del Processore
(clock della CPU, sullordine dei GHz), penalizza enormemente il modello CISC con una fase di Decode troppo lenta e complessa. Molte delle
soluzioni per incrementare le prestazioni di un calcolatore tendono a fornire istruzioni e operandi dalla Memoria alla stessa velocit che impiega il
Processore per eseguirle.
Questo il limite di una architettura CISC.

CACHE
Un modo ingegnoso per diminuire gli accessi al Bus e alla Memoria, e quindi di superare i limiti di una architettura CISC, quello di dotare il
calcolatore di una memoria tampone (C a c h e M e m o r y ) tra il Processore e il Bus.
Man mano che il Processore legge dalla Memoria, ad un determinato indirizzo, molte locazioni di Memoria con indirizzi prossimi a quello, vengono
spostati nella memoria cache (nello stesso tempo di Bus). Questi gruppi di valori che vengono portati nella cache sono detti l i n e e di cache.
Il motivo che, secondo il principio della l o c a l i t s p a z i o - t e m p o r a l e dei programmi, un programma utilizza, entro un breve intervallo di
tempo, solo una piccola parte del suo spazio degli indirizzi, una parte composta da indirizzi numericamente vicini tra di loro. Cosicch la memoria
cache (SRam), che molto pi veloce di una Memoria DRam, pu fornire, nellimmediato futuro (es., la prossima istruzione da eseguire), i valori
senza dover accedere al Bus.
Quindi, ad ogni operazione di lettura (del Processore dalla Memoria), linformazione viene cercata prima di tutto nella cache; se presente ( h i t ),
non necessario accedere al Bus; se non presente (m i s s ) si accede alla Memoria e, oltre allinformazione richiesta, si carica una nuova linea in
cache, sovrascrivendo la linea di cache meno usata di recente.
Nei calcolatori sono montate almeno tre tipi di cache (livelli): Livello 1, allinterno del processore, Livello 2, collegato al Processore, Livello 3 sulla
piastra madre.

PREFETCH, PIPELINE, SUPERSCALARIT


Un modo per aumentare il parallelismo desecuzione, e quindi di superare i limiti di una architettura SISD, fu quello di caricare nel Processore pi
istruzioni oltre a quella richiesta. Fin dagli esordi, ad esempio, i Processori erano dotati di una c o d a d i P r e f e t c h , ovvero di un buffer interno in
cui il Processore memorizzava i successivi 6 o 8 byte consecutivi a quello appena letto dalla Memoria. In questo modo, con un solo accesso alla
Memoria, si aveva a disposizione una serie di valori che potevano essere usati successivamente (come istruzioni o operandi) senza dover accedere
di nuovo al Bus.
Ben presto, alla coda di Prefetch, fu affiancato un sistema a P i p e l i n e che ha lo scopo di una catena di montaggio: invece di eseguire una
istruzione completamente e, solo al termine, la successiva, si puo avviare la successiva subito dopo che la precedente stata inserita nel data
path. Per esempio, basta che la prima istruzione si trovi in fase di Decode, e la successiva pu essere posta in stato di Fetch. Cos come in una
catena di montaggio, un nuovo pezzo pu essere lavorato anche se il precedente non stato completato: basta che le fasi (dette anche S t a d i
della pipeline) non si sovrappongano. Cos, una Pipeline a 5 stadi trasporta cinque istruzioni in catena di montaggio.
La Pipeline sopperisce cos alle attese di CPU veloci nei confronti di Memorie lente (cfr. collo di bottiglia di Von Neumann in Macchina di Von
Neumann)

Una volta dotato di Pipeline, in un Processore si notato che lo stadio di esecuzione il pi lento: lo stadio precedente fornisce pi valori di quanto
lo stadio di esecuzione, implementato nellALU, pu elaborare. Ecco allora che sui Processori sono montate pi ALU in modo da servire
velocemente ogni istruzione che arriva allo stadio di Execute. In questo caso il Processore detto S u p e r s c a l a r e .
In questo modo possibile dotare i Processori anche di due o quattro pipeline differenti.
S3Abacus Architetture/Asm .doc - 1684Kb - 08/mar/2011 - 36 / 84

Tutte queste metodologie, per, vengono vanificate da due ovvie situazioni:

a. Istruzioni di salto
b. Dipendenza dei dati tra le istruzioni

Nel primo caso la pipeline viene del tutto persa se listruzione corrente un salto ( b r a n c h ) distante dallistruzione successiva che attualmente in
pipeline. In questo caso viene persa anche la cache.
Nel secondo caso una pipeline deve essere interrotta se listruzione successiva necessita, come operando, del risultato finale dellistruzione
precedente. Es. Istruzione1: A=B+C; Istruzione 2: D=A+1. La pipeline che sta servendo lIstruzione 2 deve interrompersi allo stadio di Operand
Fetch, dato che A non disponibile se non quando lIstruzione 1 non del tutto terminata.

ESECUZIONE PREDICATIVA E SPECULATIVA


Le s e c u z i o n e p r e d i c a t i v a , implementata in moduli del Processore denominati u n i t d i p r e v i s i o n e d e i s a l t i (Dynamic Branch
Prediction), cerca di prevenire la perdita delle pipeline a causa delle istruzioni di salto. In questo caso le unit cercano, con vari algoritmi che usano
tabelle simili a memorie cache, di capire se una istruzione di salto avverr o meno (cosa del tutto non deterministica ma solo statistica o storica,
dato che il fatto avviene solo a runtime). Ad esempio, alcuni criteri considerano sempre presi (t a k e n ) i salti allindietro, tipici dei cicli (in un ciclo il
salto avviene molto pi spesso allindietro). Il problema di questa tecnica, che in realt molto efficiente, si ha quando la previsione sbagliata: le
istruzioni eseguite inutilmente devono essere gettate e lo stato della macchina ripristinato.
Lesecuzione predicativa anche nota come e s e c u z i o n e s p e c u l a t i v a , intendendosi quella elaborazione che computa anche codice che
potrebbe non essere mai utilizzato.

ESECUZIONE FUORI ORDINE E VLIW


Con lesecuzione fuori ordine (o u t o f o r d e r e x e c u t i o n ) si cerca di prevenire lo svuotamento delle pipeline a causa di dipendenze tra le
istruzioni. Quando il Processore individua una dipendenza in una pipeline, invece di buttarla e attendere loperando mancante, la salta e prosegue
con istruzioni future che, in teoria, dovrebbero essere eseguite solo DOPO quella interrotta. In questo caso la pipeline viene quasi del tutto
conservata (un solo stadio rimane bloccato, fino allarrivo delloperando mancante) ma, una volta risolta la dipendenza, saranno gi state eseguite
altre istruzioni (quelle che avevamo chiamato istruzioni future), con conseguente risalita delle prestazioni.
Naturalmente le istruzioni future possono essere eseguite solo se non hanno, a loro volta, dipendenze con istruzioni in corso. Non appena le
istruzioni con dipendenze terminano, il Processore continuer lesecuzione in ordine (i n o r d e r e x e c u t i o n ).
La condizione pi critica per questa tecnica si presenta quando il Processore deve essere interrotto a causa di un interrupt; se il Processore si trova
in fase di fuori ordine, lo stato del sistema potrebbe non essere coerente. In questi casi il Processore deve ripristinare lo stato della CPU ritirando in
ordine tutte le fasi fuori ordine.
Gran parte del lavoro delle unit che gestiscono lesecuzione fuori ordine dovuta allindividuazione delle dipendenze nelle istruzioni. La
dipendenza classica e pi complicata (R A W , Read After Write) proprio quella descritta nellesempio precedente (Istruzione1: A=B+C; Istruzione 2:
D=A+1): lIstruzione 2 contiene una dipendenza RAW.
Per poter riordinare il giusto flusso di esecuzione dopo aver saltato e ricalcolato una istruzione con dipendenza, i Processori utilizzano una serie di
registri dappoggio (interni e invisibili al programmatore) su cui memorizzare i calcoli temporanei delle istruzioni fuori ordine. Allatto del
riordinamento, per evitare di spostare i valori dai registri interni a quelli effettivamente usati nel data path, i processori sono in grado di rinominare i
registri interni nei nomi dei registri effettivi, risparmiando il tempo del trasferimento ( r e g i s t e r r e n a m i n g ).

Anche se non esplicitamente, tutte queste innovazioni (pipeline, superscalarit, predicazione, esecuzione fuori ordine) cercano di implementare un
modello di esecuzione parallelo molto studiato nei centri di calcolo, e denominato V L I W (Very Long Instruction Word). In questo modello, oltre alla
parallelizzazione dellesecuzione ottenuta in harwdware, si presuppone che lo stesso codice esecutivo generato dai compilatori sia pre-cucinato per
essere parallelizzato ottimamente dalle CPU.
S3Abacus Architetture/Asm .doc - 1684Kb - 08/mar/2011 - 37 / 84

ARCHITETTURE INTEL

X-86
Con x-86 si intende larchitettura di microprocessori inizialmente sviluppata dallazienda Intel negli anni 70, e che ancora oggi (2008)
predominante sul mercato mondiale. Altre importanti aziende producono calcolatori basati su questa tecnologia, i cui diritti sono stati a suo tempo
venduti, ad esempio AMD.
Il nome x-86 deriva dal primo microprocessore della serie, Intel 8086 (1976), a cui sono seguite numerose versioni via via pi potenti che hanno
mantenuto il suffisso nel nome: 8088 (1979), 80186 (1980), 80286 (1982), 80386 (1986), 80486 (1989).
Sono da considerarsi macchine x-86 anche i modelli successivi all80486, che hanno dovuto rinunciare al nome numerico per limpossibilit di
brevettarlo: Pentium (o P5, 1993), Pentium Pro (o P6, 1995), Pentium II (1997), Pentium III (1999), Pentium 4 (o P7, 2000), Pentium M (2003),
Pentium D (2005), Core 2 Duo (o P8, 2006).
Tutta questa famiglia di microprocessori condividono una qualit comune che ne ha decretato il successo, ma anche la notevole complessit
progettuale: sono tutti r e t r o c o m p a t i b i l i e, in particolare, tutti ancora in grado di eseguire le istruzioni originali dellISA primitiva del progenitore,
lIntel 8086, bench esso fosse una macchina a 16 bit, mentre le ultime citate sono tutte a 32 bit e, in parte, a 64 bit.

Tutti questi modelli sono sostanzialmente macchine CISC/SISD, bench dal Pentium in avanti si sia cercato di aumentare progressivamente il grado
di parallelismo dellesecuzione (cfr. Prefetch, Pipeline, Superscalar, Esecuzione Predicativa e Speculativa, Esecuzione Fuori ordine).

INTEL 8086
L'Intel 8086 (consideriamo lIntel 8088 come del tutto equivalente, anche se il bus dati a 8 bit), un m i c r o p r o c e s s o r e a 1 6 b i t (ampiezza
dei registri e del Dbus) con 2 0 l i n e e s u l l A b u s per un totale di 1Mbyte di spazio di indirizzamento fisico (220 = 1048756 celle). L'unit di
interfaccia con il bus o Unit di Controllo denominata B I U (Bus Interface Unit), e passa le istruzioni all'ALU (detta E U da Execution Unit)
attraverso una coda di prefetch di 6 byte (4 nell8088), implementando una sorta di rudimentale meccanismo di Pipeline.
L'Intel 8086 possiede 1 4 r e g i s t r i da 16 bit, di cui quattro registri per uso generico (A X , B X , C X , D X ), a cui si pu accedere anche come se
fossero otto registri a 8 bit (AH e AL, BH e BL, CH e CL, DH e DL), due registri indice per indirizzare in memoria ( S I , D I ) e due registri dedicati alla
gestione dello stack (B P e S P ).
A questi si aggiungono altri quattro registri detti d i s e g m e n t o (C S , E S , D S e E S ), dedicati specificatamente allindirizzamento della Memoria.
Completano il set di registri lInstruction Pointer I P e il registro PSW (Program Status Word), denominato F l a g r e g i s t e r .
Lo spazio degli indirizzi di I/O si avvale di un indirizzamento a 16 bit, per un totale di 64KByte (2 16 = 65536) registri di Input/Output disponibili.
Completa la sezione di I/O un set di 8 l i n e e d i i n t e r r u z i o n e hardware (poi ampliato a 16) e un canale DMA per dispositivi di I/O con ampio
traffico. La frequenza originale del clock di CPU valeva 4,77 MHz.

Specifiche soluzioni adottate da questo microprocessore sono luso della S e g m e n t a z i o n e d e l l a M e m o r i a e lutilizzo in comune delle sedici
linee del Dbus con altrettante linee dellAbus (M u l t i p l e x i n g B u s ), cosicch necessario un segnale speciale nel CBus (M/IO) che segnali se su
quelle linee presente attualmente un dato o (parte di) un indirizzo. La memorizzazione delle parole di byte in Memoria avviene in modalit l i t t l e
e n d i a n (il byte meno significativo allindirizzo pi basso), modo caratteristico di tutte le macchine Intel.
Le istruzioni dellISA 8086, lunghe da 1 a 4 byte, prevedono spesso luso implicito di alcuni registri, complicando le operazioni di salvataggio
temporaneo e rendendo il processore cronicamente povero di registri disponibili.
La ridotta quantit di registri dell8086 cos come nelle macchine successive fino al Pentium ha designato linstruction Set dell8086 come ISA a
due indirizzi, ovvero come architettura che ha continuamente bisogno di depositare dati temporanei in memoria, invece che su registri
supplementari. I molti accessi alla Memoria, come abbiamo visto, determinano una forte penalizzazione delle prestazioni.

REGISTRI
I quattro registri di uso generale, pur utilizzati frequentemente come registri di memorizzazione temporanea (a 16 o a 8 bit), sono dedicati a precisi
compiti e sono coinvolti implicitamente in numerose istruzioni dellInstruction Set x-86.
AX, o registro A c c u m u l a t o r e , predisposto per le istruzioni aritmetiche (somme, sottrazioni, moltiplicazioni e divisioni).
BX, o registro B a s e , lunico dei registri di uso generale che pu specificare un indirizzo di memoria (gli altri sono DI, SI e BP)
CX, o registro C o n t a t o r e , utilizzato implicitamente nelle istruzioni di conteggio dei cicli o di operazioni che esigono una numerazione.
DX, o registro di I / O lunico registro dell8086 che consente di indirizzare le porte di I/O. Usato anche in moltiplicazioni e divisioni.

I due registri indice, pur utilizzabili come registri di memorizzazione temporanea (ma solo a 16 bit), sono usati implicitamente nelle istruzioni
dedicate alla manipolazione di array di caratteri (stringhe).
SI, o registro I n d i c e S o r g e n t e , specifica lindirizzo da cui leggere larray
DI, o registro I n d i c e D e s t i n a z i o n e , specifica lindirizzo in cui scrivere larray.

I due registri dedicati allo stack sono in grado di indirizzare in memoria, anche se non liberamente.
BP, o B a s e P o i n t e r , contiene lindirizzo di partenza della pila di stack, per poter gestire il passaggio dei parametri delle procedure
SP, o S t a c k p o i n t e r , contiene sempre lindirizzo di memoria dellultimo elemento sullo stack.

Infine, i due registri IP e Flag, sono registri non modificabili esplicitamente dato che il Processore li mantiene aggiornati automaticamente.
IP, o I n s t r u c t i o n P o i n t e r , contiene la parte meno significativa dellindirizzo della prossima istruzione da eseguire. Il programmatore non lo
modifica mai.
Flag, o r e g i s t r o d e i F l a g s , lunico registro intepretato a singolo bit, ove ogni bit ha un significato differente e concorre a descrivere lo stato
attuale del Processore dopo lesecuzione dellultima istruzione.

INDIRIZZAMENTO
Ai dieci registri precedenti nellIntel 8086 bisogna aggiungere 4 registri di segmento (CS, DS, ES, SS) che hanno sempre il compito di contenere i
16 bit pi significativi di un qualsiasi indirizzo di Memoria. Infatti lAbus a 20 linee, mentre i registri solo a 16 bit, per mantenere la compatibilit con
S3Abacus Architetture/Asm .doc - 1684Kb - 08/mar/2011 - 38 / 84

un modello di microprocessore precedente, lIntel 8080. Cosicch un solo registro insufficiente per rappresentare un indirizzo completo, ne
servono due, accoppiati, per formare un cosiddetto I n d i r i z z o S e g m e n t a t o .
Lindirizzo segmentato quindi formato da due parti, e si indica con le notazioni (Seg:Spz) o (Seg:Ofs), ove la parte pi significativa (Seg)
detta parte S e g m e n t o dellindirizzo, mentre la parte meno significativa (Spz o Ofs) detta parte S p i a z z a m e n t o (o O f f s e t ) dellindirizzo.

La regola per ottenere un i n d i r i z z o L i n e a r e (F l a t , cio la sequenza di 20 bit da collocare sullAbus) da un indirizzo segmentato, la seguente:

Indirizzo Lineare = Seg * 10h + Spz

Si deve tenere presente che moltiplicare per 10h un numero esadecimale significa solo aggiungere uno zero (esadecimale) a destra, cosicch un
indirizzo segmentato A100h:023Dh si trasforma in lineare velocemente:

Indirizzo Lineare = A100h * 10h + 23Dh = A1000h + 23Dh = A123Dh (= 660029d)

Si noti che un qualsisi indirizzo lineare pu essere rappresentato da pi coppie di indirizzi segmentati, dato che non tutti i 32 bit dellindirizzo
segmentato sono utilizzati.
Ad esempio i due indirizzi segmentati A100h:023Dh e A110h:013Dh rappresentano lo stesso indirizzo (lineare) A123Dh.
Inoltre, molti indirizzi segmentati sono illeciti, cio rappresentano valori superiori allindirizzo lineare massimo (FFFFFh = 220-1 = 1048575d).
Ad esempio F31Ah:E100h, che risulta essere lindirizzo lineare 1012A0h (> FFFFFh, cio 1012A0h = 1053344d > 1048575d)

I registri di segmento sono spesso impliciti, ovvero, stabiliti gli accoppiamenti di default con i registri di indirizzamento standard, non necessario
indicarli espressamente nelle istruzioni dellx-86.
CS, o C o d e S e g m e n t , contiene sempre la parte pi significativa del Program Counter, ed associato a IP (CS:IP = Program Counter dellx-86)
DS, o D a t a S e g m e n t , contiene sempre la parte pi significativa della memoria dei dati. E associato a BX, SI, DI
ES, o E x t r a S e g m e n t , contiene sempre la parte pi significativa di una seconda memoria dati. E associato a BX, SI, DI
SS, o S t a c k S e g m e n t , contiene sempre la parte pi significativa della memoria in cui allocato lo Stack. E associato a BP e a SP.

IA-32
Con I A - 3 2 (Intel Architecture 32 bit) si indica il modello di architettura e lInstruction Set dei Processori Intel a partire dal 1986, anno di
commercializzazione del microprocessore Intel 80386, il primo microprocessore Intel a 32 bit. Questa architettura si mantenuta presente sulle
macchine Intel fino ad oggi (2008), seppur con numerose varianti introdotte per aumentare le prestazioni.
La terminologia IA-32 si contrappone allIA-64 (cfr. IA-64), larchitettura a 64 bit che dovrebbe modificare radicalmente la struttura dei calcolatori
Intel introducendo in modo nativo il calcolo parallelo e abbandonando il modello CISC/SISD originale dellIA-32.
In realt anche lIA-32, nelle sue evoluzioni, si sempre pi avvicinata ad un modello SIMD, gi a partire dallo stesso 80386, che fu il primo
microprocessore Intel a montare regolarmente una F P U (Floating Point Unit, coprocessore matematico), un parziale ma effettivo elemento SIMD.
Successivamente lIA-32 si arricchisce di vere e proprie istruzioni SIMD denominate M M X (MultiMedia eXtension, 1996) e S S E (Streaming SIMD
Extensions, 2000)
E con lintroduzione dellIA-32 nello specifico con l80386, che Intel perde il monopolio dellarchitettura x-86 (anche se il primo 8086 fu clonato su
licenza da NEC gi nei primi anni 80) a favore, dapprima, del produttore statunitense A M D (1991).
Naturalmente tutte le macchine con architettura IA-32 sono ancora compatibili con larchitettura x-86 a 16 bit dei modelli precedenti allIntel 80386.

Le specifiche caratteristiche dellIA-32 rispetto alla classica x-86 a 16 bit si hanno soprattutto nel nuovo spazio di indirizzamento fisico a 32bit per un
totale di 4 G b y t e di locazioni (232 = 4294967296) e la gestione completa di un modello di m e m o r i a v i r t u a l e e p r o t e t t a .
La gestione della memoria virtuale, infatti, consente a pi programmi contemporaneamente di usare tutto lo spazio di indirizzamento a prescindere
da quanta memoria fisica si effettivamente installata. Ci significa la possibilit di far funzionare i programmi in m u l t i t a s k i n g (cio pi
programmi contemporaneamente), potendo usare uno spazio lineare (e non pi segmentato) molto ampio.
La gestione della memoria protetta, infine, garantisce che i programmi non interferiscano tra di loro n con il Sistema Operativo. La protezione della
memoria e dellI/O, quindi, garantisce anche che i dispositivi non possano essere gestiti con codice errato, tramite livelli di esecuzione detti
p r i v i l e g i . Tutto ci ha reso sostanzialmente pi stabile lesecuzione delle applicazioni, superando lannoso problema dei frequenti blocchi di
sistema sulle macchine x-86.
Per questi motivi lIA-32 pu essere avviata o usata dai programmi in tre modalit di microprocessore differenti: m o d a l i t p r o t e t t a (la pi
evoluta, con indirizzamento lineare), m o d a l i t r e a l e (come un 8086 segmentato), m o d a l i t v i r t u a l e 8 0 8 6 (emulazione 8086 segmentata,
ma con protezione).
In altri termini i programmi possono essere eseguiti, anche contemporaneamente, in modalit protetta o virtuale 8086. In questo modo il blocco di
un programma non arresta il sistema. Se invece il processore viene avviato in modalit reale, esso si comporta solamente ed esattamente come un
grosso Intel 8086 (se avviene un blocco sul programma, il sistema si arresta) e non pu pi cambiare modalit.

I registri dellIA-32 sono sostanzialmente gli stessi della x-86 a 16, ma tutti a 32 bit. Solo due registri di segmento sono stati aggiunti, per un totale di
16 registri a 32 bit.
Per analogia, ogni nuovo registro eredita il nome del vecchio, ma con un prefisso E (Extended): E A X , E B X , E C X , E D X , E S I , E D I , E S P , E B P ,
EIP,EFlags,ECS, EDS,EES,ESS,EFS,EGS.
Il significato e le funzioni dei registri rimangono immutate, considerando che i 16 bit meno significativi dei registri di uso generale assumono lo
stesso nome della vecchia architettura (AX, BX, CX, DX) e, a loro volta, si scompongono nei soliti 8 registri a 8 bit (AH, AL, BH, BL, CH, CL, DH,
DL).

NETBURST, EM64T
Con N e t b u r s t si indica una tecnologia che mira ad aumentare le prestazioni dei calcolatori agendo sullaumento progressivo della frequenza di
clock del processore (clock di CPU) agendo sulla continua miniaturizzazione dei circuiti. Per questo motivo i processori equipaggiati con questa
tecnologia posseggono ALU che girano a frequenza doppia di quella della CPU. Aumentando la velocit interna alla CPU, si possono implementare
anche pipeline molto pi ampie, aumentando quindi il numero di istruzioni eseguite nellunit di tempo. Netburst ha infatti introdotto pipeline a 20
stadi, contro i dieci dei microprocessori precedenti. Naturalmente il fallimento della pipeline diventa una evenienza critica, per questa tecnologia. Se
la predizione di un salto errata o se le istruzioni contengono molte dipendenze, la pipeline si svuota e le prestazioni crollano. Per prevenire queste
eventualit Netburst ha elevato la complessit dellunit di predizione dei salti (cfr. Esecuzione Predicativa e Speculativa) e aggiunto una cache di
livello 2 in grado di conservare le microistruzioni, cos da non dover accedere alla memoria in caso di ricostruzione della pipeline.
S3Abacus Architetture/Asm .doc - 1684Kb - 08/mar/2011 - 39 / 84

LE M 6 4 T (Extended Memory 64 Technology) una tecnologia che viene utilizzata nei processori IA-32 per poter sfruttare alcuni benefici di calcolo
eseguiti a 64 bit, allinterno di processori a 32 bit.
Tramite una speciale modalit (6 4 b i t M o d e ) in cui pu operare il processore, modalit impostabile solo da programmi appositamente scritti in tal
senso, diviene disponibile un indirizzamento lineare a 64 bit, per uno spazio degli indirizzi a disposizione di tali programmi, di 17.179.869.184 GByte
o 16 ExaByte (264 = 18446744073709551616) e si possono utilizzare 8 nuovi registri a 64 bit che diminuiscono gli accessi alla memoria per
salvataggi temporanei. Naturalmente il processore dotato di EM64T pu operare anche in modo classico IA-32, nella modalit C o m p a t i b i l y
Mode.

MULTICORE
Secondo la strada indicata dalla tecnologia Netburst, si sarebbero dovute ottenere frequenze al limite dei 10GHz. Tecnologicamente, per, tali
frequenze non sono state raggiunte n sembra lo saranno a breve; per ora (2008) le frequenze di clock massime non hanno raggiunto la met di
quella previsione. A frequenze cos alte, infatti si crea una enorme instabilit sui chip e la potenza richiesta pone seri problemi di dissipazione del
calore allinterno dei circuiti.
Lorientamento attuale, denominato M u l t i C o r e , si basa sulla progressiva implementazione di calcolo parallelo, ottenuto inizialmente progettando
Processori con due (o pi) unit complete di calcolo, ognuna basata su.CPU che operano a frequenze pi basse di una Netburst.
Questo tipo di architettura, al pari dei sistemi semplicemente dual core e, pi generalmente, di tutti i sistemi biprocessore e multiprocessore,
consente di aumentare la potenza di calcolo senza aumentare la frequenza di lavoro, a tutto vantaggio del minore calore dissipato. Se con la
tecnologia Netburst il grado di parallelismo raggiunto era di tre istruzioni per ciclo di clock (usando grandi pipeline), un processore multicore arriva a
4 istruzioni per ciclo di clock per ogni core implementato, anche se le frequnze di clock interno sono normalmente inferiori. La tecnologia parallela di
un sistema Multicore detta W i d e D y n a m i c E x e c u t i o n e usa una pipeline con meno stadi (14 invece dei 31 raggiunti dalla Netburst),
risultando meno vulnerabile allo svuotamento della pipeline e operando a frequenze minori di clock con abbassamento della potenza richiesta e del
calore sviluppati.
In teoria un processore MultiCore assume le caratteristiche di una macchina MIMD, dato che i singoli processori operano in modo indipendente,
condividendo solo la c a c h e d i l i v e l l o 2 per evitare di accedere continuamente al Bus.
Per sfruttare i Core multipli per necessario che i programmi siano scritti in modo adeguato, ovvero contengano istruzioni dedicate allesecuzione
parallela, con la granularit del processo o del sottoprocesso (t h r e a d ). Infatti un programma non multithread sar eseguito da un singolo
processore, senza alcun aumento delle prestazioni.
In ogni caso tutti i sistemi operativi mulltiprogrammati (multitasking) godono di maggiore efficienza su un sistema MultiCore dato che i processi sono
distribuiti su pi unit di calcolo (Core) invece di condividerne uno solo.
Il notevole risparmio in potenza e di calore da dissipare - a causa dellabbassamento delle frequenze di clock, rende le tecnologie MultiCore
estrememente idonee per i calcolatori portatili.

IA-64
Con I A - 6 4 (Intel Architecture 64 bit) si intende una famiglia completamente nuova di architettura per microprocessore, contrapposta a IA-32 e, pi
generalmente, radicalmente differente dallarchitettura x-86.
Tale progetto stato affrontato gi da molti anni ma ha da sempre incontrato notevoli resistenze per imporsi sul mercato dato che, per forza di cose,
esso perde completamente la retrocompatibilit con i programmi scritti per lx-86, cio quasi tutti i programmi disponibili sul mercato a tuttoggi
(2008).
Il primo processore IA-64 completamente a 64 bit datato 2001 e conosciuto come Intel I t a n i u m . Nel frattempo lazienda ha continuato a
sviluppare la vecchia tecnologia IA-32 cercando di spremergli ogni possibilit di evoluzione e prestazione fino agli attuali sistemi MultiCore.
I vantaggi di una tecnologia a 64 bit suppliscono agli svantaggi della tecnologia a 32 bit, prima di tutto alla struttura fondamentalmente CISC dellIA-
32, con la presenza di molte istruzioni di lunghezze differenti e formati diversi che rallentano inevitabilmente la fase di Decode.
Inoltre il Set dellIA-32 zeppo di istruzioni che fanno riferimento alla memoria (ISA a due indirizzi) mentre sono pi efficienti le ISA a tre indirizzi (o
ISA load/store), che accedono alla memoria solo per caricare gli operandi e memorizzare i risultati.
Un altro limite strutturale la cronica povert di registri dellIA-32 che costringe i compilatori a spostare in memoria molti risultati temporanei, con
conseguente abbassamento delle prestazioni.
Infine la complessit delle istruzioni dellIA-32 comporta la presenza di molte dipendenze WAR (cfr. Esecuzione Fuori ordine e VLIW), complicando
notevolmente luso delle pipeline e la loro profondita (numerosi stadi). E molti stadi rendono le pipeline vulnerabili ai salti, ottenendo perci un
sistema continuamente in bilico con le prestazioni.
Una architettura a 64 bit, poi, consente uno spazio di indirizzamento di una grandezza veramente notevole (2 64 = 18446744073709551616 celle), in
linea (e forse molto di pi) con lampiezza del software richiesto dai sistemi operativi moderni.

La struttura dellIA-64 quindi quella di una I S A l o a d / s t o r e , con 64 registri a 64 bit. Tutte le istruzioni dellIA-64 hanno lo stesso formato, in
modo da ottenere una architettura fondamentalmente RISC. Tutti i registri sono dotati di un meccanismo di finestra (register window) che riesce a
srotolare efficacemente i cicli (l o o p ), cio a esplicitare un ciclo di istruzioni eseguite pi volte elencandole tutte per esteso, il che in genere porta a
un miglioramento delle prestazioni.
Linnovazione determinante di IA-64 ladozione di E P I C (Explicitly Parallel Instruction Computing), ovvero una tecnica che sposta lanalisi del
flusso delle istruzioni di un programma a livello del compilatore in modo tale che in CPU arrivino sequenze di istruzioni ( f a s c i o b u n d l e ) gi
pronte per una elaborazione parallela. Anche lanalisi della predizione dei salti preconfezionata a livello della compilazione, pertanto un IA-64
ottiene previsioni di salto corrette nel 98% dei casi. Si pu dire che EPIC la implementazione completa e specifica di VLIW gi adottata a suo
tempo su IA-32.
Da notare che le prime versioni di macchine con IA-64 sono a singolo Core, malgrado la presenza di una tecnologia esplicitamente orientata al
calcolo parallelo. Il calcolo parallelo, infatti, si ottiene con la superscalarit e le pipeline ottimizzate da EPIC.

Naturalmente, a causa della sua natura completamente rinnovata e dipendente dalla preanalisi del codice da parte del compilatore, larchitettura IA-
64 deve rinunciare a quasi tutto il software di sistema (Sistemi Operativi) e utente (programmi applicativi) disponibile per IA-32, e questo
rappresenta un notevole impedimento alla sua diffusione.

TABELLA RIASSUNTIVA ARCHITETTURE INTEL (2008)


Clock Clock Stadi
Nome anno architettura PIN Transistor CPU BUS Abus DBus Core pipeline Cache Volt
n. n. MHz MHz linee linee n. n. livelli v
S3Abacus Architetture/Asm .doc - 1684Kb - 08/mar/2011 - 40 / 84

8086 1979 x-86 20 29.000 4 10 20 16 1 - - 5


80286 1982 x-86 68 134.000 12 10 24 16 1 - - 5
80386 1986 IA-32 68 275.000 33 33 32 32 1 - - 5
80486 1989 IA-32 168 1.200.000 133 50 32 32 1 - L1 5
Pentium 1993 IA-32 296 3.100.000 300 66 32 64 1 5 L1 3,3
Pentium Pro 1996 IA-32 387 5.500.000 200 66 36 64 1 10 L1-L2 3,3
Pentium II 1997 IA-32 242 7.500.000 300 100 36 64 1 20 L1-L2 2
Pentium III 1999 IA-32 370 9.500.000 1200 133 36 64 1 20 L1-L2 2
Pentium 4 2000 IA-32 468 42.000.000 3400 400 36 64 1 31 L1-L2-L3 1,5
Itanium 2001 IA-64 610 2.000.000.000 1600 533 64 64 1/2 10 L1-L2-L3 1,4
Pentium D 2005 IA-32 775 125.000.000 3600 400 36 64 2/4 10 L1-L2-L3 1,4
Core 2 Duo 2006 IA-32 775 291.000.000 3000 533 36 64 2 10 L1-L2-L3 1
S3Abacus Architetture/Asm .doc - 1684Kb - 08/mar/2011 - 41 / 84

ASSEMBLY X-86

ISTRUZIONI X-86
Le istruzioni x-86 utilizzabili per creare programmi per questa architettura sono le seguenti (in evidenza le pi comuni):

Codice Op.
Mnemoni Code Cicli Descrizione
co
AAA 37 4 Regolazione ASCII dopo l'addizione (per aritmetica BCD)

AAD D5 0A 19 Regolazione ASCII prima della divisione (per aritmetica BCD)

AAM D4 0A 17 Regolazione ASCII dopo la moltiplicazione (per aritmetica BCD)

AAS 3F 4 Regolazione ASCII dopo la sottrazione (per aritmetica BCD)

ADC * 2-7 Somma con carry.

ADD * 2-7 Somma.

AND * 2-7 Esegue l'AND logico bit a bit fra i due operandi, di cui uno pu essere implicitamente il registro AL/AX/EAX.
63 Regolazione del campo RPL del selettore di segmento. Si usa nei sistemi operativi, per assicurarsi che un programma non chiami una
ARPL 21
subroutine che abbia un privilegio superiore a quello del programma stesso.
62 Controlla che l'operando sia entro determinati limiti. Serve ad evitare di indirizzare per errore zone al di fuori di un array: di solito, per motivi di
BOUND 10
efficienza, si usa soltanto nelle versioni di debug di un programma.
BSF 0F BC * Scansione in avanti dei bit dell'operando.

BSR 0F BD * Scansione all'indietro dei bit dell'operando.

BT * 3-12 Test del bit specificato dell'operando

BTC * 6-13 Test del bit specificato dell'operando e sua negazione

BTR * 6-13 Test del bit specificato dell'operando e sua impostazione a 0

BTS * 6-13 Test del bit specificato dell'operando e sua impostazione a 1

CALL * 7-98+ Chiamata di procedura o subroutine

CBW 98 3 Conversione da byte a word

CDQ 99 2 Conversione da doubleword a quadword

CLC F8 2 Azzeramento del flag di Carry

CLD FC 2 Azzeramento del flag di Direzione

CLI FA 3 Azzeramento del flag di Interrupt

CLTS 0F 06 5 Azzeramento del flag di cambio task (TS) nel registro speciale CR0

CMC F5 2 Negazione del flag di Carry

CMP * 2-6 Confronto fra due operandi


Confronto fra due stringhe di memoria i cui indirizzi relativi sono memorizzati nei registri indice SI (o ESI) e DI (o EDI): entrambi i registri
CMPS* * 10
vengono decrementati di uno. A seconda se si devono considerare byte, word o doubleword sono disponibili le varianti CMPS, CMPSB,
CMPSW e CMPSD. Molto spesso questa istruzione viene usata con prefissi REP* in modo da confrontare automaticamente intere zone di
memoria.
CWD 99 2 Conversione da word a doubleword

CWDE 98 2 Conversione da word a doubleword

DAA 27 4 Regolazione decimale dopo l'addizione (per aritmetica BCD)

DAS 2F 4 Regolazione decimale dopo la sottrazione (per aritmetica BCD)

DEC * 2-6 Decrementa di uno l'operando specificato


S3Abacus Architetture/Asm .doc - 1684Kb - 08/mar/2011 - 42 / 84

Codice Op.
Mnemoni Code Cicli Descrizione
co

DIV * 38-41 Divisione senza segno. DIV (divisore). Se divisore 8bit, il dividendo in AX. In AL il quoziente, in AH il resto.

ENTER * 10- Creazione dello stack frame necessario per le chiamate di procedura dei linguaggi ad alto livello.
Ferma il processore. Dopo un HLT non vengono eseguite nuove istruzioni finch non si verifica un interrupt o un reset: in caso di interrupt, dopo
HLT F4 5
la routine di servizio il processore riprende l'esecuzione dall'istruzione successiva alla HLT. Di solito si usa questa istruzione a fini di
sincronizzazione o di risparmio energetico.
IDIV * 19-43 Divisione con segno.

IMUL * 9-41 Moltiplicazione con segno

IN * 12+ Lettura di un byte o di una word dalla porta di I/O specificata nell'operando.

INC * 2-6 Incrementa l'operando di uno.


* Lettura di un byte o di una word dalla porta di I/O specificata nella stringa specificata dal registro indice DI (o EDI). Si usa spesso con prefissi
INS* 15-29
REP* per leggere automaticamente interi vettori di dati.
INT * 33-119 Interrompe l'esecuzione corrente ed esegue la subroutine di interrupt specificata dall'operando.

INTO CE 59-119 Interrompe l'esecuzione corrente ed esegue la subroutine di interrupt dedicata agli overflow. sinonimo di INT 4.

IRET* CF 22-82 Ritorno da una subroutine di interrupt. Come IRETD

* Salto condizionato. Il salto all'indirizzo specificato viene eseguito solo se determinati flag hanno un determinato valore: altrimenti l'esecuzione
J* 7+
continua normalmente con l'istruzione successiva. Esistono numerosi tipi di salti condizionati: JZ,JE,JNE,JG,JL,JGE,JLE, ecc
* Salto incondizionato. L'esecuzione del programma continua a partire dalla locazione indicata dall'argomento del salto: se l'argomento non
JMP 7-49+
dovesse puntare ad una istruzione valida, viene generata una eccezione e il programma si ferma.
LAHF 9F 2 Copia il registro dei flag nel registro AH
0F 02 Carica il byte dei diritti di accesso nel descrittore di segmento. Questa istruzione serve ad impostare i privilegi di un determinato segmento:
LAR 16
una istruzione privilegiata e viene usata solo dal sistema operativo.
LEA 8D 2 Caricamento dell'offset dell'indirizzo effettivo.
C9 Uscita da una procedura di un linguaggio ad alto livello: l'istruzione simmetrica di ENTER e provvede a distruggere lo stack frame della
LEAVE 4
procedura terminata.
LGDT 0F 11 Caricamento del registro della tabella dei descrittori globali dei segmenti: questa istruzione usata soltanto dai sistemi operativi, un programma
01 /2 utente non ha nessun motivo di usarla.

LIDT 0F 11 Caricamento del registro della tabella degli interrupt. Questa operazione viene fatta una volta per tutte all'avvio dal sistema operativo.
01 /3 Caricamento di un puntatore completo segmento: offset. Le varie forme dell'istruzione (LGS, LFS, LDS, LES, LSS) specificano quale registro di
L*S * 7-25
segmento conterr la parte segmento del puntatore.
LLDT 0F 20 Caricamento del registro della tabella del descrittore locale. Come tutte le istruzioni sui descrittori di segmento, anche questa usata solo dai
00 /2 sistemi operativi.

LMSW 0F 10-13 Caricamento della parola di stato della macchina (Machine Status Word)
01 /6 Caricamento di un operando stringa. L'operando puntato dal registro SI (o ESI) viene caricato in AL/AX/EAX, a seconda di quale versione
LODS* * 5
dell'istruzione viene usata (LODS, LODSB, LODSW, LODSD)
* Salto condizionato in base al valore del registro CX/ECX. Dopo il salto, CX/ECX viene decrementato di uno: quando il registro zero, il salto
LOOP* 11+
non viene pi eseguito.
LSL 0F 03 20-26 Carica il limite del segmento nel relativo descrittore, specificato nell'operando. di esclusivo uso del sistema operativo.

LTR 0F Carica il registro del task con il registro o locazione di memoria specificata dall'operando. Anche questa istruzione privilegiata e usata soltanto
00 /3 dai sistemi operativi.

MOV * 2-4 Copia il secondo operando nel primo.

MOVS* * 7 Copia il valore corrente in una certa posizione di una stringa nella corrispondente posizione della seconda. Si usa spesso con prefissi REP*.

MOVSX 0F BE 3-6 Copia il secondo operando nel primo e ne estende il segno.

MOVZX * 3-6 Copia il secondo operando nel primo e azzera il resto de primo operando.

MUL * 9-41 Moltiplicazione senza segno di AL o AX

NEG * 2-6 Negazione dell'operando in complemento a due

NOP 90 3 Nessuna operazione. Sinonimo di XCHG AX, AX (vedi).

NOT * 2-6 Negazione logica dell'operando

OR * 2-7 Or logico inclusivo di due operandi.

OUT * 10-25 Scrittura di un byte o di una word nella porta di I/O specificata dall'operando.

OUTS* * 8-28 Scrittura di un byte o di una word di una stringa nella porta di I/O specificata dall'operando.

* Caricamento dallo stack di alcuni registri. Il valore del puntatore alla cima dello stack, lo Stack Pointer SP, viene decrementato di tante unit
POP* 5-24
quanti byte sono stati letti.
* Scrittura nello stack di alcuni registri. Il valore del puntatore alla cima dello stack, lo Stack Pointer SP, viene decrementato di tante unit quanti
PUSH* 2-18
byte sono stati scritti.
* Rotazione a sinistra dell'operando con carry: tutti i bit dell'operando vengono spostati di una posizione a sinistra e in quella rimasta libera viene
RCL 9-10
copiato il valore del flag di carry, che assume il valore del bit uscito da destra.
S3Abacus Architetture/Asm .doc - 1684Kb - 08/mar/2011 - 43 / 84

Codice Op.
Mnemoni Code Cicli Descrizione
co
* Rotazione a destra dell'operando con carry: tutti i bit dell'operando vengono spostati di una posizione a destra e in quella rimasta libera viene
RCR 9-10
copiato il valore del flag di carry, che assume il valore del bit uscito da sinistra.
RET * 10-68 Ritorno da una subroutine o da una procedura a basso livello.
* Rotazione a sinistra dell'operando: tutti i bit dell'operando vengono spostati di una posizione a sinistra e quello uscito all'estrema sinistra viene
ROL 3-7
copiato nella posizione liberatasi a destra.
* Rotazione a destra dell'operando: tutti i bit dell'operando vengono spostati di una posizione a destra e quello uscito all'estrema destra viene
ROR 3-7
copiato nella posizione liberatasi a sinistra.
SAHF 9E 3 Scrittura del contenuto di AH nel registro dei flag.
* Spostamento dei bit dell'operando N volte a sinistra: i bit fuoriusciti da sinistra vengono persi. Se nessun bit viene perso, questa operazione
SAL 3-7
equivale ad una moltiplicazione per 2N.
* Spostamento dei bit dell'operando N volte a destra: i bit fuoriusciti da destra vengono persi. Questa operazione equivale ad una divisione per
SAR 3-7
2N senza resto.
SBB * 2-7 Sottrazione intera con riporto.
* Confronto di stringhe. Le posizioni di memoria puntate dai registri SI e DI (o ESI ed EDI) vengono confrontate e i due registri
SCAS* 7
incrementati/decrementati di uno a seconda del valore del flag D. Questa istruzione si usa spesso con prefissi REP*.
* Impostazione del byte in base alla condizione specificata. In modo analogo alle istruzioni J*, se i valori dei flag sono quelli imposti dalla
SET* 4-5
particolare versione di SET* usata, nel byte operando viene scritto il valore 1.
SGDT 0F 9 Memorizzazione della tabella del descrittore globale. Ad esclusivo uso dei sistemi operativi.
01 /0 Spostamento a sinistra dei bit dell'operando: il bit uscito da sinistra perso. Se era zero, l'operazione equivale ad una moltiplicazione per 2.
SHL * 3-7
SHLD * 3-7 Spostamento a sinistra dei bit dell'operando in doppia precisione. Come SHL, ma coinvolge anche un secondo registro, concatenato al primo.

SHR * 3-7 Spostamento a destra dei bit dell'operando: il bit uscito da destra perso. L'operazione equivale ad una divisione per 2 senza resto.

SIDT 0F 9 Memorizzazione della tabella degli interrupt in modalit protetta. Ad esclusivo uso dei sistemi operativi.
01 /1 Spostamento a destra dei bit dell'operando in doppia precisione. Come SHR, ma coinvolge anche un secondo registro, concatenato al primo.
SHRD * 3-7
SLDT 0F 2 Carica il registro della tabella del descrittore locale. Usata soltanto nei sistemi operativi.
00 /0 Memorizzazione della parola di stato della macchina (Program Status Word, detto anche registro Flags)
SMSW 0F 2-3
01 /4 Imposta a uno il flag di Carry
STC F9 2
STD FD 2 Imposta a uno il flag di Direzione

STI FB 3 Imposta a uno il flag di Interrupt


* Memorizza il valore di AL/AX/EAX nella posizione di una stringa puntata da DI (o EDI). Dopodich il valore di (E)DI viene
STOS* 4
incrementato/decrementato a seconda del valore del flag D.
STR 0F 23-27 Memorizza il registro dei task. Utile solo ai sistemi operativi.
00 /1 Sottrazione intera.
SUB * 2-7
* Confronto logico non distruttivo di due operandi. Viene eseguito l'AND logico fra i due, ma il risultato non viene memorizzato: vengono modificati
TEST 2-5
soltanto i flag.
VERR 0F 10-11 Verifica di accesso in lettura di un segmento: se s, il flag Zero viene posto a 1, altrimenti viene azzerato.
00 /4 Verifica di accesso in scrittura di un segmento: se s, il flag Zero viene posto a 1, altrimenti viene azzerato.
VERW 0F 15-16
00 /5 Il processore si ferma finch il segnale esterno BUSY# (proveniente dal coprocessore matematico) non si disattiva: si usa per sincronizzare i
WAIT 9B 6
calcoli del coprocessore con quelli della CPU principale.
XCHG * 3-5 Scambia i valori dei due operandi.
D7 Come XLATB. Trasformazione con tabella di consultazione. Il valore corrente di AL viene sostituito con quello nella cella di memoria della
XLAT 5
tabella puntata da DS:BX + AL stesso.
XOR * 2-7 OR logico esclusivo fra due operandi.

Questa tabella si riferisce, in realt, allInstruction Set dellIntel 80386 dato che sostanzialmente coincide con quella dell8086 e che la maggior parte
dei programmi in Assembler, oggi, si eseguono in ambienti che simulano l80386 (cfr. modalit reale e virtuale 8086 in IA-32).

REGISTRO FLAGS (PSW)


In ogni Instruction Set prima di cominciare a programmare, fondamentale conoscere il registro P S W (Program Status Word) che descrive lo stato
della CPU al termine di ogni singola istruzione eseguita.
Nellx-86 tale registro chiamato F l a g s e il suo contenuto interpretato a livello di singolo bit. Naturalmente si tratta di un registro che non
modificabile esplicitamente dal programmatore (non operando di nessuna istruzione), ma solo implicitamente tramite istruzioni che lo modificano
nel modo voluto dal programmatore. I 16 bit del registro di Flag non sono tutti utilizzati. Le sigle di quelli significativi sono le seguenti:
C P A Z S T I D O , dove ogni flag indica una precisa condizione desunta dal risultato dellultima istruzione eseguita (CPAZSO) oppure una modalit
impostabile dal programmatore (TID):
C, flag di C a r r y , a 1 segnala lavvenuto riporto (carry) o prestito (borrow) di una somma o di una sottrazione tra numeri naturali (senza segno)
P, flag di P a r i t , a 1 segnala che il risultato ha parit pari (cfr. Parit), a 0, parit dispari
A, flag A u s i l i a r i o , come il flag di Carry, ma relativo a un nibble (solo i quattro bit meno significativi degli operandi)
Z, flag di Z e r o , a 1 segnala che il risultato zero. Fondamentale per sapere se due operandi sono uguali (es. tramite una sottrazione)
S, flag di S e g n o , a 1 segnala che il risultato ha segno negativo, nella rappresentazione in complento a due (cfr. Numeri con segno).
T, flag di T r a p , impostato a 1 obbliga il processore a eseguire le istruzioni passando il controllo allutente dopo ogni singola esecuzione (debug)
I, flag di I n t e r r u z i o n e , impostato a 1 abilita le linee di interruzione hw (cfr. Input/Output), impostato a zero le disabilita.
D, flag di D i r e z i o n e , impostato a 1 indica la direzione del trasferimento inverso (da un indirizzo alto a uno basso) nelle istruzioni stringa.
S3Abacus Architetture/Asm .doc - 1684Kb - 08/mar/2011 - 44 / 84

O, flag di O v e r f l o w , come il flag di Carry, ma su numeri interi (con segno)

I Flag T, I e D si impostano a 1 e a 0 con le corrispondenti istruzioni: STT, CLT, STI, CLI, STD, CLD.

SINTASSI E INDIRIZZAMENTI
LISA x-86 una ISA a d u e i n d i r i z z i , ovvero usa una sintassi in cui ogni istruzione possiede al pi due operandi.
Questo implica che una normale operazione aritmetica, ad esempio, deve possedere il terzo operando (il risultato) in modo implicito, cio
predeterminato dallistruzione stessa. Detti Destinazione e Sorgente i due operandi di una istruzione, il primo operando (Destinazione) conterr
anche il risultato dellistruzione.

La sintassi generale di una istruzione x-86 la seguente:


2 indirizzi: Op.Code Destinazione, Sorgente
1 indirizzo: Op.Code Destinazione
0 indirizzi: Op.Code

1. Sorgente e Destinazione possono essere un numero costante ( i m m ), un Registro (r e g ) o una locazione di Memoria ( m e m ), ma mai,
contemporaneamente, due locazioni di Memoria.
2. Una costante (imm) non pu mai essere una Destinazione.
3. Sorgente e Destinazione devono essere c o n c o r d i , ovvero devono avere la stessa dimensione in bit.
4. Per indicare una locazione di Memoria (mem) si pone lindirizzo tra p a r e n t e s i q u a d r e (es. [0] la cella di indirizzo zero)
5. Se la dimensione del trasferimento non deducibile dallistruzione, bisogna specificarla con le parole riservate b y t e p t r , w o r d p t r , ecc
6. I numeri costanti (imm) devono essere prefissati con uno 0 se espressi in esadecimale. Per esprimere in esadecimale o in binario i numeri
costanti, si usano rispettivamente i suffissi h e b .

Sorgenti e Destinazioni delle istruzioni possono essere specificati in determinati modi previsti dallISA x-86, modi comunemente denominati
indirizzamenti.

Per elencare le modalit degli indirizzamenti previsti dallx-86 si usa listruzione di gran lunga pi utilizzata dai programmi, listruzione che attiva un
trasferimento, listruzione M O V , che trasferisce un byte o una word:

Istruzione MOV
Sintassi: MOV dest, src

Scopo: Il contenuto di src (sorgente) viene trasferito in dest (destinazione).

Indirizzamento i m m e d i a t o : MOV reg, imm


Esempi: MOV AL,2 MOV CX,0Ah MOV DL,10101010b
Nota: Loperando imm viene automaticamente convertito nel contenitore Destinazione, cosicch il valore Ah del secondo
caso riempie anche il byte pi significativo di CX con uno zero.

Indirizzamento r e g i s t r o : MOV reg, reg


Esempi: MOV AX, BX MOV AL, BL
Nota: I due registri operandi devono avere la stessa dimensione.

Indirizzamento d i r e t t o : MOV mem, reg MOV reg, mem MOV mem, imm
Esempi: MOV [102], AL MOV CX, [106] MOV byte ptr [200], 3
Nota: Uno dei due operandi deve sempre specificare la dimensione del trasferimento. Nel primo caso vengono spostati 8
bit, nel secondo 16 bit, prelevati dallindirizzo 106 e 107, nel terzo caso va specificata la dimensione del trasferimento.

Indirizzamento i n d i r e t t o : MOV mem, reg MOV reg, mem MOV mem, imm
Esempi: MOV [BX], AL MOV AX, [DI+3] MOV ES:[BX], 23
Nota: Allinterno delle parentesi quadre si possono solo usare registri indice: BX, SI, DI, BP, corrispettivamente associati ai
registri di segmento DS, DS, DS, SS. Nel terzo caso, volendo usare un altro registro di segmento, bisogna
specificarlo espressamente (o v e r r i d e di segmento).

X-86 E MSDOS
Per scrivere programmi in Assembler x-86 necessario decidere su quale Sistema Operativo operare per avere a disposizione tutta la serie di A P I
(Application Program Interface) che consentono di accedere correttamente allhardware di Input/Output della macchina, come ad esempio stampare
caratteri sullo schermo o acquisire valori da tastiera.
Senza le API di un Sistema Operativo a disposizione, la programmazione in Assembly rimane abbastanza frustrante, non potendo fornire dati a run
time n poter visualizzare i risultati delle elaborazioni. Inoltre le API di un Sistema Operativo consentono di usare correttamente e velocemente tutti
gli altri dispositivi di I/O necessari per un programma applicativo standard, a partire dalla gestione dei dischi e relativa gestione dei files.
Storicamente lx-86 stata distribuita con il Sistema Operativo MsDos o equivalente (PcDos e DrDos); inoltre anche i modelli pi recenti che
implementano lIA-32 prevedono lesecuzione di codice x-86 in particolari modalit del processore (modalit Reale e Virtuale86), comunemente
attraverso quelle che, sotto i sistemi Operativi Windows, sono note come S h e l l d i M s D o s (attraverso il comando C m d ).
Ci non esclude il fatto che sia proficua anche la programmazione in Assembly x-86 sotto Sistemi Operativi differenti, come ad esempio Linux
(tramite la s i n t a s s i A T & T ) o Windows-Win32 (denominata W i n A s m ).
S3Abacus Architetture/Asm .doc - 1684Kb - 08/mar/2011 - 45 / 84

MEMORIA
M s D o s stato progettato per lIntel 8086, pertanto vede una memoria a 20 bit, per un totale di 2 20 = 1048576 locazioni di memoria numerate da 0
a 1048575 (o da 00000h a FFFFFh). Per la particolare gestione della memoria utilizzata, gli indirizzi sono spesso rappresentati con la notazione
segmentata (Seg:Ofs). Qualora la parte spiazzamento (Ofs) di un indirizzo segmentato valga zero, esso si dice i n d i r i z z o d i p a r a g r a f o .
MsDos un Sistema Operativo (SO) m o n o p r o g r a m m a t o , o monotask, e m o n o u t e n t e ; pu mandare in esecuzione un solo programma alla
volta.
La Memoria principale suddivisa in tre aree tipiche, la M e m o r i a d i S i s t e m a , la M e m o r i a C o n v e n z i o n a l e , la M e m o r i a R i s e r v a t a .
Nella memoria di Sistema, molto piccola, vengono salvate allavvio alcune strutture dati fondamentali per il SO, come larea dei vettori di Interrupt (o
I D T , Interrupt Descriptor Table).
Nella memoria Convenzionale, la pi ampia, viene conservato il k e r n e l di MsDos e il programma applicativo dellutente.
Nella memoria Riservata viene allocata una porzione di Firmware (B I O S ) e, in generale, viene allocato lI/O mappato in memoria (cfr. Input/Output)
di schede di I/O installabili dallutente.

Lo schema generale il seguente:

Indirizzi (hex) Dimensione Descrizione Nome


(byte) (Kb)
00000-005FF 1536 1,5 Strutture dati e valori riservati a MsDos Memoria di Sistema
00600-9FFFF 653823 640 IO.SYS, MSDOS.SYS e COMMAND.COM
Memoria Convenzionale
Programmi Applicativi
A0000-FFFFF 393215 384 ROM BIOS
Memoria Riservata
ROM despansione di schede di I/O

BOOT
Ogni Sistema Operativo deve avviarsi contando sul software scritto allinterno del calcolatore (FirmWare su B i o s ) e sul software scritto nel settore
di avvio di un dispositivo avviabile (es. un hard disk, o in generale un dispositivo di memoria secondaria avviabile) nel cosiddetto B o o t S e c t o r .
Tutta la fase di avvio di un calcolatore denominata B o o t s t r a p (o Boot), e la prima parte dellavvio indipendente dal Sistema Operativo - cio
identica per ogni Sistema Operativo installabile sulla macchina.
Questa fase, denominata in breve P O S T (Power On Self Test) a carico del FirmWare scritto dalla casa costruttrice nel Bios come si nota dalla
classica schermata di avvio che ne riporta il logo. Le routine scritte nel Bios sono scritte in puro linguaggio Assembly, non essendo ancora
disponibile alcun supporto per programmi ad alto livello.
Quando la fase di POST termina, essa individua un dispositivo avviabile secondo lordine che memorizzato nella EEPROM del Bios, e cede, alla
cieca, il controllo al Boot Sector del dispostivo.
Il codice nel Boot Sector ancora scritto in puro linguaggio Assembly, e usa qualche sottoprogramma messo a disposizione dal Bios per cominciare
a caricare i dati del Sistema Operativo da disco fisso (se il dispositivo di Boot era il disco fisso).

Il codice scritto nel Boot Sector carica il primo programma per MsDos, che contenuto nel file I O . S Y S . Questo si avvia e a sua volta carica il
secondo file di MsDos, che si chiama M S D O S . S Y S . Infine, MSDOS.SYS carica il terzo programma fondamentale di MsDos, denominato
COMMAND.COM.
Il processo di avvio prevede che i files di sistema, durante il boot, vadano a consultare due files di testo in cui lutente pu scrivere alcune istruzioni
di configurazione specifiche per il proprio calcolatore. Questi files di configurazione sono CONFIG.SYS e AUTOEXEC.BAT.
CONFIG.SYS contiene parametri di configurazione personalizzata, solo letti da MsDos, mentre AUTOEXEC.BAT contiene una lista di istruzioni
personalizzate da eseguire al termine della fase di avvio del Sistema Operativo.

Si pu dire che il k e r n e l di MsDos (ovvero la parte di SO pi profonda) costituito da IO.SYS e MSDOS.SYS, che interagisce con lhardware e
con i programmi, mentre la s h e l l di MsDos (ovvero la parte di SO pi superficiale) costituita da COMMAND.COM, che interagisce con lutente e
il kernel.
MsDos completato da una serie di programmi residenti su disco che ne estendono la funzionalit (es. format.exe). Questi programmi di sistema
sono anche detti comandi e s t e r n i , per differenziarli da quelli direttamente eseguiti dalla shell, denominati comandi i n t e r n i (es. copy).

FORMATO DEGLI ESEGUIBILI E RILOCAZIONE: EXE E COM


MsDos riconosce come programmi eseguibili due tipi di formati che corrispondono a due tipi di files a loro volta distinti da una estensione
caratteristica: files eseguibili di tipo C O M (con estensione .COM) e files eseguibili di tipo E X E (con estensione .EXE). Inoltre la shell in grado di
eseguire in serie una lista di comandi (interni o esterni) scritti, riga per riga, su un file di testo denominato b a t c h e di estensione B A T (.BAT). Pur
esssendo eseguito, un file .BAT non un file eseguibile.
Gli eseguibili di tipo COM non possono essere pi ampi di 64Kb, mentre gli eseguibili di tipo EXE possono essere di qualsiasi dimensione, purch
inferiore alla dimensione della memoria convenzionale disponibile (tipicamente 640 Kb).

Leseguibile di tipo COM molto semplice: contiene direttamente la lista di istruzioni assembler da eseguire, senza alcuna informazione ulteriore.
Quando la shell deve eseguire un file COM - su ordine dellutente o perch presente in una riga di un file batch, decide a quale indirizzo di Memoria
caricarlo operazione detta di r i l o c a z i o n e s t a t i c a (o caricamento rilocante statico) di MsDos.
Nei primi 256 byte, a partire da quellindirizzo, scrive una serie di informazioni canoniche dette P S P (Program Segment Prefix), quindi legge il
file .COM da disco byte per byte e lo ricopia nello stesso ordine in Memoria, subito dopo il PSP. Terminato il caricamento, MsDos cede il controllo
alla prima istruzione del programma COM in memoria, impostando il Program Counter sullindirizzo iniziale del programma. Quando il programma
terminer, dovr preoccuparsi di riconsegnare il controllo a MsDos, affinche il calcolatore ritorni nella condizione di partenza.

Il caricamento rilocante statico di MsDos per i files COM avviene in questo modo:
a. MsDos cerca una zona di Memoria libera contigua di ampiezza 64Kb (ampiezza denominata s e g m e n t o ), a partire da un indirizzo di
paragrafo nella memoria convenzionale (es. 10A0h:0000h)
b. A partire dallindirizzo di paragrafo cos prescelto, scrive il PSP, allinterno del quale compaiono informazioni utili al programma che sta per
essere caricato, come ad esempio il suo nome e i gli eventuali parametri su linea di comando che lutente pu aver aggiunto (es. in format
c:, c: un parametro su linea di comando)
S3Abacus Architetture/Asm .doc - 1684Kb - 08/mar/2011 - 46 / 84

c. Subito dopo il PSP, il loader ricopia ordinatamente, byte per byte, il contenuto del file COM in Memoria (nessuna rilocazione).
d. Imposta tutti i registri di segmento al valore della parte segmento (seg) dellindirizzo di paragrafo prescelto (nel nostro caso 10A0h), il
registro SP a FFFFh, il registro IP a 0100h e i rimanenti registri a 0. Limpostazione del registro IP a 0100h coincide con limpostazione del
Program Counter (nel nostro caso CS:IP = 10A0h:0100h), quindi lesecuzione viene di fatto ceduta al programma.

Si deve ricordare che loperazione di caricamento di un programma in memoria, e sua effettiva esecuzione, viene fatta dal cosiddetto l o a d e r del
Sistema Operativo; nel nostro caso il loader di MsDos risiede allinterno di COMMAND.COM.
Una volta in esecuzione, il programma prende il nome di p r o c e s s o (mentre programma il nome delle istruzioni contenute nel file).
Il valore costante 0100h impostato su IP, coincide con la dimensione del PSP (100h = 256), esattamente cos da indicare sempre ed esattamente
lindirizzo di memoria della prima istruzione del programma caricato.
La ragione dellimpostazione al valore costante FFFFh del registro SP la si vedr quando si studier lo s t a c k .

I files eseguibili di tipo EXE vengono caricati in modo sostanzialmente differente, dato che la loro ampiezza pu superare il limite del segmento
(limite di 64Kb, cio la dimensione ottenibile usando i 16 bit di un registro x-86).
E necessario che ogni file eseguibile contenga, oltre al proprio codice eseguibile, anche una serie di informazioni supplementari che serviranno al
loader di MsDos per poterlo caricare correttamente in memoria. In questo caso si parla ancora di rilocazione statica, ma anche di c a r i c a m e n t o
rilocante dinamico.
Le informazioni supplementari contenute in un file EXE si dicono h e a d e r d e l f i l e E X E , cio intestazione del file.
Esse sono ampie almeno 512 byte, cosicch un file EXE sempre almeno ampio 514 byte (due byte servono comunque per listruzione di
terminazione INT 21h). Lheader di un file EXE inizia sempre con due byte costanti, che sono i primi due byte di qualsiasi file EXE: MZ (le iniziali del
nome di un progettista di MsDos). Nellheader del file EXE sono memorizzate in un formato specifico e a cura dei linker dei compilatori, tutte le
informazioni necessarie al loader di MsDos per caricare il programma in memoria. Queste informazioni riguardano ad esempio la quantit di blocchi
da 64Kb (segmenti) di cui costituito il programma EXE e le loro effetive dimensioni, e quale, tra questi, il segmento di codice di partenza.

Il caricamento rilocante dinamico di MsDos per i files EXE avviene in questo modo:
a. Il loader di MsDos legge lo header del file EXE e cerca tante zone di Memoria libere (e contigue) di ampiezza 64Kb (segmenti), quanti ne
sono elencati nello header, a partire da indirizzi di paragrafo. Uno di questi sar lindirizzo di paragrafo (e il relativo segmento) di avvio del
programma (es. 10B0h:0000h), mentre un altro sar lindirizzo di paragrafo (e il relativo segmento) dei Dati del programma.
b. A partire dallindirizzo di paragrafo dei Dati, MsDos scrive il PSP del programma EXE.
c. A partire dallindirizzo di paragrafo del segmento di avvio del programma, il loader ricopia il file EXE nei vari segmenti individuati
precedentemente, avendo cura di correggere gli indirizzi che ne sono contenuti in accordo con la posizione dei valori nei segmenti di
memoria libera individuati precedentemente (rilocazione su caricamento).
d. Infine imposta il registro di segmento del codice (CS) al valore (seg) dellindirizzo di avvio del programma (es. 10B0h), il registro di
segmento dei dati (DS) al valore (seg) del segmento del PSP, il registro SP a FFFFh, il registro IP a 0000h e i rimanenti registri a 0.
Limpostazione del registro IP a 0000h coincide con limpostazione del Program Counter (nel nostro caso CS:IP = 10B0h:0000h), quindi
lesecuzione viene di fatto ceduta al programma.

Come evidente, il caricamento di un file EXE pi laborioso e richiede pi tempo. Come si pu notare, IP viene posto inizialmente a 0, a
differenza del valore iniziale che assume nel caso di caricamento di file COM, dato che il PSP, nei files EXE, allocato sullindirizzo di paragrafo dei
dati e non del codice.

API , INTERRUZIONI SW E SERVIZI


Quando MsDos operativo, esso fornisce una interfaccia pubblica a numerose funzioni fondamentali che consentono ai programmatori di accedere
velocemente al video, alla tastiera, ai dischi e a tutti i dispositivi installati dal sistema, evitando di conoscere i dettagli e le complessit dellaccesso
allhardware di I/O.
Queste funzioni, in generale, sono dette A P I (A p p l i c a t i o n P r o g r a m m a b l e I n t e r f a c e ) del Sistema Operativo.
Per MsDos le API di sistema sono scritte in Assembly e invocabili tramite una speciale istruzione dellISA x-86 denominata INT o i n t e r r u z i o n e
s o f w a r e . Per i sistemi operativi Win32 (Windows) e Linux, invece, le API sono scritte in linguaggio C, e sono radicalmente differenti.

Tutte le 256 interruzioni del Sistema Operativo sono numerate da 0 a 255 (0-FFh), e si distinguono in i n t e r r u z i o n i h a r d w a r e (le prime 16, da 0
a Fh), i n t e r r u z i o n i s o f t w a r e d e l B I O S (da 10h a 1Fh), i n t e r r u z i o n i s o f t w a r e d i M s D o s (da 20h a 2Fh). Le successive, da 30h a
3Fh non sono documentate, mentre le rimanenti (da 40h a FFh) sono disponibili per usi definibili dallutente.

Molto spesso le interruzioni forniscono pi di una funzione duso, cosicch necessario selezionare una precisa sottofunzione di una interruzione
specifica, prima di invocarla. Ogni sottofunzione di una interruzione anche detta s e r v i z i o d e l l i n t e r r u z i o n e , ed adeguatamente numerata
in modo che la selezione sia univoca. Il numero di sottofunzione di una interruzione va sempre specificato nel semiregistro A H prima
dellinvocazione dellinterruzione.

Il funzionamento delle interruzioni, che sono in realt dei sottoprogrammi (o subroutine) molto semplice: quando il chiamante invoca linterruzione
di numero X, il sistema calcola lindirizzo assoluto X * 4, si reca in memoria a questo indirizzo (0000h:X * 4), legge i quattro byte consecutivi a
questo indirizzo, imposta il Program Counter CS:IP con il valore di questi 4 byte e cede il controllo, alla cieca, al programma che si trova a
quellindirizzo, programma detto anche routine associata allinterruzione (o I S R , I n t e r r u p t s e r v i c e R o u t i n e ).
Una speciale istruzione, che deve sempre essere presente come ultima istruzione di una ISR, consente di reimpostare il Program Counter
allindirizzo successivo a quello dellinvocazione, cos lesecuzione ritorna automaticamente al chiamante esattamente nel punto in cui era stata
interrotta.
Infatti linizio della memoria di MsDos (memoria di Sistema), contiene la tavola dei vettori di Interruzione ( I D T , I n t e r r u p t D e s c r i p t o r T a b l e ),
cio una serie di 256*4 = 1024 byte che corrispondono agli indirizzi di 256 sottoprogrammi gi pronti in memoria, le routine di interruzione.

La differenza tra interruzioni software e interruzioni hardware riguarda solo il modo in cui vengono invocate: se linterruzione software, il
programmatore che la invoca con listruzione x-86 I N T che ha messo nel codice del suo programma. La chiamata detta s i n c r o n a .
Se linterruzione hardware, la chiamata viene fatta automaticamente dalla CPU - in questo caso si parla di e c c e z i o n e , o dal dispositivo di I/O a
cui quellinterruzione associata. La chiamata detta a s i n c r o n a .

Bisogna dire che non tutte le interruzioni software possiedono una ISR allindirizzo della IDT corrispondente. In alcuni casi presso quellindirizzo
risiedono strutture dati dette T a b e l l e , contenenti dati necessari per la configurazione di determinati dispositivi.

Istruzione INT
S3Abacus Architetture/Asm .doc - 1684Kb - 08/mar/2011 - 47 / 84

Sintassi: INT num

Scopo: Viene avviata linterruzione sw di numero num.

Esempi: INT 20h INT 21h INT 10h

Nota: In molte occasioni prima di usare listruzione INT, deve essere impostato nel registro AH il numero di sottoservizio

In generale, il meccanismo dellinterruzione cos descritto consente di v i r t u a l i z z a r e laccesso allhardware, che la parte pi complessa della
programmazione per qualsiasi ambiente.
La possibilit di modificare la IDT, e quindi le varie ISR associate, consente di caricare in memoria il codice pi aggiornato, o pi efficiente o pi
adeguato per ogni dispositivo di I/O disponibile anche in futuro, lasciando intatte le chiamate dei programmi alle funzioni di gestione. La IDT pu
essere aggiornata sia in fase di caricamento del Sistema Operativo cos come fa MsDos con i files IO.SYS, MSDOS.SYS e COMMAND.COM, sia
caricando al volo codice specifico in moduli speciali detti d r i v e r che in MsDos hanno estensione .SYS, sia operando la modifica della IDT
durante lesecuzione di un programma utente (cio a r u n t i m e , badando per di risistemare le impostazioni al termine dellesecuzione).
In ogni caso le API del Bios (10h-1Fh) sono sempre disponibili nella loro forma originale, garantite dalla immodificabilit del FW su Bios (bench
IO.SYS ne intercetti le chiamate e le normalizzi).

VIDEO E TASTIERA CON LE INTERRUZIONI SW DEL BIOS


Le istruzioni assembler necessarie per accedere alla c o n s o l e (video e tastiera) sono necessarie per poter scrivere un qualsiasi programma
significativo.
Le principali funzioni per accedere al video e alla tastiera sono contenute nel sottoinsieme delle interruzioni software del Bios, in particolare la 10h
(e sue sottofunzioni) per il Video e la 16h (e sue sottofunzioni) per la tastiera.
Le funzioni di accesso alla console fornite dalle interruzioni del Bios sono importanti perch sempre disponibili fin dallavvio del calcolatore, essendo
scritte in FW.
n. INT Descrizione

10h Funzioni per la gestione del Video


11h Determinazioni dotazione del computer
12h Determinazioni della memoria
13h Funzioni per la gestione dei dischi
14h Funzioni per la gestione delle porte seriali
15h Funzioni per la gestione estesa del sistema
16h Funzioni per la gestione della Tastiera
17h Funzioni per la gestione della stampante
18h Caricatore del Basic IBM (obsoleta)
19h Esecuzione del Bootstrap da disco
1Ah Funzioni per la gestione dell'orologio in tempo reale
1Bh Procedura utente per la gestione della tastiera
1Ch Procedura utente per la gestione del timer di Sistema
1Dh Tabella di inizializzazione del video
1Eh Tabella dei parametri dei floppy disk
1Fh Tabella dei caratteri video

INT 10h Sottofunzione 0Eh Stampa di un carattere sullo schermo


MOV AL, 30h ; codice Ascii del carattere da stampare a video (es. 30h lo zero, o 0)
MOV AH, 0Eh ; sottofunzione
INT 10h ; interruzione sw del Bios gestione Video

Il carattere da stampare a schermo va sempre fornito con il suo codice Ascii, pertanto la stampa di singoli numeri decimali (da 0 a 9) deve essere
sempre normalizzata, aggiungendo 48 (o 30h) al numero da stampare.
Si pu indicare il codice Ascii di un qualsiasi carattere indicandolo tra singoli apici, cos come in linguaggio C.

INT 16h Sottofunzione 00h Input di un carattere da tastiera


MOV AH, 00h ; sottofunzione
INT 16h ; interruzione sw del Bios gestione Tastiera
; in AL il codice Ascii del carattere premuto, in AH il codice di scansione

Naturalmente lesecuzione di questa interruzione blocca il flusso del programma in esecuzione, che rimane in attesa di un carattere digitato dalla
tastiera. Non appena un carattere viene premuto, la routine ritorna avendo memorizzato in AL il codice Ascii del carattere premuto.

VIDEO E TASTIERA CON LE INTERRUZIONI SW DI MSDOS


Le stesse funzioni di accesso alla console possono essere richieste tramite linterruzione software di MsDos denominata INT 21h.
Leffetto sostanzilamente identico, anche se bisogna ricordare che tali routines non sono disponibili fin dallavvio del sistema, ma solo allorquando
MsDos completamente caricato. Per i programmi utente questa distinzione non rilevante.

INT 21h Sottofunzione 02h Stampa di un carattere sullo schermo


MOV DL, 30h ; codice Ascii del carattere da stampare a video (es. 30h lo zero, o 0)
S3Abacus Architetture/Asm .doc - 1684Kb - 08/mar/2011 - 48 / 84

MOV AH, 02h ; sottofunzione


INT 21h ; interruzione sw di MsDos

Il carattere da stampare a schermo va sempre fornito con il suo codice Ascii, pertanto la stampa di singoli numeri decimali (da 0 a 9) deve essere
sempre normalizzata, aggiungendo 48 (o 30h) al numero da stampare.
Si pu indicare il codice Ascii di un qualsiasi carattere indicandolo tra singoli apici, cos come in linguaggio C.

INT 21h Sottofunzione 01h Input di un carattere da tastiera


MOV AH, 01h ; sottofunzione
INT 21h ; interruzione sw di MsDos
; in AL il codice Ascii del carattere premuto

Naturalmente lesecuzione di questa interruzione blocca il flusso del programma in esecuzione, che rimane in attesa di un carattere digitato dalla
tastiera. Non appena un carattere viene premuto, la routine ritorna avendo memorizzato in AL il codice Ascii del carattere premuto.
A differenza della sua gemella del Bios, questa funzione mostra a video il carattere premuto.

TERMINARE I PROGRAMMI IN MSDOS


Ogni programma scritto per MsDos in assembler x-86 quando termina deve avvisare il Sistema Operativo tramite una interruzione sw specifica.
In questo modo il SO riacquisisce il controllo del calcolatore correttamente, riconfigurandosi opportunamente per riprendere la sessione di lavoro in
attesa del lancio di un nuovo programma eseguibile da parte dellutente. Tramite lavviso di terminazione, che deve essere sempre lultima
istruzione assembler di ogni programma sia EXE, sia COM, il programma pu avvisare il SO sullo stato della propria terminazione, indicando, ad
esempio, eventuali terminazioni anomale o, pi frequentemente, una terminazione regolare.

INT 20h Te r m i n a z i o n e d i u n p r o g r a m m a C O M
INT 20h ; interruzione sw di MsDos Terminazione programma COM

Linterruzione non necessita di alcun parametro, ma non consente di avvisare MsDos sullo stato di terminazione.

INT 21h Sottofunzione 4Ch Te r m i n a z i o n e d i u n p r o g r a m m a E X E


MOV AL, 00h ; codice di terminazione. Se 0 = terminazione regolare
MOV AH, 4Ch ; sottofunzione
INT 21h ; interruzione sw di MsDos Terminazione programma EXE

Linterruzione di terminazione dei file eseguibili EXE consente di avvisare MsDos sullo stato di terminazione, inseribile nel semiregistro AL. MsDos
pu valutare questo valore usando listruzione ERRORLEVEL, magari in un comando batch.
Se si volesse usare lo stato di terminazione anche per un file eseguibile COM, si pu usare questa interruzione.
S3Abacus Architetture/Asm .doc - 1684Kb - 08/mar/2011 - 49 / 84

ASSEMBLY CON DEBUG


Il modo pi immediato di scrivere programmi in Assembly per x-86 tramite il programma di Sistema Operativo D E B U G . C O M fornito su tutte le
piattaforme Microsoft tramite la Shell di MsDos (invocabile a sua volta usando il comando c m d ).
Con questo programma si scrivono programmi assembly x-86 in formato COM e con indirizzi assoluti numerici, imponendo una rigorosa disciplina
nella scrittura delle istruzioni e mostrando realmente la pratica della programmazione x-86.
Inoltre, il fatto che DEBUG.COM sia sempre disponibile su ogni piattaforma Microsoft x-86 (ovvero da MsDos fino a Win32), ne garantisce la
continuit didattica e la reperibilit immediata per gli studenti.

COMANDI
Debug un ambiente a carattere, con un prompt (il trattino) che attende un comando dellutente.
Tutti i numeri utilizzati con Debug sono sempre in formato esadecimale; per usare una diversa rappresentazione va specificato il formato in coda al
numero.
I comandi dellutente sono singoli caratteri, di facile comprensione. In evidenza, i comandi principali.
Debug non c a s e s e n s i t i v e , ovvero non distingue se il comando scritto in maiuscolo o in minuscolo, comportandosi allo stesso modo in
entrambi i casi..

Nome Sigla Parametri Descrizione

Assembla A [indirizzo] Consente di scrivere il programma


Confronta C intervallo indirizzo
Dump D [intervallo] Esplora la memoria
Immetti E indirizzo [elenco]
Riempi F intervallo elenco
Vai G [=indirizzo] [indirizzi]
Esadecimale H valore1 valore2
Input I Porta
Carica L [indirizzo] [unit] [primosettore] [numero]
Muovi M intervallo indirizzo
Nomina N [nomefile] [elencoargomenti] Assegna il nome al programma
Output O porta byte
Procedi P [=indirizzo] [numero]
Esci Q Esce da Debug
Registro R [registro] Esplora e/o imposta i registri
Cerca S intervallo elenco
Traccia T [=indirizzo] [valore]
Disassembla U [intervallo] Consente di modificare il programma
Scrivi W [indirizzo] [unit] [primosettore] [numero] Salva su disco il programma

ESPLORARE LA MEMORIA
Con il Comando D (D u m p ) Debug consente di esplorare la memoria principale, da 0 a FFFFFh.
Naturalmente la modalit duso e rappresentazione del comando prevede la sintassi con indirizzi segmentati seg:ofs e i numeri rappresentanti gli
indirizzi e i contenuti delle locazioni sono sempre espressi in formato esadecimale.
Al prompt di Debug (il trattino) si pu quindi usare D [intervallo], potendo specificare lindirizzo di partenza da cui analizzare la memoria o un
intervallo:
d Mostra la memoria a partire dallattuale indirizzo contenuto in CS:IP
d 0:0 Mostra la memoria a partire dallindirizzo 0h:0h
d 0:0 100 Mostra la memoria a partire dallindirizzo 0h:0h e per 256 celle (100h = 256)

C:\>debug
-d
0CE2:0100 4D 00 00 5F 00 B4 02 CD-21 FE C2 E2 F8 CD 20 6F M.._....!..... o
0CE2:0110 43 4F 4D 53 50 45 43 3D-43 3A 5C 57 34 00 D1 0C COMSPEC=C:\W4...
0CE2:0120 57 53 5C 53 59 53 54 45-4D 33 32 5C 43 4F 4D 4D WS\SYSTEM32\COMM
0CE2:0130 41 4E 44 2E 43 4F 4D 00-41 4C 4C 55 53 45 52 53 AND.COM.ALLUSERS
0CE2:0140 50 52 4F 46 49 4C 45 3D-43 3A 5C 44 4F 43 55 4D PROFILE=C:\DOCUM
0CE2:0150 45 7E 31 5C 41 4C 4C 55-53 45 7E 31 00 41 50 50 E~1\ALLUSE~1.APP
0CE2:0160 44 41 54 41 3D 43 3A 5C-44 4F 43 55 4D 45 7E 31 DATA=C:\DOCUME~1
0CE2:0170 5C 6F 6C 6C 61 72 69 5C-44 41 54 49 41 50 7E 31 \ollari\DATIAP~1
-d 0:0
0000:0000 68 10 A7 00 8B 01 70 00-16 00 8D 03 8B 01 70 00 h.....p.......p.
0000:0010 8B 01 70 00 B9 06 0C 02-40 07 0C 02 FF 03 0C 02 ..p.....@.......
0000:0020 46 07 0C 02 EC 06 97 05-3A 00 8D 03 54 00 8D 03 F.......:...T...
0000:0030 6E 00 8D 03 88 00 8D 03-A2 00 8D 03 FF 03 0C 02 n...............
0000:0040 A9 08 0C 02 A4 09 0C 02-AA 09 0C 02 5D 04 0C 02 ............]...
0000:0050 B0 09 0C 02 0D 02 DB 02-C4 09 0C 02 8B 05 0C 02 ................
0000:0060 0E 0C 0C 02 14 0C 0C 02-1F 0C 0C 02 AD 06 0C 02 ................
0000:0070 AD 06 0C 02 A4 F0 00 F0-37 05 0C 02 61 90 00 C0 ........7...a...
-q
C:\>
S3Abacus Architetture/Asm .doc - 1684Kb - 08/mar/2011 - 50 / 84

Le videate del comando D sono costituite normalmente da 8 righe cos strutturate:


Sezione di sinistra: mostra l'indirizzo segmentato della prima locazione di memoria riportata nella sezione centrale. Lindirizzo avanza di
10h, dato che su ogni riga sono rappresentate 16 celle di memoria da un byte luna.
Sezione centrale: elenca il contenuto delle 16 locazioni consecutive, a partire da quella indirizzata dalla prima sezione. Per maggior
chiarezza la sequenza dei 16 byte di ciascuna riga divisa in due gruppi da 8 byte divisi da un trattino.
Sezione destra: mostra le stesse 16 celle di memoria in formato Ascii stampabile, cio escludendo i simboli con codici Ascii da 00h a 1Fh
(caratteri di controllo) e da 80h a FFh (caratteri Ascii estesi). Se il carattere non stampabile, viene sostituito da un punto.

Se il comando D viene ripetuto, viene riportata a video la successiva serie di 128 byte, e cos ad oltranza.

Nel secondo blocco dellesempio, i 128 byte riportati sono i 32 indirizzi (128 / 4 = 32) delle prime 32 interruzioni di MsDos. Infatti, alla base della
memoria (cfr. Memoria) si trova la IDT (cfr. API , Interruzioni).

CONSULTARE I REGISTRI
Con il Comando R Debug consente di visualizzare il contenuto e lo stato dei registri x-86, nonch impostarne il valore.
Naturalmente i valori visualizzati sono espressi in esadecimale, mentre il registro dei Flags mostrato attraverso delle sigle convenzionali.
Al prompt di Debug (il trattino) si pu quindi usare R [registro], specificando un registro se si vuole impostarne il valore. Infine, si pu modificare un
singolo bit del registro dei flag con il comando rf, specificando la lista dei nuovi valori (consultare la tabella sottostante):
r Visualizza lo stato dei registri
r CX Imposta il registro CX
r f Imposta uno o pi bit del registro dei Flag

C:\>debug
-r
AX=0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=0CED ES=0CED SS=0CED CS=0CED IP=0100 NV UP EI PL NZ NA PO NC
0CED:0100 27 DAA
-r cx
CX 0000
:12
-r
AX=0000 BX=0000 CX=0012 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=0CED ES=0CED SS=0CED CS=0CED IP=0100 NV UP EI PL NZ NA PO NC
0CED:0100 27 DAA
-rf
NV UP EI PL NZ NA PO NC -pe
-rf
NV UP EI PL NZ NA PE NC -zr po
-r
AX=0000 BX=0000 CX=0012 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=0CED ES=0CED SS=0CED CS=0CED IP=0100 NV UP EI PL ZR NA PO NC
0CED:0100 27 DAA
-q

Si nota che oltre ai registri, il comando R mostra sempre lindirizzo, lop. code e il codice mnemonico dellistruzione puntata dal Program Counter
(CS:IP).
Per quanto riguarda il registro Flags, vengono mostrati solo otto stati di otto bit significativi, con una coppia di caratteri.
La decodifica delle coppie di caratteri la seguente:

Flag Codice Debug bit Descrizione Codice Debug Bit Descrizione


Overflow OV 1 si NV 0 no
Direzione DN 1 decremento UP 0 incremento
Interruzione EI 1 abilitato DI 0 disabilitato
Segno NG 1 negativo PL 0 positivo
Zero ZR 1 si NZ 0 no
Ausiliario AC 1 si NA 0 no
Parit PE 1 pari PO 0 dispari
Carry CY 1 si NC 0 no

SCRIVERE UN PROGRAMMA
La sequenza di passi per scrivere un programma x-86 per Msdos in formato COM con Debug la seguente:

1. Comando A scrivere le istruzioni (e d i t )


2. Terminare la fase di edit con un invio su una riga vuota
3. Comando R impostare la lunghezza del programma
4. Comando N Assegnare il nome al programma
5. Comando W Salvare il programma su disco

Il comando A deve essere specificato con l[indirizzo] impostato a 100 (esadecimale), per rispettare la regola di MsDos circa il PSP (cfr. Formato
degli eseguibili e Rilocazione): la prima istruzione di un programma .COM deve sempre trovarsi allindirizzo 100 (h).
Quindi si digiti A 100 per cominciare la fase di edit.
Ad ogni pressione del tasto Enter (Invio) listruzione confermata e si pu scrivere la successiva.
S3Abacus Architetture/Asm .doc - 1684Kb - 08/mar/2011 - 51 / 84

Debug riporta sempre lindirizzo delle istruzioni digitate.


Per terminare leditazione del programma, bisogna premere Enter su una riga vuota. Debug, a questo punto, mostra il prompt (il trattino).
Controllando lindirizzo dellultima istruzione scritta, sottraendo lindirizzo iniziale (sempre 100h), si calcola facilmente la dimensione, in byte, del
programma scritto. Questa dimensione va specificata nel registro CX tramite il comando R, nella forma R CX. Si digita la dimensione e la si
conferma con Enter. Debug mostra di nuovo il prompt.
Ora si pu assegnare il nome al programma con il comando N. Il nome deve rispettare le regole per gli identificatori di MsDos, ovvero non pu
essere pi lungo di 8 caratteri e non pu contenere caratteri speciali (es. lo spazio), n iniziare con una cifra. Va sempre specificata lestensione
COM. Quindi il comando da utilizzare il seguente (se si sceglie pippo come nome): N PIPPO.COM. Digitato Enter, Debug mostra di nuovo il
prompt (il trattino).
Per salvare il programma su disco nella cartella corrente, basta usare il comando W senza argomenti. Debug risponde con la quantit di byte
scritti su disco e mostra il prompt.
Ora si pu uscire (comando Q) e lanciare il programma dal prompt di MsDos.

IL PROGRAMMA PI CORTO DEL MONDO


Il programma pi corto del mondo per x-86 un programma eseguibile COM che si termina.
Nel dettaglio, tutti i passi da usare con Debug per scrivere questo programma.

C:\> Prompt di MsDos


C:\>debug Lancio del programma Debug da Msdos
-a 100 Edit del programma a partire dallindirizzo 100h
0CE1:0100 int 20 Unica riga di codice: terminazione di file .COM
0CE1:0102 Riga vuota: termine delledit
-r cx Comando per limpostazione della dimensione
CX 0000 Visualizzazione del contenuto attuale del registro CX da parte di Debug
:2 Impostazione della dimensione (100h-102h=2h)
-n corto.com Assegnazione del nome (corto.com)
-w Comando per la scrittura del file di programma su disco
Scrittura di 00002 byte in corso Visualizzazione della quantit di byte scritti da parte di Debug
-q Uscita da debug

C:\>corto Lancio del programma corto.com da MsDos


Nessun output del programma
C:\> Prompt di MsDos

Si noti come, su ogni riga digitata, Debug riporti lindirizzo seg:ofs dellistruzione, calcolando automaticamente lampiezza, in byte, dellistruzione
utilizzata. Il valore della parte segmento dellindirizzo non significativo, mentre la parte offset dellindirizzo lesatta posizione in memoria che
quellistruzione avr nel segmento scelto dal caricatore di MsDos una volta lanciato il programma.

Istruzione NOP
Sintassi: NOP

Scopo: Non fa nulla. Usata per scopi di servizio, p.e. per allineare una sequenza di istruzioni.

Esempi: NOP

Nota: A volte viene inserita NOP se si vuole aumentare di una unit lindirizzo del codice in esecuzione. In altri casi per
rallentare lesecuzione.

Per verificare il programma scritto ed eventualmente modificarlo, si usano i comandi L e U dopo aver specificato il nome del programma da
manipolare. Verr aggiunta una sola istruzione NOP al codice precedente, per mostrare il modo in cui Debug consente di modificare un programma:

C:\> Prompt di MsDos


C:\>debug Lancio del programma Debug da Msdos
-n corto.com Assegnazione del nome (corto.com)
-l Caricamento del file da disco (nella cartella corrente)
-u 100 L2 Disassemblaggio, a partire dallindirizzo 100h, per 2 byte (dimensione del file)
0D5C:0100 CD20 INT 20 Codice disassemblato, con indirizzo (0100h), op. code (CD20h) e codice mnemonico (INT 20)
-a 100 Modifica dellistruzione allindirizzo 100h
0D5C:0100 nop Nuova istruzione (NOP = non fa nulla)
0D5C:0101 int 20 Terminazione di file .COM
0D5C:0103 Riga vuota: termine delledit
-r cx Comando per limpostazione della dimensione
CX 0002 Visualizzazione del contenuto attuale del registro CX da parte di Debug
:3 Impostazione della dimensione (100h-103h=3h)
-w Comando per la scrittura del file di programma su disco
Scrittura di 00003 byte in corso Visualizzazione della quantit di byte scritti da parte di Debug
-q Uscita da debug
C:\> Prompt di MsDos

In alternativa, il file di programma da disassemblare pu essere caricato direttamente citandolo come argomento di Debug:

C:\> Prompt di MsDos


C:\>debug corto.com Lancio del programma Debug da Msdos con caricamento del file corto.com
-u 100 L2
0D5C:0100 CD20 INT 20
-a 100
S3Abacus Architetture/Asm .doc - 1684Kb - 08/mar/2011 - 52 / 84

0D5C:0100 nop
0D5C:0101 int 20
0D5C:0103
-r cx
CX 0002
:3
-w
Scrittura di 00003 byte in corso
-q
C:\>

VIDEO E TASTIERA
Un programma che si limita a richiedere limmissione di un carattere e a stampare la stringa CIAO pu essere scritto nel seguente modo:

C:\> Prompt di MsDos


C:\>debug Lancio del programma Debug da Msdos
-a 100 Edit del programma a partire dallindirizzo 100h
0CED:0100 mov ah,0 Sottofunzione 00h di INT 16h, Input di un carattere da Tastiera
0CED:0102 int 16 Lancio interruzione sw Bios 16h
0CED:0104 mov al,43 Codice Ascii da stampare (43h = C)
0CED:0106 mov ah,0e Sottofunzione 0Eh di INT 10h, Stampa carattere sullo Schermo
0CED:0108 int 10 Lancio interruzione sw Bios 10h
0CED:010A mov al,49 Codice Ascii da stampare (49h = I)
0CED:010C mov ah,0e Sottofunzione 0Eh di INT 10h, Stampa carattere sullo Schermo
0CED:010E int 10 Lancio interruzione sw Bios 10h
0CED:0110 mov al,41 Codice Ascii da stampare (41h = A)
0CED:0112 mov ah,0e Sottofunzione 0Eh di INT 10h, Stampa carattere sullo Schermo
0CED:0114 int 10 Lancio interruzione sw Bios 10h
0CED:0116 mov al,4f Codice Ascii da stampare (4Fh = O)
0CED:0118 mov ah,0e Sottofunzione 0Eh di INT 10h, Stampa carattere sullo Schermo
0CED:011A int 10 Lancio interruzione sw Bios 10h
0CED:011C int 20 Terminazione di file .COM
0CED:011E Riga vuota: termine delledit
-n ciao.com Assegnazione del nome (ciao.com)
-r cx Comando per limpostazione della dimensione
CX 0003 Visualizzazione del contenuto attuale del registro CX da parte di Debug
:1e Impostazione della dimensione (100h-11Eh=1Eh)
-w Comando per la scrittura del file di programma su disco
Scrittura di 0001e byte in corso Visualizzazione della quantit di byte scritti da parte di Debug
-q Uscita da debug
C:\> Prompt di MsDos

STRUTTURE DI CONTROLLO
Le principali strutture di controllo utilizzate in assembler x-86, oltre alla sequenza, sono la c o n d i z i o n e (se-allora) e li t e r a z i o n e (ripeti n volte),
rispettivamente implementate dalle istruzioni di s a l t o c o n d i z i o n a t o (J* indirizzo) e dallistruzione l o o p (LOOP* indirizzo).
Le istruzioni di salto condizionato, che spostano lesecuzione allindirizzo in esse specificato, sono numerose, e vanno utilizzate, di norma, subito
dopo listruzione di confronto C M P , cosicch i flag del registro omonimo risultano impostati in base al rapporto tra i due operandi dellistruzione di
confronto (che in realt coincide con una sottrazione).
In base allo stato dei singoli flag del registro dei Flags, infatti, le varie istruzioni di salto condizionato effettuano il salto allindirizzo specificato o
meno.

Istruzione CMP
Sintassi: CMP op1, op2

Scopo: Viene eseguita la sottrazione op1 - op2 e impostati i Flags opportuni in base allesito della sottrazione.

Esempi: CMP AL,2 CMP AX, BX MOV [BX], AL


Nota: Listruzione viene utilizzata in base alle regole generali della sintassi x-86 (cfr. Sintassi e indirizzamenti). Naturalmente
op1 e op2 rimangono invariati dopo la CMP.

Istruzione J*
Sintassi: J* indirizzo

Scopo: Il flusso dellesecuzione si sposta su indirizzo se la condizione sui flags previste dalla J* sono verificate, altrimenti il
flusso dellesecuzione prosegue regolarmente in sequenza. Questo gruppo di istruzioni sono dette s a l t i
c o n d i z i o n a t i , e si usano spesso dopo listruzione CMP per sfruttarne le modifiche di stato dei flag

Esempi: JE 109h JG 110h JB 112h


Nota: Se lesito del confronto CMP precedente ha impostato il flag di Zero, allora i due operandi di CMP sono uguali e la JE
salta allindirizzo 109h. Analogamente per gli altri due casi, se gli operandi sono, rispettivamente, il primo maggiore
del secondo (numeri con segno), il primo minore del secondo (numeri senza segno).
S3Abacus Architetture/Asm .doc - 1684Kb - 08/mar/2011 - 53 / 84

Ricordare che indirizzo non pu rappresentare una differenza maggiore di 128 rispetto allindirizzo in cui si trova
listruzione J*.

Una tabella di riferimento per consultare velocemente il comportamento delle istruzioni di salto condizionato, la seguente:

Istruzione ZeroF CarryF SegnoF OF PF Operatore Descrizione


JE,JZ 1 = Salta se uguali
JNE, JNZ 0 Salta se diversi
JA,JNBE 0 0 > Salta se maggiore, senza segno
JAE,JNB,JNC 0 >= Salta se maggiore o uguale, senza segno
JB,JC,JNAE 1 < Salta se minore, senza segno
JBE,JNA 1 1 <= Salta se minore o uguale, senza segno
JG,JNLE 0 = = > Salta se maggiore, con segno
JGE,JNL = = >= Salta se maggiore o uguale, con segno
JL,JNGE < Salta se minore, con segno
JLE,JNG 1 <= Salta se minore o uguale, con segno
JNO 0 Salta se non c overflow
JNP,JPO 0 Salta se ce non ce parit (ovvero c parit dispari)
JNS 0 Salta se non ce segno
JO 1 Salta se c overflow
JP,JPE 1 Salta se ce parit (pari)
JS 1 Salta se ce segno

Istruzione JMP
Sintassi: JMP indirizzo

Scopo: Sposta il flusso dellesecuzione allindirizzo

Esempi: JMP 120h JMP CS:120h

Nota: Listruzione viene usata per spostare il flusso dellesecuzione ad un indirizzo specifico in modo incondizionato.
Listruzione viene detta s a l t o i n c o n d i z i o n a t o e non ha i limiti di estensione del salto condizionato. Pu infatti
essere specificato un indirizzo completo seg:ofs.

Ecco come si presenta un codice Debug che attende un tasto, se il tasto lo zero (0), viene stampato a schermo una zeta maiuscola, altrimenti una
n minuscola:
C:\> Prompt di MsDos
C:\>debug Lancio del programma Debug da Msdos
-a 100 Edit del programma a partire dallindirizzo 100h
0d53:0100 mov ah,00 Sottofunzione 00h di INT 16h, Input di un carattere da Tastiera
0d53:0102 int 16 Lancio interruzione sw Bios 16h
0d53:0104 cmp al,30 Confronto carattere in input (AL) con carattere zero (30h = 0)
0d53:0106 je 0110 Se uguali, salta allindirizzo 110h ove si stamper Z
0d53:0108 mov al,6e Altrimenti si stampa il carattere n (6eh = n)
0d53:0100 mov ah,0e Sottofunzione 0Eh di INT 10h, Stampa carattere sullo Schermo
0d53:010c int 10 Lancio interruzione sw Bios 10h
0d53:010e jmp 0116 Salta alla fine del programma
0d53:0110 mov al,5a Si stampa il carattere Z (5ah = Z)
0d53:0112 mov ah,0e Sottofunzione 0Eh di INT 10h, Stampa carattere sullo Schermo
0d53:0114 int 10 Lancio interruzione sw Bios 10h
0d53:0116 int 20 Terminazione di file .COM
0d53:0118 Riga vuota: termine delledit
-n cmpj.com Assegnazione del nome
-r cx Comando per limpostazione della dimensione
CX 001e Visualizzazione del contenuto attuale del registro CX da parte di Debug
:18 Impostazione della dimensione (100h-118h=18h)
-w Comando per la scrittura del file di programma su disco
Scrittura di 00018 byte in corso Visualizzazione della quantit di byte scritti da parte di Debug
-q Uscita da debug
C:\> Prompt di MsDos

Istruzione INC
Sintassi: INC dest

Scopo: Listruzione INC incrementa di una unit dest, che pu essere un registro o una locazione di memoria.

Esempi: INC AX INC [102] INC DL

Nota: Non modifica il registro dei Flags, pertanto se servisse valutarli, si pu usare lequivalente ADD dest,1 (cfr. istruzione
ADD). La sua duale DEC, che ha la stessa sintassi e decrementa di una unit dest.

Istruzione LOOP
Sintassi: LOOP indirizzo

Scopo: Allesecuzione di LOOP la CPU decrementa di una unit il registro contatore CX; se CX diverso da zero, il flusso
passa allistruzione posta ad indirizzo, altrimenti il flusso dellesecuzione prosegue regolarmente in sequenza.
S3Abacus Architetture/Asm .doc - 1684Kb - 08/mar/2011 - 54 / 84

Esempi: LOOP 110h

Nota: Naturalmente literazione automatica di LOOP funziona solo se, prima del blocco da ripetere chiuso da LOOP, si
imposta il registro CX con il numero delle iterazioni desiderate. LOOP salta quasi sempre allindietro, ovvero indirizzo
quasi sempre una locazione di memoria precedente a LOOP, ma seguente allimpostazione di CX.

Ecco un codice per debug che stampa le 26 lettere minuscole dellelenco alfabetico inglese

C:\> Prompt di MsDos


C:\>debug Lancio del programma Debug da Msdos
-a 100 Edit del programma a partire dallindirizzo 100h
0d53:0100 mov cx,1a Numero di iterazioni: 26 (1ah = 26)
0d53:0103 mov dl,61 Codice Ascii della a minuscola (61h = a)
0d53:0105 mov ah,02 Sottofunzione 02h di INT 21h, Stampa carattere sullo Schermo
0d53:0107 int 21 Lancio interruzione sw MsDos 21h
0d53:0109 inc dl Incrementa di una unit il codice Ascii
0d53:010b loop 0105 Ripeti CX volte dallindirizzo 105h, quindi prosegui
0d53:010d int 20 Terminazione di file .COM
0d53:010f Riga vuota: termine delledit
-n alfabe.com Assegnazione del nome
-r cx Comando per limpostazione della dimensione
CX 0018 Visualizzazione del contenuto attuale del registro CX da parte di Debug
:f Impostazione della dimensione (100h-10Fh=Fh)
-w Comando per la scrittura del file di programma su disco
Scrittura di 0000f byte in corso Visualizzazione della quantit di byte scritti da parte di Debug
-q Uscita da debug
C:\> Prompt di MsDos

EDITARE UN PROGRAMMA
La scrittura di programmi con Debug complicata, soprattutto per quanto riguarda il calcolo degli indirizzi, ad esempio, per le istruzioni di salto.
Per rendere pi agevole luso di Debug, si pu utilizzarlo sfruttando i simboli di ridirezione di MsDos, ottenendo cos la possibilit di poter agire su
un codice sorgente in un file di testo.

La scrittura di un file sorgente per Debug semplice.

Avviare la scrittura di un file di testo (es. alfabe.txt) tramite un editor di testo (es. notepad alfabe.txt)
C:\>notepad alfabe.txt

Ogni istruzione va riportata su una riga, e la prima riga deve essere sempre il comando di Assemblaggio (es. a 100).
Dopodich vanno specificate le righe di codice, magari scrivendo indirizzi temporanei (es. sempre 100) laddove non possibile, in un
primo tempo, sapere il valore preciso dellindirizzo da specificare nel programma ( p r i m a p a s s a t a ).
Il codice va terminato, come al solito, con una riga vuota, quindi si riportano i comandi di Debug soliti per il salvataggio del file eseguibile
COM, specificando una dimensione temporanea abbondante (es. 100).
Ricordare di lasciare sempre una riga vuota al termine del file.

Editando un file per debug, si pu proficuamente dotare il testo di c o m m e n t i , cio di righe che non verranno prese in considerazione
dal programma Debug, e che contengono indicazioni di aiuto alla comprensione del listato.
I commenti si possono porre su righe che abbiano come primo carattere il p u n t o e v i r g o l a (;)

Il programma precedente, scritto su file di testo (es. alfabe.txt), appare nel seguente modo:

a 100
mov cx,1a
mov dl,61
mov ah,2
int 21
inc dl
loop 100 ; 100h = indirizzo temporaneo
int 20

n alfabe.com
rcx
100 Nota: 100h = dimensione temporanea
w
q

Per ottenere il file eseguibile (es. alfabe.com), ora sufficiente usare la seguente ridirezione al prompt di MsDos:
C:\>debug < alfabe.txt > alfabe.lst

Se il codice corretto, su disco viene salvato regolarmente il file eseguibile (es. alfabe.com) e un secondo file di tipo l i s t i n g (es.
alfabe.lst) che ha la seguente forma:

-a 100
0CE2:0100 mov cx,1a
0CE2:0103 mov dl,61
S3Abacus Architetture/Asm .doc - 1684Kb - 08/mar/2011 - 55 / 84

0CE2:0105 mov ah,2


0CE2:0107 int 21
0CE2:0109 inc dl
0CE2:010B loop 100
0CE2:010D int 20
0CE2:010F
-n alfabe.com
-rcx
CX 0000
:100
-w
Scrittura di 00100 byte in corso
-q

Se nella prima passata si erano riportati indirizzi temporanei, consultando il file di listing si possono agevolmente desumere gli indirizzi
reali, nonch la dimensione effettiva del programma. Con una s e c o n d a p a s s a t a sul file sorgente e una nuova operazione di
ridirezione, il programma viene messo a punto definitivamente. Ecco come appare dopo la messa a punto:

a 100
mov cx,1a
mov dl,61
mov ah,2
int 21
inc dl
loop 105 ; 105h = indirizzo effettivo, desunto dal file di listing
int 20

n alfabe.com
rcx
f Nota: fh = dimensione effettiva, desunta dal file di listing
w
q

Infine, si ottiene il file eseguibile definitivo (es. alfabe.com) riutilizzando di nuovo la ridirezione al prompt di MsDos:
C:\>debug < alfabe.txt > alfabe.lst

Lintera sequenza per editare, mettere a punto e generare il file eseguibile Com a partire da un file di testo TXT la seguente:

OUTPUT
C:\>
C:\>notepad alfabe.txt ; creazione del file di testo contenente il programma alfabe.txt
C:\>debug < alfabe.txt > alfabe.lst ; prima passata: creazione del file di listing alfabe.lst da consultare
C:\>notepad alfabe.lst ; apertura del file di listing per consentire la messa a punto
C:\>debug < alfabe.txt > alfabe.lst ; seconda passata: creazione del file eseguibile alfabe.com
C:\>alfabe ; esecuzione del programma alfabe.com
Abcdefghijklmnopqrstuvwxyz ; output del programma
C:\>

AREA DATI E AREA CODICE


Naturalmente le API di MsDos forniscono gli strumenti per memorizzare dati singoli (variabili), array di caratteri (stringhe), array di numeri e lI/O di
stringhe sullo schermo e dalla tastiera.
Lallocazione di dati in memoria avviene tramite una p s e u d o i s t r u z i o n e , ovvero una indicazione contenuta nel codice affinch il dato da allocare
sia semplicemente posto in memoria per distinguerlo dall op. code di una istruzione.
Le pseudoistruzioni non generano alcun codice macchina, ma servono solo per indicare come deve comportarsi un traduttore (nel nostro caso
Debug). Le pseudoistruzioni per allocare dati in memoria sono:

PseudoIstruzione D*
Sintassi: D* dato

Scopo: Alloca il dato allindirizzo corrente

Esempi: DB 0 DB 41h DB A DB ? DB 10 DUP (0)

Nota: Nel primo caso viene allocato un byte in memoria (0), nel secondo un byte che rappresenta il codice Ascii della A
maiuscola, nel terzo caso un modo equivalente al secondo e nel terzo si allocano due byte contigui.
Nel caso DB ? si alloloca un byte senza inizializzarlo (il valore in quella cella sar casuale), mentre in DB 10 DUP (0)
si indica lallocazione di 10 byte tutti inizializzati a 0.
E disponibile anche DW (alloca due byte) DD (4 byte) DQ (8 byte) e DT (10 byte), queste ultime spesso usate per
memorizzare numeri in virgola fissa per i calcoli con il coprocessore matematico.

Ovviamente larea di memoria destinata a contenere i dati (variabili e array) non deve essere eseguita come codice. Essa detta a r e a D a t i , e
deve essere separata dalla r e a C o d i c e , che contiene le istruzioni da eseguire.
S3Abacus Architetture/Asm .doc - 1684Kb - 08/mar/2011 - 56 / 84

Nel modello COM, area Dati e area Codice risiedono nello stesso segmento, cio in locazioni di memoria contigue. Se, come spesso si opta, larea
Dati viene posta allinizio della zona della memoria del programma, necessario porre una istruzione iniziale di salto incondizionato per saltare
larea Dati e avviare correttamente larea Codice.
In altri casi si pu optare allocando larea Dati immediatamente dopo larea di Codice.

Si veda il seguente esempio, in cui si allocano 8 byte contenenti i codici Ascii della stringa HAL, per stamparli sullo schermo:

a 100
jmp 105 ; Istruzione iniziale per saltare larea dati e indirizzare la prima istruzione dellarea codice (mov bx,102)
db 'H' ; Area Dati. Si allocano tre byte, I tre codici Ascii della stringa HAL
db 'A'
db 'L'
mov bx,102 ; Area Codice. In BX lindirizzo del primo byte dellarea Dati
mov cx,3 ; Contatore del ciclo a 3 (3 caratteri da stampare)
mov dl,[bx] ; Indirizzamento indiretto. In DL il codice Ascii che si trova in area Dati allindirizzo specificato in BX
mov ah,2 ; Sottofunzione 02h di MsDos, stampa carattere
int 21 ; Interruzione sw MsDos
inc bx ; Incremento dellindirizzo in area Dati: La prossima cella contiene il prossimo codice Ascii da stampare
loop 10b ; Iterazione a partire dallistruzione mov dl,[bx]
int 20

n hal.com
rcx
16
w
q

OUTPUT
C:\>hal
HAL
C:\>

Le tre locazioni di memoria cos allocate, possono ospitare a tutti gli effetti delle variabili. Infatti in quelle locazioni i dati possono essere cambiati a
runtime per memorizzare altri valori. Nellesempio, le tre locazioni vengono manipolate, aggiungendo una unit ad ogni cella, ottenendo i tre cosici
Ascii della stringa IBM, che poi verr stampata a schermo:

a 100
jmp 105
db 'H'
db 'A'
db 'L'
mov bx,102
mov cx,3 ; contatore a 3 (3 locazioni di memoria da manipolare)
mov al,[bx] ; lettura della variabile (locazione di memoria puntata da BX)
inc al ; incremento di una unit
mov [bx],al ; salvataggio della variabile (nella locazione di memoria puntata da BX)
inc bx ; prossima variabile in memoria
loop 10b ; iterazione
mov bx,102 ; indirizzo della prima locazione di memoria, per stampare a schermo
mov cx,3 ; contatore a 3 (3 stampe da effettuare)
mov dl,[bx]
mov ah,2
int 21
inc bx
loop 11a
int 20

n ibm.com
rcx
25
w
q
OUTPUT
C:\>ibm
IBM
C:\>

ALLINEAMENTO
Quando si alloca larea Dati prima dellarea Codice, non sempre la prima istruzione di codice pu essere collocata immediatamente dopo lultimo
byte dellarea Dati. Infatti il microprocessore interpreta i dati come codice e raggruppa i byte dei dati in base alle combinazioni di op. code che essi
formano inconsapevolmente.
Per evitare questa situazione, che impedisce lavvio del codice, bisogna allineare i dati, ovvero aggiungere in coda allarea Dati alcuni byte che
consentano alla CPU di interpretare correttamente la prima istruzione di codice.
Si veda questa situazione nel codice che segue, che effettua linput di tre caratteri, proponendo un prompt a forma di punto interrogativo, e indica a
video il maggiore con la stringa il max vale:.
S3Abacus Architetture/Asm .doc - 1684Kb - 08/mar/2011 - 57 / 84

In una prima versione, i dati della stringa causano il disallineamento del codice:

C:\>debug m3.com
-u 100
0D54:0100 EB0A JMP 010E JMP 10E
0D54:0102 49 DEC CX 49 (=i)
0D54:0103 6C DB 6C 6C (=l)
0D54:0104 206D61 AND [DI+61],CH 20 (= ) 6D (=m) 61 (=a)
0D54:0107 7820 JS 0129 78 (=x) 20 (= )
0D54:0109 7661 JBE 016C 76 (=v) 61 (=a)
0D54:010B 6C DB 6C 6C (=l)
0D54:010C 65 DB 65 65 (=e)
0D54:010D 3AB402B2 CMP DH,[SI+B202] 3A (=:) B402 (=MOV AH,02) B2
0D54:0111 3F AAS 3F (=MOV AL,3F)
0D54:0112 CD21 INT 21 CD21 INT 21
0D54:0114 B401 MOV AH,01 B401 MOV AH,01
0D54:0116 CD21 INT 21 CD21 INT 21

Come si pu notare, la sequenza di byte allocati in memoria che rappresentano la stringa il max vale:, non vengono correttamente allineati.
Infatti allindirizzo seg:010D il byte 3A (il codice Ascii dei due punti) viene compattato dellop. code dellistruzione CMP DH,[SI+B202], inglobando
la prima effettiva istruzione di codice (MOV AH,02) e facendo fallire il salto iniziale ad essa (JMP 10E).

Aggiungendo un solo byte al termine dellarea Dati, con la pseudoistruzione DB 0, il codice viene riallineato e il salto incondizionato deve essere
aggiornato con una unit in pi:

C:\>debug m3.com
-u 100
0D54:0100 EB0A JMP 010F JMP 10F
0D54:0102 49 DEC CX 49 (=i)
0D54:0103 6C DB 6C 6C (=l)
0D54:0104 206D61 AND [DI+61],CH 20 (= ) 6D (=m) 61 (=a)
0D54:0107 7820 JS 0129 78 (=x) 20 (= )
0D54:0109 7661 JBE 016C 76 (=v) 61 (=a)
0D54:010B 6C DB 6C 6C (=l)
0D54:010C 65 DB 65 65 (=e)
0D54:010D 3A00 CMP AL,[BX+SI] 3A (=:) 00 (=per lallineamento)
0D54:010F B402 MOV AH,02 B402 MOV AH,02
0D54:0111 B23F MOV DL,3F B23F MOV AL,3F
0D54:0113 CD21 INT 21 CD21 INT 21
0D54:0115 B401 MOV AH,01 B401 MOV AH,01
0D54:0117 CD21 INT 21 CD21 INT 21

Il programma completo:

a 100
JMP 10f ; Si salta larea Dati per arrivare allistruzione MOV AH,02
DB 'Il max vale:' ; area Dati
db 0 ; byte di allineamento. Usato anche come variabile per contenere il massimo
MOV AH,02 ; sottofunzione per la stampa di un carattere
MOV DL,3f ; codice Ascii del punto interrogativo (il prompt prima dellinput)
INT 21 ; Interruzione sw Msdos stampa un carattere
MOV AH,01 ; sottofunzione per linput di un carattere da tastiera
INT 21 ; Interruzione sw Msdos
MOV BX,10e ; in BX lindirizzo del byte di memoria che funger da variabile (il byte di allineamento)
MOV [BX],AL ; memorizzazione dellinput nella variabile
MOV AH,02 ; secondo prompt per il secondo input
MOV DL,3f
INT 21
MOV AH,01 ; secondo input
INT 21
CMP AL,[BX] ; confronto tra linput e la variabile in memoria
JL 12e ; se inferiore, non memorizzo (salto allistruzione MOV AH,02)
MOV [BX],AL ; altrimenti salvo nella variabile il nuovo massimo
MOV AH,02 ; terzo prompt per il terzo input
MOV DL,3f
INT 21
MOV AH,01 ; terzo input
INT 21
CMP AL,[BX] ; confronto tra linput e la variabile in memoria
JL 13e ; se inferiore, non memorizzo (salto allistruzione MOV CX,0d)
MOV [BX],AL ; altrimenti salvo nella variabile il nuovo massimo
MOV CX,0d ; contatore a 13 (0dh=13) per i 12 caratteri della stringa da stampare pi il byte della variabile che contiene il max
MOV AH,02 ; sottofunzione di stampa carattere
MOV BX,102 ; indirizzo iniziale dei caratteri da stampare
MOV DL,[BX] ; in DL il carattere da stampare, prelevato dalla memoria
INT 21 ; interruzione MsDos
S3Abacus Architetture/Asm .doc - 1684Kb - 08/mar/2011 - 58 / 84

INC BX ; prossimo indirizzo per il prossimo carattere


LOOP 146 ; iterazione dalla istruzione MOV AH,02
INT 20

n m3.COM
rcx
4f
w
q

OUTPUT
C:\>m3
?1?5?3Il max vale:5
C:\>m3
?6?4?3Il max vale:6
C:\>m3
?1?2?9Il max vale:9
C:\>
S3Abacus Architetture/Asm .doc - 1684Kb - 08/mar/2011 - 59 / 84

ASSEMBLY CON TASM


Naturalmente la programmazione dellassembler x-86 con Debug ha senso solo per ragioni didattiche.
Nella realt, aldil di brevi frammenti di codice di test, Debug non viene utilizzato per scrivere programmi, e i programmatori si affidano a veri e
propri ambienti di sviluppo su linea di comando, i pi noti dei quali sono T A S M (Borland) e M A S M (Microsoft). Un ambiente freeware molto
apprezzato anche N A S M , in ogni caso tutti prodotti ormai facilmente reperibili senza alcun costo.
La scelta di TASM deriva dal fatto che la sintassi MASM correttamente interpretata da TASM, mentre non vero il viceversa.

Come si verificato utilizzando Debug, la principale difficolt nello scrivere programmi in assembler la gestione degli indirizzi e il loro ricalcolo ad
ogni modifica del programma. Inoltre tali ambienti offrono la possibilit di utilizzare decine di pseudoistruzioni e direttive che rendono la
programmazione assembler molto efficace e veloce.

La gestione semplificata degli indirizzi viene ottenuta da questi ambienti tramite luso delle e t i c h e t t e (label) al posto degli indirizzi numerici, e del
concetto di d o p p i a p a s s a t a dellassemblatore, che il programma che analizza il file sorgente contenente il codice assembler e le
pseudoistruzioni.
Con la doppia passata lassemblatore traduce correttamente tutte le etichette nei corrispondendi indirizzi numerici senza che il programmatore
debba pi preoccuparsene, cosicch nei files sorgenti scritti per questi ambienti, luso degli indirizzi numerici praticamente abolito.
Letichetta, inoltre, rende il codice molto pi comprensibile, dato che gli identificatopri di etichetta sono scelti dal programmatore e possono
descrivere, tramite il loro nome, la funzione svolta dallindirizzo simbolico che rappresentano.

STRUTTURA DEI PROGRAMMI


Come si visto in precedenza, i programmi contengono, generalmente, almeno due aree distinte di istruzioni: larea del Codice e larea Dati.
Questo vale per qualsiasi programma scritto in qualsiasi linguaggio.
Oltre a queste due aree, i programmi ne contengono altre, altrettanto impostanti: a r e a d i S t a r t u p , a r e a d e l l o S t a c k e a r e a d e l l o H e a p

Area di Startup
E la zona iniziale di ogni programma, generata da un programma speciale denominato l i n k e r (correlatore) che si incarica di scrivere le prime
istruzioni da eseguire subito dopo che il Sistema Operativo avvia il processo a partire dal programma su disco. Questo codice deve essere coerente
con le regole di esecuzione del Sistema Operativo, da cui riceve il controllo, e deve essere in grado di avviare la prima istruzione eseguibile scritta
dal programmatore (e n t r y p o i n t ) in modo corretto, fornendo i dati di avvio ereditati dal Sistema Operativo, come ad esempio i p a r a m e t r i s u
r i g a d i c o m a n d o . Solo i files eseguibili .COM non possiedono unarea di Startup.

Area di Codice
E la zona del programma che contiene le istruzioni da eseguire durante lesecuzione, cio durante il r u n t i m e del programma.
Larea di codice scritta espressamente dal programmatore tramite le regole della sintassi.di un linguaggio di programmazione, nel nostro caso le
regole della programmazione assembler x-86. Essa si trova immediatamente dopo larea di Startup, dalla quale eredita il controllo allavvio
dellesecuzione del programma.

Area Dati
E la zona in cui il programmatore alloca i dati tramite istruzioni presenti nellarea Codice. Qui trovano posto le v a r i a b i l i g l o b a l i s t a t i c h e dei
programmi, cio quelle locazioni di memoria disponibili durante tutto il runtime. Questa area sia di lettura che di scrittura, a differenza dellarea di
Codice e di Startup che sono esclusivamente aree di lettura.

Area dello Heap


E una zona opzionale, in cui durante il runtime, il programmatore, tramite istruzioni ben precise, alloca temporaneamente della memoria per far
posto a variabili la cui dimensione accertabile solo durante lesecuzione (es. la dimensione di una stringa in input). E anche detta m e m o r i a
d i n a m i c a , dato che la sua dimensione non prefissata e pu essere anche allocata e deallocata pi volte durante il runtime. La gestione dellarea
di Heap viene ottenuta tramite istruzioni in area Codice, che richiedono i servizi di allocazione/deallocazione al Sistema Operativo.

Area dello Stack


E una zona gestita automaticamente dai compilatori su tipiche tecniche di programmazione scritte in area di Codice dal programmatore, come la
dichiarazione di v a r i a b i l i l o c a l i e il p a s s a g g i o d i p a r a m e t r i a l l e p r o c e d u r e : a fronte di questi costrutti, i compilatori gestiscono larea
di Stack in modo trasparente al programmatore, allocando e deallocando le variabili locali e i parametri passati alle procedure. Solo nella
programmazione in Assembler possibile gestire direttamente larea di Stack con opportune istruzioni.

CICLO DI VITA DI UN PROGRAMMA


La creazione, lo sviluppo, lesecuzione e la messa a punto di un programma, generalmente, segue un certo numero di fasi caratterizzate da attivit
specifiche, tempi specifici, applicazioni di supporto specifiche, errori specifici e file specifici.
E possibile sintetizzare il ciclo di vita di un programma tramite un diagramma e una tabella che riportano fasi, tempi, applicazioni, files ed errori
relativi ad ogni fase.
S3Abacus Architetture/Asm .doc - 1684Kb - 08/mar/2011 - 60 / 84

Fase di Edit
Il programmatore scrive il testo del programma (sorgente) con la sintassi di un linguaggio di programmazione. Spesso i programmi sono costituiti da
pi sorgenti, ma solo uno contiene le n t r y p o i n t del programma. I rimanenti sono denominati l i b r e r i e d i c o d i c e .
Il programma usato in questa fase un E d i t o r , spesso integrato in un I D E (Integrated Development Equipment). Lattivit del programmatore in
questa fase detta D e s i g n T i m e . Gli errori pi frequenti a Design Time riguardano il formato dei files (es. i files devono essere rigorosamente
files di testo), la loro irreperibilit o la loro corruzione.

Fase di Compilazione
Una volta completato un modulo sorgente, esso deve essere assemblato, ovvero le istruzioni e le pseudoistruzioni presenti nei sorgenti in
linguaggio simbolico ad alto livello, devono essere trasformate in assembler, a basso livello. Ogni file sorgente quindi viene ridotto, da un
programma di supporto denominato a s s e m b l a t o r e , a un file binario corrispondente (detto anche file o g g e t t o ).
Dopo lassemblaggio, necessaria la c o r r e l a z i o n e o l i n k i n g , ad opera di un secondo programma a supporto, denominato l i n k e r .
Il linker collega tutti i files oggetto in uno solo, e genera il file eseguibile (t a r g e t della compilazione), aggiungendovi, nella sua parte iniziale, la
porzione di Startup (cfr. Struttura dei programmi) e leventuale Header (cfr. Formato degli eseguibili e Rilocazione). Le due fasi di assemblaggio e
linking sono spesso riunite in un unico passo, denominato C o m p i l e T i m e .
Durante il Compile Time si possono verificare i tipici errori di sintassi (del linguggio scelto) che sono sempre segnalati dai programmi compilatori,
sottoforma di errori e/o warning.

Fase di Caricamento
Una volta su disco, il programma eseguibile deve essere caricato in memoria dal Sistema Operativo per essere poi trasformato in processo.
Il SO legge lo header del file eseguibile e carica in memoria il programma, dopodich cede il controllo al codice di Startup delleseguibile. Spesso i
SO creano una zona di memoria di collegamento tra programma e Sistema Operativo (cfr. PSP in Formato degli eseguibili e Rilocazione) prima di
cedere il controllo.
Tipici errori della fase di L o a d T i m e sono errati formati degli header, o limpossibilit del caricamento per scarsit di memoria.

Fase di Esecuzione
Il R u n t i m e il tempo durante il quale il processo opera in CPU, dalla prima istruzione di codice allultima prevista dal programmatore. Tipici errori
di RunTime sono le divisioni per zero, i loop infiniti, le terminazioni anomale per mancanza o incongruenza delle risorse richieste dal programma.

Fase di messa a Punto


Il Runtime pu anche essere avviato tramite un programma speciale, denominato d e b u g g e r .
In questo caso il debugger carica ed esegue il programma nelle modalit impostate dal programmatore, ad esempio p a s s o p a s s o (per verificare
il flusso dellesecuzione) o tramite b r e a k p o i n t , ovvero sospensioni dellesecuzione su istruzioni critiche, per eplorare lo stato di registri, variabili e
memoria (w a t c h ). Tutto ci al fine di individuare le cause di eventuali malfunzionamenti riscontrati al Runtime.

CICLO DI VITA DI UN PROGRAMMA TASM


Allo stesso modo, lambiente di sviluppo TASM prevede le fasi tipiche del ciclo di vita di un programma, fornendo i relativi programmi di supporto.
Bisogna tener presente che, malgrado si sia scelto di sviluppare direttamente in Assembler, e quindi in apparenza potrebbe sembrare inutile una
fase di compilazione, luso delle fondamentali due passate per risolvere il problema degli indirizzi numerici, rende necessaria la presenza di un
programma assemblatore e un programma linker.
I sorgenti per TASM possono essere scritti con un qualsiasi editor di testo (es. Notepad di Windows), avendo cura di usare sempre lestensione
.ASM per ogni modulo sorgente; il programma assemblatore si chiama TASM.EXE e il programma linker si chiama TLINK.EXE. Il programma
debugger, infine, si chiama Turbo Debugger (TD.EXE).
In particolare, per usare TASM, sono sufficienti i seguenti files, reperibili anche allinterno delle cartelle dei compilatori Borland C 3.1 e/o Turbo
Pascal 7.0: TASM.EXE, TLINK.EXE, TD.EXE, DPMILOAD.EXE, DPMIMEM.DLL

Limitandoci per ora a programmi composti da un unico file sorgente (es. PIPPO.ASM), scritto per ottenere un eseguibile di tipo COM (es.
PIPPO.COM), assemblaggio, linking e debugging si avviano nei seguenti modi:

C:\>tasm pippo ; lassemblatore tasm.exe genera il file oggetto pippo.obj dal file sorgente pippo.asm
C:\>tlink pippo /t ; il linker tlink.exe genera il file eseguibile pippo.com dal file oggetto pippo.obj
S3Abacus Architetture/Asm .doc - 1684Kb - 08/mar/2011 - 61 / 84

C:\>pippo ; MsDos carica in memoria il file eseguibile pippo.com per lesecuzione


C:\>td pippo.com ; oppure il debugger td.exe carica il file eseguibile pippo.com per la messa a punto

Si noti come tasm e tlink non abbiano bisogno che venga specificata lestensione dei file in ingresso, rispettivamente pippo.asm per tasm,
pippo.obj per tlink.
La fase di correlazione operata da tlink viene eseguita con il parametro /t per indicare a tlink di non creare lo header del file. Infatti gli eseguibili
di tipo COM sono gli unici che mancano sia di Header che di area di Startup.

Se il file sorgente contiene errori di sintassi, lassemblatore mostra un messaggio esplicito che indica il tipo di errore e la riga su cui stato rilevato.
E ovvio che in presenza di errori, il file oggetto non viene creato, interrompendo la fase di creazione del file eseguibile.
Allo stesso modo, ma pi raramente, il linker mostra un messaggio derrore nel caso di incongruenza nella correlazione..

Nellesempio, una sequenza corretta di creazione e lancio di un programma assembler con TASM (il programma che calcola il massimo di tre
caratteri, riscritto per TASM):
OUTPUT
C:\>tasm m3
Turbo Assembler Version 3.1 Copyright (c) 1988, 1992 Borland International

Assembling file: m3.asm


Error messages: None
Warning messages: None
Passes: 1
Remaining memory: 452k

C:\>tlink m3 /t
Turbo Link Version 5.1 Copyright (c) 1992 Borland International

C:\>m3
?1?5?3Il max vale:5
C:\>

In questaltro caso, una esempio che riporta una tipica videata di errore riscontrato durante lassemblaggio, causato da un errato uso dellistruzione
MOV DL,0a3fh (in DL possono essere memorizzati solo byte, non word):

OUTPUT
C:\>tasm m3
Turbo Assembler Version 3.1 Copyright (c) 1988, 1992 Borland International

Assembling file: m3.asm


**Error** m3.asm(22) Constant too large
Error messages: 1
Warning messages: None
Passes: 1
Remaining memory: 452k

C:\>

Si noti che lerrore si trova sulla riga 22 del codice sorgente, come indicato dal messaggio derrore.

Infine, una tipica videata del debugger TD, applicato al file m3.com:

OUTPUT
C:\>td m3.com

File Edit View Run Breakpoints Data Options Window Help READY
[]CPU 804861[]
cs:0100EB0E jmp 0110 ax 0000 c=0
cs:0102 90 nop bx 0000 z=0
cs:0103 49 dec cx cx 0000 s=0
cs:0104 6C insb dx 0000 o=0
cs:0105 206D61 and [di+61],ch si 0000 p=0
cs:0108 7820 js 012A di 0000 a=0
cs:010A 7661 jbe 016D bp 0000 i=1
cs:010C 6C insb sp FFFE d=0
cs:010D 653A00 cmp al,gs:[bx+si] ds 547F
cs:0110 B402 mov ah,02 es 547F
cs:0112 B23F mov dl,3F ss 547F
cs:0114 CD21 int 21 cs 547F
cs:0116 B401 mov ah,01 ip 0100
cs:0118 CD21 int 21
cs:011A BB0F01 mov bx,010F

ds:0100 EB 0E 90 49 6C 20 6D 61 Il ma ss:0000 20CD


ds:0108 78 20 76 61 6C 65 3A 00 x vale: ss:FFFE0000
ds:0110 B4 02 B2 3F CD 21 B4 01 ?! ss:FFFC 0000
ds:0118 CD 21 BB 0F 01 88 07 B4 ! ss:FFFA 0000
ds:0120 02 B2 3F CD 21 B4 01 CD ?! ss:FFF8 0000

F1-Help F2-Bkpt F3-Mod F4-Here F5-Zoom F6-Next F7-Trace F8-Step F9-Run F10-Menu
S3Abacus Architetture/Asm .doc - 1684Kb - 08/mar/2011 - 62 / 84

C:\>

SCRIVERE UN PROGRAMMA EXE


Come si visto, lassembler x-86 prevede che I programmi siano sviluppati, attraverso le aree tipiche di un programma quali area di Codice, area
Dati e area di Stack, allinterno di aree di memoria contenute in segmenti, cio zone di memoria ampie 64 Kbytes. Per gli eseguibili di tipo COM,
tutte le tre aree tipiche risiedono nello stesso segmento, che anche lunico segmento possibile per questo tipo di programmi; inoltre gli eseguibili di
tipo COM non possiedono larea di Startup, essendo caricati in memoria dal loader di Sistema Operativo con caricamento rilocante statico (cfr.
Formato degli eseguibili e Rilocazione: EXE e COM).
Gli eseguibili di tipo EXE, i pi comuni e diffusi, hanno invece la necessit che le tre aree siano assegnate a rispettivi segmenti in memoria,
potendo, anche in questo caso, essere lo stesso segmento di memoria, ma tuttavia con la necessit di essere esplicitati espressamente nel codice
cos da poter permettere il caricamento rilocante dinamico.

Ecco allora come si presenta un generico programma sorgente x-86 per MsDos destinato a diventare un eseguibile di tipo EXE (il solito programma
per il calcolo del massimo tra tre caratteri in input).
Il codice presenta numerose e t i c h e t t e (in blu, per evitare luso di indirizzi numerici) e p s e u d o i s t r u z i o n i (in verde, per indicare
allassemblatore le intenzioni del programmatore).

SEG_DATI segment ; definizione del segmento per larea Dati

MSG DB "Il max vale:"


VAR DB 0

ends

SEG_STACK segment stack ; definizione del segmento per larea di Stack

ends

SEG_CODICE segment ; definizione del segmento per larea Codice

assume cs:SEG_CODICE, ; associazione dei nomi dei segmenti ai registri di segmento


ss:SEG_STACK,
ds:SEG_DATI,
es:SEG_DATI

START: ; etichetta che segnala linizio dellarea Codice


mov ax, SEG_DATI ; impostazioni a runtime dei valori di segmento ai registri di segmento
mov ds,ax
mov es, ax
mov ax, SEG_STACK ; impostazioni a runtime dei valori di segmento ai registri di segmento
mov ss, ax

mov ah,02 ; codice del programma


mov dl,3fh
int 21h
mov ah,01
int 21h
lea bx,VAR ; riferimento di una etichetta contenente un indirizzo di memoria in area Dati
mov [bx],al
mov ah,02
mov dl,3fh
int 21h
mov ah,01
int 21h
cmp al,[bx]
jl SALTA1 ; riferimento di una etichetta contenente un indirizzo di memoria in area Codice
mov [bx],al
SALTA1:
mov ah,02
mov dl,3fh
int 21h
mov ah,01
int 21h
cmp al,[bx]
jl SALTA2
mov [bx],al
SALTA2:
mov cx,0dh
lea bx,MSG
CICLO:
mov ah,02
mov dl,[bx]
int 21h
S3Abacus Architetture/Asm .doc - 1684Kb - 08/mar/2011 - 63 / 84

inc bx
loop CICLO
mov ax, 4c00h
int 21h
ends

end START ; chiusura delletichetta che segnalava linizio dellarea Codice e chiusura del file

Le tre etichette principali SEG_DATI, SEG_STACK e SEG_CODICE danno il nome ai tre segmenti di memoria di questo programma, segmenti
inizializzati dalla pseudoistruzione segment/ends. In effetti questo programma non usa una area dello Stack, quindi in linea di principio non
sarebbe necessario specificarla.
Nellarea Codice, infine, la pseudoistruzione assume cs:,ds:,ss:,es: consente di associare le tre aree ai registri di segmento appropriati.
Si noti come i registro Extra (ES) sia impostato sullo stesso valore del registro dati DS.
Infine, come istruzioni effettive, bisogna impostare i registri di segmento con i valori indicati tramite le pseudoistruzioni.
Si noti come non sia possibile impostare un registro di segmento direttamente, ma solo tramite un registro dappoggio (in questo caso AX).
La direttiva end a fine file necessaria affinch lassemblatore sappia con precisione quando il file sorgente terminato.

Molto interessante luso delle etichette VAR, MSG, SALTA1, SALTA2 e CICLO esse consentono di evitare luso di indirizzi numerici, lasciando il
compito di calcolarli adeguatamente allassemblatore.
Le etichette che segnalano indirizzi allinterno dellarea codice sono dette l a b e l , e devono terminare con i due punti (:). Quando le etichette sono
usate nel codice, invece, si parla di r i f e r i m e n t o alletichetta.

Attenzione
A. Il nome di fantasia di una label pu apparire una sola volta nel codice (mentre i riferimenti sono liberi), altrimenti lassemblatore non saprebbe a
quale indirizzo associarne il nome.
B. La distanza tra letichetta e ogni suo riferimento tramite un salto condizionato rimane vincolata a un massimo di 128 byte. Ci deriva dal limite
progettuale delle istruzioni di salto condizionato.
Entrambi questi limiti possono essere risolti dallassemblatore attraverso speciali direttive LOCALS e JUMPS (cfr. Direttive per la programmazione e
Librerie)

Infine, letichetta START, con la sua chiusura a fine sorgente, necessaria affinch lassemblatore possa considerare terminata larea di Codice del
programma (si tratta di una specifica che indica il termine del modulo principale che contiene il punto di ingresso dellarea Codice di un programma)

Le etichette sono identificativi ideati dal programmatore, ovvero nomi di fantasia. Esse non possono n cominciare con un numero, n riportare
spazi o caratteri speciali. Va da s che il programmatore usi nomi significativi per esse, magari in base a indicazioni precise che vengono dette
regole di naming.

La compilazione di un sorgente destinato a diventare un file eseguibile di tipo EXE:

C:\>tasm pippo ; lassemblatore tasm.exe genera il file oggetto pippo.obj dal file sorgente pippo.asm
C:\>tlink pippo ; il linker tlink.exe genera il file eseguibile pippo.exe dal file oggetto pippo.obj

MODELLI DI MEMORIA
Questo sorgente genera quindi un file EXE in cui area Dati, area Codice e area dello Stack risiedono su tre segmenti separati.
Questo programma, pertanto, potr essere ampio al pi 64KB + 64KB = 128 KB, di cui 64 KB riservati al codice, e 64KB riservati ai dati.
Per superare questi limiti, il programmatore deve usare in modo spesso anche complesso le direttive segment/ends e assume allinterno del
codice, cos da ottenere programmi che possano operare su pi segmenti di codice e pi segmenti di dati.

Per evitare la gestione esplicita di queste direttive di segmento, lassemblatore TASM mette a disposizione una pseudoistruzione molto efficace che
semplifica luso delle direttive di segmento: con la pesudoistruzione M O D E L , infatti, il programmatore pu decidere il modello di memoria
desiderato per il proprio programma, senza pi preoccuparsi di gestire i segmenti.

Direttiva MODEL
Sintassi: .MODEL tipo

Scopo: Lassemblatore regola la generazione dei segmenti di Codice, Dati e Stack in base al tipo indicato
T I N Y , un solo segmento comune per area Codice, Dati e Stack. Dedicato ai programmi eseguibili di tipo COM
S M A L L , un segmento per area Codice, un segmento per area Dati e Stack, solo per eseguibili di tipo EXE
M E D I U M , pi segmenti per larea Codice, un solo segmento per area Dati e area Stack.
C O M P A C T , pi segmenti per larea Dati, un solo segmento per area Codice e area Stack.
L A R G E , pi segmenti per larea Codice, pi segmenti per larea di Dati, pi segmenti per larea di Stack.
H U G E , come LARGE, con la possibilit che un dato contiguo possa essere maggiore di un segmento (es. un array >
64KB).

Esempi: .MODEL TINY .MODEL SMALL .MODEL LARGE

Nota: In realt esiste un sesto modello di memoria, denominato FLAT, che non prevede segmentazione e usato solo nelle
piattaforme a 32bit.

Ecco come diventa lo stesso sorgente di poco fa in sintassi semplificata:

.MODEL SMALL ; direttiva di segmento per il modello di memoria desiderato


.STACK ; direttiva per la definizione del segmento dellarea di Stack
S3Abacus Architetture/Asm .doc - 1684Kb - 08/mar/2011 - 64 / 84

.DATA ; direttiva per la definizione del segmento dellarea Dati

MSG DB "Il max vale:"


VAR DB 0

.CODE ; direttiva per la definizione del segmento dellarea Codice

mov ax,@DATA ; impostazioni a runtime del valore di segmento per larea Dati
mov ds,ax

mov ah,02 ; codice del programma


mov dl,3fh
int 21h
mov ah,01
int 21h
lea bx,VAR ; uso di una etichetta contenente un indirizzo di memoria in area Dati
mov [bx],al
mov ah,02
mov dl,3fh
int 21h
mov ah,01
int 21h
cmp al,[bx]
jl SALTA1 ; uso di una etichetta contenente un indirizzo di memoria in area Codice
mov [bx],al
SALTA1:
mov ah,02
mov dl,3fh
int 21h
mov ah,01
int 21h
cmp al,[bx]
jl SALTA2
mov [bx],al
SALTA2:
mov cx,0dh
lea bx,MSG
CICLO:
mov ah,02
mov dl,[bx]
int 21h
inc bx
loop CICLO
mov ax, 4c00h
int 21h
end

Le direttive .MODEL, .DATA, .STACK e .CODE sono dette d i r e t t i v e d i s e g m e n t o s e m p l i f i c a t e , e rendono i sorgenti assembly molto pi
semplici da gestire, evitando al programmatore lo sforzo di definire i vari segmenti del programma in modo esplicito.
Lunica accortezza da ricordare il caricamento esplicito del segmento Dati tramite letichetta di sistema @DATA

SCRIVERE UN PROGRAMMA COM


Per imparare la programmazione assembly x-86 pi che sufficiente sviluppare programmi eseguibili di formato COM, che sono anche pi semplici
nella struttura, evitando di usare pseudoistruzioni e istruzioni per la definizione e il caricamento dei registri di segmento.
Spesso, infatti, anche i programmi eseguibili di formato EXE vengono ridotti a COM, per sfruttarne la semplicit e la velocit di caricamento, con un
apposito applicativo del SO, denominato E X E 2 B I N .

Ecco i codici sorgenti del solito programma che calcola il massimo di tre caratteri in input, nella versione con direttive di segmento e direttive di
segmento semplificate:

Sorgente per file COM Sorgente per file COM


Con direttive di segmento Con direttive di segmento semplificate

SEG_UNICO segment ; unico segmento per Area Dati e Codice


assume CS:SEG_UNICO .MODEL TINY ; modello di memoria per files COM
assume DS:SEG_UNICO .CODE ; definizione area Codice e Dati

ORG 100H ; il codice inizia a 100h, e non a zero ORG 100h ; il codice inizia a 100h e non a zero

START: jmp MAIN ; si salta larea Dati START: jmp MAIN ; si salta larea Dati

MSG DB "Il max vale:" ; area Dati MSG DB "Il max vale:" ; area Dati
VAR DB 0 VAR DB 0

MAIN: ; area Codice MAIN: ; area Codice


mov ah,02 mov ah,02
S3Abacus Architetture/Asm .doc - 1684Kb - 08/mar/2011 - 65 / 84

mov dl,3fh mov dl,3fh


int 21h int 21h
mov ah,01 mov ah,01
int 21h int 21h
lea bx, VAR lea bx, VAR
mov [bx],al mov [bx],al
mov ah,02 mov ah,02
mov dl,3fh mov dl,3fh
int 21h int 21h
mov ah,01 mov ah,01
int 21h int 21h
cmp al,[bx] cmp al,[bx]
jl SALTA1 jl SALTA1
mov [bx],al mov [bx],al
SALTA1: SALTA1:
mov ah,02 mov ah,02
mov dl,3fh mov dl,3fh
int 21h int 21h
mov ah,01 mov ah,01
int 21h int 21h
cmp al,[bx] cmp al,[bx]
jl SALTA2 jl SALTA2
mov [bx],al mov [bx],al
SALTA2: SALTA2:
mov cx,0dh mov cx,0dh
lea bx,MSG lea bx,MSG
CICLO: CICLO:
mov ah,02 mov ah,02
mov dl,[bx] mov dl,[bx]
int 21h int 21h
inc bx inc bx
loop CICLO loop CICLO
int 20h int 20h
ends ; fine segmento unico end START ; fine programma
end START ; fine programma

Si noti che, dovendo risiedere dati e codice nello stesso segmento, come sempre per i files eseguibili COM, la prima istruzione di codice deve
saltare larea Dati con un salto incondizionato.

Direttiva ORG
Sintassi: ORG valore

Scopo: La fondamentale direttiva O R G (Origine) indica allassemblatore che lorigine degli indirizzi del segmento deve valere
valore e non zero.

Esempi: ORG 100h

Nota: Si impone che il Location Counter dellassemblatore inizi il conteggio degli indirizzi a partire dal valore 100h e non dal
valore 0. Tipico caso dellassemblaggio dei files .COM.

Con la direttiva ORG 100h si impone che gli indirizzi delleseguibile di tipo COM comincino dal 256 byte (=100h) del segmento di codice, per saltare
larea del PSP (cfr. Formato degli eseguibili e Rilocazione)

La compilazione di un sorgente destinato a diventare un eseguibile di tipo COM deve ricordare al linker di non immettere larea di startup
nelleseguibile tramite lo p z i o n e / t , pertanto i sorgenti di questo tipo devono essere compilati nel seguente modo:

C:\>tasm pippo ; lassemblatore tasm.exe genera il file oggetto pippo.obj dal file sorgente pippo.asm
C:\>tlink pippo /t ; il linker tlink.exe genera il file eseguibile pippo.com dal file oggetto pippo.obj
S3Abacus Architetture/Asm .doc - 1684Kb - 08/mar/2011 - 66 / 84

ASSEMBLY X-86 AVANZATO


S3Abacus Architetture/Asm .doc - 1684Kb - 08/mar/2011 - 67 / 84

MACRO
Come sempre accade nella programmazione, speciali valori sono cos importanti da meritarsi un nome proprio, cos da poterli velocemente
individuare allinterno del codice sorgente. Assegnare il nome ad un valore altres fondamentale per questioni di manutenzione del codice. Infatti,
se il valore dovesse essere modificato, luso di un nome simbolico consente di modificare il valore solo una volta, avendo usando solo il nome del
valore allinterno del codice. Assegnare un nome a un valore significa definire una m a c r o c o s t a n t e .

MACRO COSTANTI
Si veda questo breve codice che stampa a schermo la cifra 0 e, a capo, la cifra 1:

.MODEL TINY
.CODE
ORG 100h
START:
mov ah,02
mov dl,'0' ; il codice Ascii dello zero (30h) pu essere scritto con questa sintassi derivata dal C: 30h = 0
int 21h ; stampa a video il carattere zero
mov ah,02
mov dl,0dh ; il codice Ascii 0dh (=13d) il Carriage Return (CR). Sposta il cursore allinizio della riga corrente
int 21h
mov dl,0ah ; il codice Ascii 0ah (=10d) il Line Feed (LF). Sposta il cursore nella riga sottostante
int 21h
mov ah,02
mov dl,'1'
int 21h ; stampa a video il carattere uno
int 20h
end START

OUTPUT
C:\>acapo
0
1
C:\>

La stampa a schermo dei caratteri Ascii speciali 0dh (=13d) e 0ah (=10d), detti rispettivamente CR (C a r r i a g e R e t u r n ) e LF (L i n e F e e d ),
provoca leffetto dell andare a capo.
Siccome si tratta di valori speciali, usati per un compito dedicato, buona norma nominarli e usare, nel codice sorgente, il loro nome.
Nominare un valore, significa creare una costante Macro, cio un nome simbolico associato ad un valore: quando lassemblatore incontra quel
nome simbolico nel sorgente, sostituisce il simbolo con il valore corrispondente ( e s p a n s i o n e d e l l a m a c r o ).

PseudoIstruzione EQU
Sintassi: nome EQU espressione

Scopo: Crea il nome che sar sostituito con espressione durante lassemblaggio.

Esempi: CR EQU 0dh RIGA EQU 80 COLONNA EQU 25 SCHERMO EQU RIGA*COLONNA

Nota: Normalmente i simboli delle costanti macro sono scritti in maiuscolo.


Si noti che lassemblatore, durante la prima passata, pu ricalcolare valori costanti tramite operatori aritmetici (+,-,*,/)
e sostituire, al simbolo, il valore costante ricalcolato. La pseudoistruzione EQU del tutto equivalente alla direttiva
#define del linguaggio C.

Ovviamente la pseudoistruzione EQU non genera alcuna riga di codice macchina, essendo una direttiva. Lassemblatore si limita a sostituire ai
simboli individuati nel sorgente, i rispettivi valori costanti durante il compile time. Per questo motivo le costanti EQU vanno citate prima dellinizio
del codice.

Il programma sottostante equivalente al precedente; usa EQU per indicare costanti speciali. Loutput rimane invariato

CR EQU 13 ; Direttive EQU per CR e LF


LF EQU 10

.MODEL TINY
.CODE
ORG 100h

START:
mov ah,02
mov dl,'0'
int 21h
mov ah,02
mov dl,CR ; il simbolo CR sar sostituito con il valore 13 (=0dh)
int 21h
mov dl,LF ; il simbolo LF sar sostituito con il valore 10 (=0ah)
S3Abacus Architetture/Asm .doc - 1684Kb - 08/mar/2011 - 68 / 84

int 21h
mov ah,02
mov dl,'1'
int 21h ; stampa a video il carattere uno
int 20h
end START

MACRO DI CODICE
Dovendo stampare diverse righe di zeri e uni, nel codice dovremmo usare varie volte le sei righe di codice che stampano a schermo un acapo.
Il codice ripetuto appesantisce il sorgente e lo rende meno leggibile, cosicch possibile riunire un blocco di codice sorgente e assegnargli un
nome simbolico, citando il solo nome nel codice. In questo caso si parla di m a c r o d i c o d i c e .
Come prima, durante la prima passata, lassemblatore, quando incontra il nome simbolico di una macro di codice, sostituisce ad essa lintero blocco
di codice corrispondente (e s p a n s i o n e d e l l a m a c r o ), operazione di nuovo eseguita a compile time.

PseudoIstruzione MACRO / ENDM


Sintassi: nome MACRO
(codice)
ENDM

Scopo: Crea il blocco di (codice) che sar sostituito al simbolo nome durante lassemblaggio.

Esempi: BEEP MACRO ACAPO MACRO


mov ah,2 mov ah,2
mov dl, 7 mov dl, 13
int 21h int 21h
ENDM mov dl, 10
Int 21h
ENDM

Nota: Negli esempi, una macro BEEP che emette un suono (infatti il codice Ascii speciale 7 non emette simboli sullo
schermo, ma un breve beep). Quindi una macro ACAPO che emette un acapo sullo schermo.

Si veda il seguente codice, che stampa una sequenza di zeri e uni su quattro righe:

ACAPO MACRO ; Definizione della macro, con nome simbolico ACAPO


mov ah,2
mov dl, 13
int 21h
mov dl, 10
int 21h
ENDM ; terminazione del blocco macro

.MODEL TINY
.CODE
ORG 100h

START:
mov ah,02
mov dl,'0'
int 21h
ACAPO ; Uso della macro. In questo punto la macro ACAPO verr espansa nelle 5 istruzioni che la compongono
mov ah,02
mov dl,'1'
int 21h
ACAPO ; Uso della macro. Altre 5 istruzioni espanse
mov ah,02
mov dl,'0'
int 21h
ACAPO ; Uso della macro. Altre 5 istruzioni espanse
mov ah,02
mov dl,'1'
int 21h
int 20h
end START
OUTPUT
C:\>macapo
0
1
0
1
C:\>
S3Abacus Architetture/Asm .doc - 1684Kb - 08/mar/2011 - 69 / 84

MACRO CON PARAMETRI E ETICHETTE


Le macro di codice diventano veramente interessanti se utilizzate con parametri, ovvero se dotate di argomenti che possono essere variabili nel
momento delluso.
La seguente una macro che stampa un carattere sullo schermo, indicato al momento delluso:

STAMPACAR MACRO carattere


mov ah, 2
mov dl, carattere
int 21h
ENDM

Il suo uso e intuibile:

STAMPACAR P

Se invece una macro dovesse contenere una o pi etichette, si presenterebbe il problema delluso ripetuto delletichetta (cfr. Scrivere un
programma EXE), dato che la macro viene espansa nel codice del programma e il nome delletichetta verr ripetuto tante volte quante volte la
macro usata.
Per ovviare a questo problema si usa una direttiva dedicata L O C A L che consente di dichiarare le etichette utilizzate nella macro, lasciando il
compito allassemblatore di gestirne correttamente la ripetizione.

Direttiva LOCAL
Sintassi: LOCAL nome

Scopo: Impone allassemblatore di trasformare il simbolo nome usato in una macro in un simbolo univoco per ogni
espansione della macro.

Nota: La direttiva va posta allinizio del blocco di codice della macro.

Si osservi questo codice che acquisisce un carattere in input dopo aver mostrato un rudimentale prompt (?), e presenta una macro che stampa un
carattere, ma solo se numerico:

STAMPACARNUM MACRO regchar ; regchar il parametro della macro, un registro a 8bit


LOCAL NONOK ; letichetta NONOK deve essere dichiarata con la direttiva LOCAL
cmp regchar, '0'
jl NONOK
cmp regchar, '9'
jg NONOK
mov ah, 2
mov dl, regchar
int 21h
NONOK: ; la dichiarazione delletichetta impedisce lerrore di duplicazione, nel caso di pi usi della macro
ENDM

.MODEL TINY
.CODE
ORG 100h

START:
mov ah,2 ; stampa a video del carattere ? come prompt per linput
mov dl, '?'
int 21h
mov ah,0 ; input di un carattere da tastiera, senza echo. Il carattere digitato ritorna in AL
int 16h
STAMPACARNUM al ; AL il valore del parametro della macro
int 20h
end START
OUTPUT
C:\>mparam
?1
C:\>
(si digitato il carattere 1, che viene regolarmente stampato a schermo)
S3Abacus Architetture/Asm .doc - 1684Kb - 08/mar/2011 - 70 / 84

STACK
Solo con la programmazione assembly il programmatore pu utilizzare espressamente la zona di memoria dello Stack. Ricordiamo che tutti i
linguaggi ad alto livello usano lo Stack, ma in modo trasparente al programmatore, per allocare/deallocare le variabili locali, far transitare i parametri
alle procedure e gestire gli indirizzi di andata e ritorno delle subroutines.
Per velocizzare tutti questi processi, lo Stack assume la forma di una s t r u t t u r a d a t i a P i l a (o L I F O , Last In, First Out). Limmissione di un
valore nello stack si appoggia sullultimo valore presente nello stack, in modo tale che lultimo valore immesso, sempre in cima alla pila, sia
immediatamente accessibile. Per raggiungere i valori sotterrati nella pila necessario scaricare quelli che lo ricoprono, come quando si vuole
prendere un piatto in mezzo ad una pila di piatti.

Per gestire velocemente le operazioni di scrittura (inserimento) e lettura (prelevamento) dallo stack, lISA x-86 prevede istruzioni specifiche
(rispettivamente P U S H e P O P ) e automatismi specifici su alcuni registri: lo Stack Pointer SP contiene sempre e automaticamente lindirizzo
dellultimo elemento sulla cima dello stack.

Lo stack x-86 organizzato a word (due byte), ovvero ogni elemento in pila sempre ampio due byte.
Lo stack x-86 inizia (ha la base) sempre alla fine di un segmento di memoria, ovvero lindirizzo del primo elemento di uno stack ha sempre valore di
offset pari a FFFEh.
In altre parole, allavvio di un qualsiasi programma eseguibile (EXE o COM) il registro SP contiene sempre il valore FFFEh.
Ci significa che la pila dello stack x-86 cresce diminuendo gli indirizzi (dello Stack Pointer SP) di due unit alla volta per ogni elemento.
Questa scelta opportuna, dato che lo stack si amplia a runtime senza controllo: se si perde il controllo dello stack e lo si riempie indefinitamente
(S t a c k O v e r f l o w ), vengono sovrascritte locazioni di memoria del programma, ma non del Sistema Operativo.

Le istruzioni per la gestione esplicita dello stack sono:

Istruzione PUSH
Sintassi: PUSH sorgente

Scopo: Decrementa SP di due unit e pone sorgente sullo Stack allindirizzo contenuto in SP.

Esempi: PUSH AX PUSH 7 ; non per l8086, dal 80186+ PUSH [BX]

Nota: Nel primo caso il contenuto di AX viene posto sulla cima dello stack.
Sorgente non pu essere un valore immediato, almeno nell8086/88, ma pu essere una locazione di memoria,
purch ampia due byte

Istruzione POP
Sintassi: POP destinazione

Scopo: Preleva una word dallo Stack, dallindirizzo contenuto in SP, e la deposita in destinazione, quindi incrementa SP di
due unit.

Esempi: POP AX POP [BX] POP VAR

Nota: Nel primo caso, il valore a due byte in cima allo stack viene posto in AX.
Negli altri casi, il valore in cima allo stack viene posto direttamente in memoria, occupando due celle contigue a
partire dagli indirizzi contenuti, rispettivamente, in BX e VAR.

Altre istruzioni oramai necessarie per lo sviluppo del codice desempio, sono le principali istruzioni aritmetiche:

Istruzione ADD
Sintassi: ADD destinazione, sorgente

Scopo: Effettua la somma (anche con segno) tra destinazione e sorgente.


Il risultato viene collocato in destinazione.
destinazione non pu essere un immediato, ma pu essere una zona di memoria.

Esempi: ADD BX, 256 ADD BX, CX ADD VAR, 12

Istruzione SUB
Sintassi: SUB minuendo, sottraendo

Scopo: Sottrae da minuendo il sottraendo (anche con segno).


Il risultato viene collocato in minuendo.
minuendo non pu essere un immediato, ma pu essere una zona di memoria.

Esempi: SUB BX, 256 SUB BX, CX SUB VAR, 12


S3Abacus Architetture/Asm .doc - 1684Kb - 08/mar/2011 - 71 / 84

Istruzione MUL
Sintassi: MUL moltiplicatore

Scopo:
Effettua la moltiplicazione senza segno tra:
- AL e moltiplicatore, se moltiplicatore a 8 bit, oppure tra
- AX e moltiplicatore, se moltiplicatore a 16 bit.
Nel primo caso colloca in AX il risultato, nel secondo caso in DX:AX
moltiplicatore non pu essere un immediato, ma pu essere una cella di memoria.

Esempi: MUL CH MUL VAR MUL SI

Nota: Attenzione: se il risultato maggiore del contenitore, saranno impostati i flag di Overflow o di Carry, altrimenti
azzerati.

Istruzione DIV
Sintassi: DIV divisore

Scopo: Effettua la divisione senza segno tra:


- AX e divisore, se divisore a 8 bit, oppure tra
- DX:AX e divisore, se divisore a 16 bit.
Nel primo caso colloca in AL il quoziente e in AH il resto, nel secondo caso in AX il quoziente e in DX il resto.
divisore non pu essere un immediato, ma pu essere una cella di memoria.

Esempi: DIV BL DIV VAR DIV SI

Nota: Attenzione: se il quoziente non sta nel contenitore, avviene un errore di overflow o di divisione per zero.
Es., MOV AX,0A100; MOV BL,2; DIV BL; genera un errore perch A100h / 2 = 5080h, che non sta in un byte.

Si consulti ora questo codice, che stampa in binario il valore memorizzato nella variabile VAR allocata in memoria. Si usa listruzione DIV (divisione)
per memorizzare i resti delle divisioni per due, memorizzarli sullo stack, quindi riprenderli per stampare le cifre binarie.

.MODEL TINY
.CODE
ORG 100h

START:
jmp MAIN

VAR DW 00A1h ; area Dati; il valore VAR (A1h) sar convertito in binario

MAIN:
mov ax,VAR ; il dividendo in AX
mov bl,2 ; il divisore in BL
mov cx,0 ; conter il numero di divisioni, cio il numero di cifre binarie
ANCORA:
div bl ; divisione per 2, in AH il resto, in AL il risultato
push ax ; salvataggio del resto e del risultato sullo stack
inc cx ; conteggio del numero delle cifre binarie
mov ah,0 ; annullamento del resto, rimarr solo il risultato per la prossima divisione
cmp al,0 ; il risultato zero?
jne ANCORA ; se no, si continua la divisione per due
STAMPA:
pop dx ; si preleva dallo stack il valore, tra cui il resto della divisione per due
mov dl,dh ; si mette il resto (0 o 1) in DL per la stampa a schermo
add dl,'0' ; si aggiunge il codice Ascii dello zero per ottenere il codice Ascii del numero (0 o 1) corrispondente
mov ah,2
int 21h ; stampa a schermo della cifra binaria
loop STAMPA ; ancora cifre da stampare?
int 20h
end START

OUTPUT
C:\>bin
10100001
C:\>

Lo stack di questo programma si riempie nel seguente modo, a seguito di otto chiamate PUSH AX.
Nella colonna in grigio, i resti, a fianco i risultati

Stack SP valori Descrizione

ss:FFEE 0100 8va divisione: 01h / 2 = 00h, resto 1


S3Abacus Architetture/Asm .doc - 1684Kb - 08/mar/2011 - 72 / 84

ss:FFF0 0001 7ma divisione: 02h / 2 = 01h, resto 0


ss:FFF2 0102 6ta divisione: 05h / 2 = 02h, resto 1
ss:FFF4 0005 5ta divisione: 0Ah / 2 = 05h, resto 0
ss:FFF6 000A 4ta divisione: 14h / 2 = 0Ah, resto 0
ss:FFF8 0014 3za divisione: 28h / 2 = 14h, resto 0
ss:FFFA 0028 2da divisione: 50h / 2 = 28h, resto 0
ss:FFFC 0150 1ma divisione: A1h / 2 = 50h, resto 1
ss:FFFE 0000 Valore iniziale dello Stack Pointer

Bisogna ricordare che le operazioni sullo stack devono sempre essere b i l a n c i a t e , ovvero lo Stack Pointer (SP) deve sempre tornare al valore di
partenza alla fine del programma. Le istruzioni PUSH e POP, pertanto, devono essere eseguite lo stesso numero di volte.
S3Abacus Architetture/Asm .doc - 1684Kb - 08/mar/2011 - 73 / 84

PROCEDURE
Luso delle macro di codice semplifica notevolmente la scrittura dei programmi assembly ed vivamente consigliata. Un effetto collaterale delluso
delle macro di codice lespansione del codice sorgente e del codice eseguibile, cio il suo incremento in quantit. Ci significa anche maggior
memoria principale utilizzata. Le macro di codice, inoltre, rallentano il tempo di compilazione e, soprattutto, non possono adeguarsi circa situazioni
che avvengono solo a run time.
Una soluzione a questi problemi luso di p r o c e d u r e (o subroutines) che solo apparentemente svolgono un compito analogo alla macro.
Una procedura ancora un blocco di codice con un nome simbolico, ma stavolta il nome della procedura non un simbolo ma lindirizzo della sua
prima istruzione in memoria. Le procedure, infatti, sono allocate in memoria, in uno spazio privato, e devono essere chiamate a runtime dal
codice del programma (o da altre procedure).
Ci significa che il blocco di codice di una procedura non viene ripetuto nel sorgente ad ogni occorrenza del suo nome, ma solo usato dal
chiamante: il blocco di codice di una procedura unico e allocato in memoria, cio le procedure operano a runtime.
Le procedure, pertanto, non incrementano il codice sorgente ed eseguibile del programma, e quindi risparmiano anche nelluso della memoria
principale, rispetto alle macro di codice. Inoltre, operando a runtime, possono crearsi veri e propri ambienti autonomi di elaborazione, es. mediante
la creazione, sempre a runtime, di zone di memoria private, dette v a r i a b i l i l o c a l i .
Lunico effetto collaterale di una procedura, rispetto alle macro di codice, una maggior lentezza nellesecuzione, dato che il codice chiamante deve
preparare la memoria (di solito lo stack) per avviare la procedura, e la procedura, a sua volta, deve ripristinare la memoria al suo termine e prima di
ritornare al chiamante. Queste operazioni sono dette m e c c a n i s m o d i c h i a m a t a e ritorno della procedura.

DEFINIZIONE DI PROCEDURA
Le procedure vanno definite con una sintassi molto simile a quella delle macro di codice, anche se la collocazione delle procedure deve essere
posta necessariamente nellarea codice, prima del programma principale, o dopo.

PseudoIstruzione PROC / ENDP


Sintassi: nome PROC
(codice)
(RET)
ENDP

Scopo: Definisce il blocco di (codice) che sar chiamato tramite listruzione CALL nome. Al termine bisogna ridare il controllo
al chiamante con (RET)

Esempi: BEEP PROC ACAPO PROC


mov ah,2 mov ah,2
mov dl, 7 mov dl, 13
int 21h int 21h
ret mov dl, 10
ENDP Int 21h
ret
ENDP

Nota: I due esempi sono simili a quelli riportati nella sintassi delle direttive MACRO/ENDM, ma il blocco di codice termina
con listruzione RET per completare il meccanismo di chiamata.
Di fianco a PROC si pu aggiungere il modificatore F A R se la chiamata avviene da un segmento di codice differente
da quello che contiene la procedura (per i modelli di memoria MEDIUM, LARGE e HUGE)

Una procedura deve essere chiamata dal codice del programma e quindi deve ritornare al chiamante per consentirgli il regolare flusso di
esecuzione. LIsa x-86 preve due istruzioni caratteristiche per gestire il meccanismo di chiamata:

Istruzione CALL
Sintassi: CALL target

Scopo: Listruzione CALL esegue le seguenti operazioni:


1) salva nello stack li n d i r i z z o d i r i t o r n o ;
2) trasferisce il controllo alloperando target tramite un salto incondizionato.
Lindirizzo di ritorno lindirizzo dellistruzione successiva a quella di CALL.

Esempi: CALL ACAPO CALL word ptr [BX]

Nota: Nel primo caso la CALL ACAPO pu essere vista come lunione delle due PUSH IP; JMP ACAPO, ricordando che il
nome di una procedura il suo indirizzo in memoria. Nel secondo caso un esempio di chiamata dinamica, ovvero una
chiamata che assume valore solo a runtime (in base al valore attuale di BX). Word ptr serve per indicare
allassemblatore che la locazione puntata da BX riguarda due byte contigui a partire dallindirizzo contenuto in BX.

Istruzione RET
Sintassi: RET

Scopo: Listruzione RET assume che lindirizzo di ritorno si trovi attualmente in cima allo stack.
Essa esegue le seguenti operazioni:
1) preleva dallo stack dellindirizzo di ritorno
2) salto allindirizzo di ritorno.
S3Abacus Architetture/Asm .doc - 1684Kb - 08/mar/2011 - 74 / 84

Esempi: RET

Nota: La RET, che va sempre posta come ultima istruzione di un blocco di procedura, esegue, praticamente, le seguenti
istruzioni: POP indirizzoritorno/JMP indirizzoritorno, oppure, con una sola istruzione logica: POP IP

In entrambi i casi, se la procedura di tipo FAR cio si trova in un segmento di codice differente da quello del chiamante, sia CALL che RET,
invece di salvare/rileggere solo la parte offset dellindirizzo del program counter (indirizzo di ritorno su due byte), salvano e rileggono sia la parte seg
che la parte offset dellindirizzo (indirizzo di ritorno su quattro byte) in modo del tutto trasparente al programmatore.

MECCANISMO DI CHIAMATA
Si veda il seguente esempio che illustra il meccanismo di chiamata e ritorno di una procedura tramite lo stack.
La colonna in grigio mostra gli indirizzi effettivi delle righe di codice.

.MODEL TINY
.CODE
ORG 100h

START:
cs:0100 jmp MAIN ; Allavvio si deve saltare il codice delle procedure

ACAPO PROC ; La procedura deve stare nellarea di codice, ma deve essere saltata allavvio, cos come si salta larea Dati
cs:0103 mov ah,2
cs:0105 mov dl, 13
cs:0107 int 21h
cs:0109 mov dl, 10
cs:010B int 21h
cs:010D ret ; Listruzione RET necessaria per far funzionare il meccanismo di ritorno
ENDP

MAIN:
cs:010E mov ah,02
cs:0110 mov dl,'0'
cs:0112 int 21h
cs:0114 call ACAPO ; La procedura ACAPO deve essere chiamata esplicitamente con listruzione CALL, per garantire il ritorno
cs:0117 mov ah,02
cs:0119 mov dl,'1'
cs:011B int 21h
cs:011D int 20h
end START
OUTPUT
C:\>pacapo
0
1
C:\>

Lo stack del programma subisce il seguente movimento (tre passi, compreso lo stato iniziale):

Stack SP valori Descrizione

ss:FFFA ....
ss:FFFC ....
ss:FFFE 0000 Valore iniziale dello Stack Pointer

ss:FFFA ....
ss:FFFC 0117 Indirizzo di ritorno, sulla CALL ACAPO
ss:FFFE 0000 Valore iniziale dello Stack Pointer

ss:FFFA ....
ss:FFFC ....
ss:FFFE 0000 Dopo la RET nella procedura ACAPO

PRESERVARE I REGISTRI
Lutilizzo delle procedure comporta un effetto collaterale abbastanza grave, detto i n t e r f e r e n z a : i registri usati dalla procedura sovrascrivono il
contenuto precedentemente salvato in quei registri dal chiamante, con leffetto che al ritorno della procedura il chiamante non ritrova pi i valori
precedentemente salvati nei registri.
Per evitare linterferenza, la procedura deve preservare i registri in ingresso, ovvero salvare il contenuto dei registri che essa stessa user al suo
interno, salvandoli ordinatamente sullo stack, per poi ripristinarli ordinatamente appena prima di ritornare il controllo al chiamante (appena prima
dellistruzione RET).
La preservazione dei registri pu essere effettuata puntualmente, salvando sullo stack solo i registri usati dalla procedura, o in modo completo
sfruttando due apposite istruzioni x-86, PUSHA e POPA che, rispettivamente, salvano sullo stack e riprendono dallo stack tutti i registri (ma solo per
lx-86 a partire dall80186, con lesclusione, quindi, dell8086/88).

Il codice precedente, dotato di preservazione dei registri, appare come segue (loutput non cambia):
S3Abacus Architetture/Asm .doc - 1684Kb - 08/mar/2011 - 75 / 84

.MODEL TINY
.CODE
ORG 100h

START:
jmp MAIN

ACAPO PROC
push ax ; si preservano i soli registri AX e DX, gli unici usati dalla procedura, inviandoli sullo stack
push dx
mov ah,2
mov dl, 13
int 21h
mov dl, 10
int 21h
pop dx ; si ricaricano i registri preservati, in ordine inverso, per restituirli invariati al chiamante
pop ax
ret
ENDP

MAIN:
mov ah,02
mov dl,'0'
int 21h
call ACAPO
mov ah,02
mov dl,'1'
int 21h
int 20h
end START
OUTPUT
C:\>pacapo
0
1
C:\>
S3Abacus Architetture/Asm .doc - 1684Kb - 08/mar/2011 - 76 / 84

PASSAGGIO DI PARAMETRI
Le procedure diventano realmente fondamentali quando permettono il passaggio dei parametri, ovvero possono svolgere il proprio compito sulla
base di valori che il chiamante decide a runtime.
In realt si gi usato un sistema di passaggio di parametri, ad esempio durante luso delle interruzioni sw: valorizzare un registro prima della
chiamata allistruzione INT significa passare t r a m i t e r e g i s t r o un parametro alla routine dellinterruzione sw.
Il passaggio dei parametri tramite registri molto veloce e semplice, ma ha molte limitazioni, prima di tutto la quantit dei registri disponibili.
Le procedure, per linguaggi ad alto e a basso livello come lassembly, usano in realt lo stack per passare i parametri e, quando serve, per ritornarli
al chiamante.
Lidea semplice: il chiamante, prima di chiamare la procedura con la consueta istruzione CALL, deposita sullo stack i valori che intende passare
alla procedura. La procedura, prima di iniziare il suo compito, preleva dallo stack i parametri e li usa al suo interno.
Per ritornare valori dalla procedura al chiamante, si usa lo stesso meccanismo.
In questo caso il passaggio di parametri si dice t r a m i t e l o s t a c k .

Il passaggio di parametri tramite lo stack deve tener presente che, sullo stack, come ultimo valore, verr sempre posto lindirizzo di ritorno della
procedura ad opera dellistruzione CALL. Pertanto la procedura dovr prelevare i parametri senza eliminare dalla cima dello stack lindirizzo di
ritorno, che dovr essere usato dallistruzione RET per ritornare correttamente al chiamante.

Esistono varie tecniche per passare i parametri sullo stack. Le pi diffuse prendono il nome di c d e c l (usata dal linguaggio C e derivati) e s t d c a l l
(usata dal linguaggio Pascal e dalle API di alcuni SO).
In questa sezione vedremo un passaggio di parametri alle procedure abbastanza simile allo stile del C o cdecl, che usa il registro BP (Base Pointer)
per prelevare i dati sullo stack senza modificare il registro SP (Stack Pointer). Si ricorda che il registro BP ha la propriet di indirizzare in memoria,
cio di contenere indirizzi di memoria.

1. Prima di tutto il chiamante deve porre nello stack i parametri richiesti dalla procedura. Loperazione si effettua con la consueta istruzione
PUSH, ripetuta tante volte quanti sono i parametri da passare.
2. Quindi si effettua la chiamata normalmente, con listruzione CALL. Essa immetter sulla cima dello stack, come di consueto, lindirizzo di
ritorno.
3. La procedura, a sua volta, deve immediatamente salvare sullo stack il registro BP, dato che verr usato e sovrascritto per prelevare i
parametri.
4. Quindi il registro BP deve essere impostato con il valore dello Stack pointer SP, mediante una istruzione MOV: in questo modo BP punta
alla cima dello stack.
5. Ora i parametri possono essere prelevati uno a uno tramite BP, avendo cura di ricordare che il primo parametro profondo 4 byte nello
stack: infatti i primi due byte in cima alla pila riportano il valore di BP (appena memorizzato), e i successivi due byte riportano il valore
dellindirizzo di ritorno. Ogni parametro si scosta di due byte, pertanto a BP+4 corrisponde il valore del primo parametro, a BP+6 il valore
del secondo parametro, a BP+8 il valore del terzo parametro, e cos via.
6. Ora pu essere scritto il codice della procedura, comprese le eventuali istruzioni per preservare i registri.
7. Infine, appena prima dellistruzione RET, va ripristinato il registro BP, che se tutto stato svolto correttamente, si trova attualmente in cima
allo stack. Una volta prelevato il valore originale di BP, lindirizzo di ritorno disponibile in cima alla pila per listruzione RET.
8. Il chiamante, quando riprende il controllo, si ritrova i parametri ancora sullo stack, per cui deve ripristinare lo stato dello stack
deallocandoli, cio facendo tornare lo Stack Pointer SP al valore originario. Ci semplice, tramite una istruzione ADD: si aggiungono allo
Stack Pointer tante doppiette quanti sono i parametri (es., per 3 parametri: ADD SP,6). Una delle maggiori differenze tra la tecnica cdecl
e stdcall consiste nel fatto che cdecl impone che sia il chiamante a deallocare i parametri dallo stack, mentre in stdcall la procedura a
farlo.

Bisogna ricordare che il salvataggio immediato di BP e il suo successivo ripristino, fondamentale bench BP non sia di norma usato dai moduli
che chiamano le procedure. Infatti una procedura pu e spesso lo fa, chiamarne unaltra al suo interno (c h i a m a t a a n n i d a t a ), alla quale
passare parametri. Se BP non fosse preservato, le chiamate annidate non funzionerebbero.

Il seguente codice usa una procedura a cui viene passato sullo stack il codice Ascii da stampare a schermo. Siccome lo stack usa elementi a 16 bit,
il codice Ascii (8bit) viene enucleato nella parte bassa del registro AX, che e a 16 bit.

.MODEL TINY
.CODE
ORG 100h

START:
cs:0100 jmp MAIN

STAMPACAR PROC
cs:0103 push bp ; si preserva BP sullo stack, come prima istruzione della procedura
cs:0104 mov bp,sp ; si memorizza lo stack Pointer in BP, in modo che BP possa servire pre reperire il parametro
cs:0106 mov dx,[bp+4] ; ecco il parametro, profondo 4 byte dentro lo stack (il codice Ascii del ?)
cs:0109 mov ah,2
cs:010B int 21h
cs:010D pop bp ; ripristino di BP. Ora sullo stack c lindirizzo di ritorno, cos che RET funzioni a dovere
cs:010E ret
ENDP

MAIN:
cs:010F mov al,'?'
cs:0112 push ax ; passaggio del parametro sullo stack (il codice Ascii del ?, in AL allinterno di AX)
cs:0113 call STAMPACAR
cs:0116 add sp,2 ; deallocazione dello stack. Un parametro, una doppietta
cs:0119 int 20h
S3Abacus Architetture/Asm .doc - 1684Kb - 08/mar/2011 - 77 / 84

end START
OUTPUT
C:\>pparam
?
C:\>

Seguendo il listato del programma, si pu seguire landamento dello stack per ogni istruzione che lo modifica implicitamente (come CALL e RET) o
esplicitamente come PUSH, POP e ADD SP,2.

Stack SP valori Descrizione

ss:FFF8 ....
ss:FFFA ....
ss:FFFC ....
ss:FFFE 0000 Valore iniziale dello Stack Pointer

ss:FFF8 ....
ss:FFFA ....
ss:FFFC 003F PUSH AX; 3Fh il codice Ascii del carattere ?
ss:FFFE 0000 Valore iniziale dello Stack Pointer

ss:FFF8 ....
ss:FFFA 0116 CALL STAMPACAR; 116h lindirizzo di ritorno
ss:FFFC 003F PUSH AX
ss:FFFE 0000 Valore iniziale dello Stack Pointer

ss:FFF8 0000 PUSH BP; in BP cera il valore 0


ss:FFFA 0116 CALL STAMPACAR
ss:FFFC 003F PUSH AX
ss:FFFE 0000 Valore iniziale dello Stack Pointer

Nella procedura ora si pone in BP lo Stack Pointer, con mov bp,sp, cio BP = FFF8h.
Allindirizzo BP + 4 = FFFCh, c lindirizzo del parametro sullo stack, cosicch mov dx,[bp+4] pone in DX il valore 003Fh, cio in DL il
codice Ascii (3Fh) del punto interrogativo.

ss:FFF8 0000 POP BP; ripristinato BP (0000h)


ss:FFFA 0116
ss:FFFC 003F
ss:FFFE 0000

ss:FFF8 0000
ss:FFFA 0116 RET; caricato lindirizzo di ritorno (0116h)
ss:FFFC 003F
ss:FFFE 0000

ss:FFF8 ....
ss:FFFA ....
ss:FFFC ....
ss:FFFE 0000 ADD SP, 2 e valore iniziale dello Stack Pointer
S3Abacus Architetture/Asm .doc - 1684Kb - 08/mar/2011 - 78 / 84

VARIABILI LOCALI
Una delle propriet fondamentali delle procedure la possibilit di crearsi un ambiente di memoria privato con il quale interagire per completare
compiti anche abbastanza articolati. Larea di memoria privata di una procedura allocata sullo stack e deallocata appena prima del ritorno al
chiamante.
Le variabili che prendono posto nellarea privata delle procedure sono dette v a r i a b i l i l o c a l i o v a r i a b i l i a u t o m a t i c h e .

Come visto in precedenza, una volta preso il controllo, una procedura memorizza la cima dello stack in BP per poter prelevare eventuali parametri
sotterrati nella pila.
Per creare memoria alle variabili locali, bisogna invece estendere lo stack al di sopra della cima, di tante doppiette quante sono le variabili locali da
creare. Cos, utilizzando sempre BP come base, si raggiungeranno le variabili locali con sottrazioni di doppiette: in BP-2 ci sar lindirizzo della
prima variabile locale, in BP-4 lindirizzo della seconda, in BP-6 lindirizzo della terza, e cos via.
Al termine, larea delle variabili locali deve essere deallocata dalla procedura, riportando lo stack Pointer al suo valore originale.

1. La procedura, dopo aver memorizzato in BP la cima dello stack, lo amplia opportunamente sottraendo allo Stack Pointer SP tante
doppiette quante sono le variabili locali da usare, es. SUB SP,4, alloca due variabili locali da due byte luna (o quattro variabili locali da un
byte luna).
2. Ora la procedura pu scrivere nella variabile locale con la consueta MOV, indicando lindirizzo della variabile tramite BP, es. MOV [BP-2],
AX, mette nella prima variabile locale il valore del registro AX
3. Allo stesso modo la procedura pu leggere le variabili locali, usando sempre BP per indirizzarle, es. MOV DL, byte ptr [BP-4] pone nel
registro DL la variabile locale di ampiezza un byte dalla seconda area di memoria allocata sullo stack.
4. Al termine, la zona delle variabili locali viene deallocata riportando lo Stack pointer SP al valore originale che ora contenuto in BP (es.
MOV SP, BP).

Come esempio vediamo una versione di listato molto simile a quello usato per il passaggio di un parametro. In questo caso si passa alla procedura
una cifra ed essa ne stamper il simbolo Ascii sullo schermo, dopo aver usato una variabile locale per memorizzare la base dei codici Ascii
numerici, cio il codice Ascii di zero (30h):

.MODEL TINY
.CODE
ORG 100h

START:
cs:0100 jmp MAIN

STAMPANUM PROC
cs:0103 push bp ; consueta predisposizione dello stack frame per il prelevamento del parametro
cs:0104 mov bp,sp
cs:0106 mov dx,[bp+4]
cs:0109 sub sp,2 ; allocazione della variabile locale
cs:010C mov byte ptr [bp-2],30h ; scrittura della variabile locale, con il valore 30h
cs:0110 add dx,[bp-2] ; lettura della variabile locale, tramite listruzione ADD. Si somma il codice Ascii dello zero per ottenere il simbolo
cs:0113 mov ah,2
cs:0115 int 21h
cs:0117 mov sp,bp ; deallocazione della variabile locale
cs:0119 pop bp
cs:011A ret
cs:0113 ENDP

MAIN:
cs:011B mov al,9 ; preparazione del parametro, in questo caso il numero nove (e non il suo codice Ascii)
cs:011E push ax ; passaggio del parametro sullo stack
cs:011F call STAMPANUM
cs:0122 add sp,2 ; deallocazione dello stack
cs:0125 int 20h
end START

OUTPUT
C:\>varloc
9
C:\>

Seguendo il listato del programma, si pu seguire landamento dello stack allatto dellallocazione e deallocazione dellarea di memoria locale:

Stack SP valori Descrizione

ss:FFF6 ....
ss:FFF8 ....
ss:FFFA ....
ss:FFFC ....
ss:FFFE 0000 Valore iniziale dello Stack Pointer

ss:FFF6 ....
ss:FFF8 ....
ss:FFFA ....
S3Abacus Architetture/Asm .doc - 1684Kb - 08/mar/2011 - 79 / 84

ss:FFFC 0009 PUSH AX; 9h il codice Ascii del carattere zero


ss:FFFE 0000 Valore iniziale dello Stack Pointer

ss:FFF6 ....
ss:FFF8 ....
ss:FFFA 0122 CALL STAMPANUM; 122h lindirizzo di ritorno
ss:FFFC 0009 PUSH AX
ss:FFFE 0000 Valore iniziale dello Stack Pointer

ss:FFF6 ....
ss:FFF8 0000 PUSH BP; in BP cera il valore 0
ss:FFFA 0122 CALL STAMPANUM
ss:FFFC 0009 PUSH AX
ss:FFFE 0000 Valore iniziale dello Stack Pointer

ss:FFF6 .... SUB SP, 2; spostando SP di due unit, si alloca un elemento sullo stack
ss:FFF8 0000 PUSH BP; in BP cera il valore 0
ss:FFFA 0122 CALL STAMPANUM
ss:FFFC 0009 PUSH AX
ss:FFFE 0000 Valore iniziale dello Stack Pointer

ss:FFF6 ..30 MOV byte ptr [bp-2],30h; si scrive nella variabile locale
ss:FFF8 0000 PUSH BP; in BP cera il valore 0
ss:FFFA 0122 CALL STAMPANUM
ss:FFFC 0009 PUSH AX
ss:FFFE 0000 Valore iniziale dello Stack Pointer

ss:FFF6 ..30 ADD DX,[bp-2]; si legge nella variabile locale


ss:FFF8 0000 PUSH BP; in BP cera il valore 0
ss:FFFA 0122 CALL STAMPANUM
ss:FFFC 0009 PUSH AX
ss:FFFE 0000 Valore iniziale dello Stack Pointer

ss:FFF6 ..30 questa locazione ora non pi valida


ss:FFF8 0000 MOV SP, BP; si dealloca la variabile locale ripristinando lo Stack Pointer
ss:FFFA 0122 CALL STAMPANUM
ss:FFFC 0009 PUSH AX
ss:FFFE 0000 Valore iniziale dello Stack Pointer

ss:FFF6 ..30
ss:FFF8 0000 POP BP; ripristinato BP (0000h)
ss:FFFA 0122
ss:FFFC 0009
ss:FFFE 0000

ss:FFF6 ..30
ss:FFF8 0000
ss:FFFA 0122 RET; caricato lindirizzo di ritorno (0116h)
ss:FFFC 0009
ss:FFFE 0000

ss:FFF6 ....
ss:FFF8 ....
ss:FFFA ....
ss:FFFC ....
ss:FFFE 0000 ADD SP, 2 e valore iniziale dello Stack Pointer

NOTAZIONI PER IL PASSAGGIO DI PARAMETRI E LE VARIABILI LOCALI


Per rendere il codice assembly pi leggibile e semplice da utilizzare, spesso conveniente utilizzare uno stile che fa uso di qualche macro costante
per poter servirsi di nomi simbolici al posto delle notazioni che indirizzano brutalmente lo Stack, sia per quanto riguarda la gestione dei parametri,
che la gestione delle variabili locali.

In questo modo il listato precedente assume la seguente forma (il programma eseguibile assolutamente identico):

.MODEL TINY
.CODE
ORG 100h

START:
jmp MAIN

STAMPANUM PROC
Parametro EQU word ptr [BP+4] ; Il nome simbolico Parametro equivale alla zona dello stack che contiene il primo parametro
Variabile EQU byte ptr [BP-2] ; Il nome simbolico Variabile equivale alla zona dello stack che contiene la prima variabile locale

push bp
mov bp,sp
mov dx,Parametro ; Uso del nome simbolico Parametro per recuperare il parametro
S3Abacus Architetture/Asm .doc - 1684Kb - 08/mar/2011 - 80 / 84

sub sp,2
mov Variabile,30h ; Uso del nome simbolico Variabile per scrivere la variabile locale
add dx,Variabile ; Uso del nome simbolico Variabile per leggere la variabile locale
mov ah,2
int 21h
mov sp,bp
pop bp
ret
ENDP

MAIN:
mov al,9
push ax
call STAMPANUM
add sp,2
int 20h
end START
S3Abacus Architetture/Asm .doc - 1684Kb - 08/mar/2011 - 81 / 84

DIRETTIVE PER LA PROGRAMMAZIONE E


LIBRERIE
Per una efficiente programmazione assembly, necessario utilizzare alcune direttive allassemblatore per superare alcuni limiti architetturali come
il problema della distanza tra etichetta e riferimento per i salti condizionati o per rendere pi agevole la scrittura dei programmi come ad esempio
evitare di pianificare luso univoco dei nomi delle etichette.
Inoltre fondamentale conoscere il modo in cui pi moduli sorgenti concorrono per generare un file eseguibile, tecnica necessaria per i progetti sw
che intendono avvalersi di moduli di libreria.

SALTI LUNGHI, DIRETTIVA JUMPS


Per evitare di incorrere nel problema del salto lungo, cio quando la distanza tra riferimento e etichetta supera i 128 bytes, sufficiente citare una
direttiva iniziale allassemblatore, la direttiva J U M P S :

Direttiva JUMPS
Sintassi: JUMPS

Scopo: Impone allassemblatore di trasformare il codice di eventuali salti a distanze superiori di 128 bytes, in un codice
equivalente in grado di superare tale limite ed effettuare anche salti lunghi.

Nota: La direttiva va posta allinizio del modulo sorgente, subito dopo la direttiva che indica linizio dellarea Codice
(.CODE). Spesso si usa anche quando non si certi della presenza di salti lunghi nel codice. La direttiva vale solo
per lassemblatore TASM.

La direttiva JUMPS si limita a trasformare il salto condizionato in una struttura di salto che utilizza un salto incondizionato JMP come supporto per
raggiungere letichetta distante pi di 128 byte dal suo riferimento. Infatti listruzione di salto incondizionato JMP non ha limiti di distanza tra
riferimento e etichetta.

DUPLICAZIONE DI ETICHETTE, DIRETTIVA LOCALS


Allinterno delle procedure spesso si vorrebbero usare etichette con nomi uguali in procedure diverse, soprattutto per indicare zone logiche del
codice equivalenti (es. FINE, OK, ecc.). Questo genera un errore dellassemblatore, che necessita di nomi univoci per le etichette in tutta larea di
Codice. Per evitare di pianificare uno schema di naming univoco per le etichette da usare nelle procedure, si pu usare una direttiva speciale
(L O C A L S ) e una notazione che rendono libero il programmatore nella scelta dei nomi:

Direttiva LOCALS
Sintassi: LOCALS

Scopo: Impone allassemblatore di trasformare le etichette scritte con un prefisso speciale @@nome univoche aldil della
rimanente parte del nome

Nota: La direttiva va posta allinizio del modulo sorgente, subito dopo la direttiva che indica linizio dellarea Codice
(.CODE).
La direttiva vale solo per lassemblatore TASM.

In definitiva, un codice che usa tali direttive, e che stampa due stringhe con due procedure analoghe, il seguente:

.MODEL TINY
.CODE
JUMPS ; Direttiva per evitare il limite del salto lungo (in questo codice per non ce ne sono)
LOCALS ; Direttiva per usare etichette con nomi uguali (tramite il prefisso @@)
ORG 100h

START:
jmp MAIN

MSG_1 DB "Sistemi Abacus",0 ; Stringa ASCIIZ (termina con uno zero)


MSG_2 DB "Classe 3a$" ; Stringa che termina con il carattere speciale $ (come nel servizio MsDos)

PROC STAMPAASCIIZ ; procedura che stampa a schermo stringhe ASCIIZ (indirizzo passato sullo stack)
push bp
mov bp,sp
mov bx,[bp+4]
@@ANCORA: ; ecco le etichette con il prefisso @@ che consentono nomi uguali in accordo con LOCALS
mov dl,[bx]
cmp dl,0
je @@FATTO
mov ah,2
int 21h
inc bx
jmp @@ANCORA
S3Abacus Architetture/Asm .doc - 1684Kb - 08/mar/2011 - 82 / 84

@@FATTO:
pop bp
ret
ENDP

PROC STAMPADOLLARO ; procedura che stampa a schermo stringhe terminanti con $ (indirizzo passato sullo stack)
push bp
mov bp,sp
mov bx,[bp+4]
@@ANCORA: ; ecco le etichette con il prefisso @@ che consentono nomi uguali in accordo con LOCALS
mov dl,[bx]
cmp dl,'$'
je @@FATTO
mov ah,2
int 21h
inc bx
jmp @@ANCORA
@@FATTO:
pop bp
ret
ENDP

MAIN:
lea ax,msg_1
push ax
call STAMPAASCIIZ
add sp,2

mov ah,2
mov dl, 10
int 21h

lea ax,msg_2
push ax
call STAMPADOLLARO
add sp,2

int 20h
end START

OUTPUT
C:\>jumpslcl
Sistemi Abacus
Classe 3a
C:\>

LIBRERIE, DIRETTIVE INCLUDE, PUBLIC ED EXTRN


Come per i linguaggi ad alto livello, programmare in assembly diventa veramente proficuo quando si possono usare moduli di l i b r e r i a , cio files
sorgenti o binari che contengono procedure o definizioni di utilit generale, utilizzabili nei programmi senza dover, ogni volta, riscrivere la soluzione
di problemi gi risolti.
Lo sviluppo dei programmi con lo stile del p r o g e t t o e tramite moduli di libreria una pratica oramai consolidata nel mondo della programmazione.
Un progetto linsieme di pi moduli sorgenti (a volte anche moduli binari), di cui uno solo contiene il punto di ingresso del programma e, tutti gli
altri, sono detti moduli di libreria. La compilazione di un progetto la compilazione di ogni modulo, e la loro unione tramite linker nel t a r g e t del
progetto, solitamente un file eseguibile.
Naturalmente un progetto deve affrontare il problema dei rapporti tra i moduli i quali possono essere, alternativamente, sia c l i e n t che s e r v e r di
funzioni presenti in altri moduli: sono client se citano elementi presenti in altri moduli; sono server se contengono definizioni citate da altri moduli.
Il modulo principale, invece, lunico che sempre e solo un modulo client.

Il modo pi semplice per realizzare il rapporto tra il modulo principale e altri moduli server tramite la direttiva I N C L U D E .
Con questa direttiva, usata dal modulo principale, si indica allassemblatore di aprire da disco il file argomento della direttiva (modulo server) ed
espanderlo nel modulo principale (modulo client) cos com a partire dalla posizione in cui si trova la direttiva INCLUDE nel modulo principale. Il
processo del tutto paragonabile a quello di una macro di codice. In questo caso la libreria (modulo server) detta l i b r e r i a d i c o d i c e .

Direttiva INCLUDE
Sintassi: INCLUDE nomefile

Scopo: Impone allassemblatore di cercare il file nomefile, aprirlo ed espanderlo riga per riga nella posizione corrente.

Nota: La direttiva pu essere posta in qualsiasi zona del sorgente; il nome del file pu essere indicato anche con il
percorso. Solitamente i files assembly dinclusione hanno estensione .INC.

mainincl.asm acapo.inc
modulo client (principale) modulo server (libreria di codice)
S3Abacus Architetture/Asm .doc - 1684Kb - 08/mar/2011 - 83 / 84

.MODEL TINY CR EQU 13


.CODE LF EQU 10
ORG 100h
ACAPO PROC
START: mov ah,2
jmp MAIN mov dl, CR
int 21h
INCLUDE acapo.inc ; qui sar espanso il file acapo.inc mov dl, LF
int 21h
MAIN: ret
mov ah,02 ENDP
mov dl,'0'
int 21h
call ACAPO
mov ah,02
mov dl,'1'
int 21h
int 20h
end START

Il progetto si compila come se fosse composto da un unico file, il file principale (mainincl.asm). Il file server acapo.inc deve essere raggiungibile
(nellesempio, nella cartella corrente):

C:\>tasm mainincl
C:\>tlink mainincl /t
C:\>mainincl
0
1
C:\>

Pi spesso il programmatore usa librerie binarie, ovvero moduli server che vengono assemblati autonomamente e collegati ai moduli client durante
la fase di linking.
I moduli client devono dichiarare in testa al codice quali simboli tratti da moduli esterni verranno usati (direttiva E X T R N ), in modo che
lassemblatore non cada in errore incontrando simboli mai definiti.
A sua volta il server deve dichiarare quali simboli possono essere utilizzati da altri moduli (direttiva P U B L I C ) in modo che lassemblatore e il linker
sappia come effettuare il collegamento.

Direttiva EXTRN
Sintassi: EXTRN nome:tipo

Scopo: Indica allassemblatore che un certo simbolo nome non definito nel modulo sorgente attuale, bens in uno esterno.
tipo pu essere NEAR o FAR se nome il nome di una procedura; pu essere BYTE o WORD se nome letichetta
in unarea dati.

Nota: La direttiva pu essere posta in testa al modulo client, per mettere in evidenza la lista di simboli esterni al sorgente,
detti anche d i p e n d e n z e .
Per quanto riguarda i nomi delle procedure, il tipo sempre NEAR se il modello di memoria scelto TINY, SMALL e
COMPACT; FAR negli altri casi.
Ogni direttiva EXTRN dovrebbe essere associata ad una duale direttiva PUBLIC contenuta in un modulo esterno.

Direttiva PUBLIC
Sintassi: PUBLIC nome

Scopo: Indica allassemblatore che un certo simbolo nome pu essere utilizzato da moduli esterni.

Nota: La direttiva pu essere posta in testa al modulo server, per mettere in evidenza la lista di simboli pubblici che il
modulo offre ai moduli client.
Naturalmente ogni nome in ogni direttiva PUBLIC del modulo deve corrispondere ad una effettiva etichetta nel
modulo (funzione o dato).

Lo stesso progetto di poco fa, implementato con libreria binaria:

mainlib.asm libreria.asm
(modulo client principale) (modulo server di libreria)

EXTRN ACAPO: NEAR PUBLIC ACAPO

.MODEL TINY .MODEL TINY


.CODE .CODE
ORG 100h
ACAPO PROC
START: mov ah,2
mov ah,02 mov dl, 13
mov dl,'0' int 21h
S3Abacus Architetture/Asm .doc - 1684Kb - 08/mar/2011 - 84 / 84

int 21h mov dl, 10


call ACAPO int 21h
mov ah,02 ret
mov dl,'1' ACAPO ENDP
int 21h end
int 20h
end START

In questo caso il processo di compilazione radicalmente differente rispetto alluso delle libreire sorgenti tramite la direttiva INCLUDE.
I due moduli sono assemblabili autonomamente, e danno luogo a due files oggetto .OBJ.

Sar il linker a effettuare il collegamento tra i due moduli binari, come dalla seguente sintassi:

C:\>tasm mainlib ; assemblaggio modulo client (principale). Genera mainlib.obj


C:\>tasm libreria ; assemblaggio modulo server (libreria). Genera libreria.obj
C:\>tlink mainlib libreria /t ; correlazione (linking) dei moduli. Genera mainlib.exe
C:\>mainlib
0
1
C:\>

MAKEFILE
Nel caso della compilazione di progetti con librerie binarie, risulta molto utile utilizzare lutility M A K E in dotazione con Borland C (file MAKE.EXE).
Il programma Make accetta in input un file di testo provvisto delle regole di compilazione di un progetto, ed esegue ordinatamente tutti i passi
necessari per la sua compilazione, assemblando i vari moduli sorgenti (client e server) e linkandoli adeguatamente.
Un makefile quindi un file di testo scritto con una determinata sintassi, spesso di nome makefile (senza estensione), che viene dato in input al
programma make.exe.
Se il processo esente da errori, loutput di make sar il file target (solitamente un file eseguibile) e tutti i files intermedi del caso (solitamente
files .obj).

Il makefile mainlib.mak per il progetto precedente, risulterebbe quindi come il seguente (le righe che iniziano con # sono commenti):

#uso: make f mainlib.mak

.AUTODEPEND

mainlib.exe:
TLINK mainlib.obj libreria.obj /t

libreria.obj: libreria.asm
TASM libreria.ASM,libreria.OBJ

mainlib.obj: mainlib.asm
TASM mainlib.ASM,mainlib.OBJ

Il processo di make, infine, si avvia nel seguente modo:

C:\>make -f mainlib.mak
MAKE Version 3.6 Copyright (c) 1992 Borland International
Available memory 15728640 bytes

TLINK mainlib.obj libreria.obj /t


Turbo Link Version 5.1 Copyright (c) 1992 Borland International
C:\>

Non il caso di approfondire il discorso sui makefile, che non rientra negli obiettivi di questo testo. In ogni caso si tratta di un argomento di grande
importanza per tutti i linguaggi di programmazione, anche ad alto livello.

Potrebbero piacerti anche