Sei sulla pagina 1di 26

Appunti di CALCOLATORI ELETTRONICI 1

CAPITOLO 1 - ARCHITETTURA DEI CALCOLATORI

1.1 - GENERALITA’
Il corso si occupa di calcolatori elettronici digitali, ossia di macchine in grado di eseguire
operazioni aritmetiche e logiche su dati rappresentati in forma discreta, costruite utilizzando
“prevalentemente” componenti elettronici. La definizione fa trasparire l’esistenza di
calcolatori non elettronici (per es. meccanici) e non digitali (i cosiddetti calcolatori analogici,
che operano su dati rappresentati in forma non discreta ma continua).
Quando si fa riferimento al loro uso in specifiche applicazioni i calcolatori elettronici digitali
sono anche denominati sistemi per l’elaborazione dell’informazione. Nel corso si usera’
per brevita’ il termine calcolatori.
L’architettura dei calcolatori a sua volta si occupa delle relazioni che intercorrono tra le
varie parti di un calcolatore.

Un calcolatore e’ chiamato a compiere cinque funzioni basilari, originate dall’esecuzione dei


programmi per esso predisposti: acquisizione di dati, memorizzazione di dati, elaborazione di
dati, presentazione di risultati, controllo del funzionamento globale.
Di conseguenza in un calcolatore si possono individuare i seguenti blocchi fondamentali (fig.
1.1):
• Unità centrale
E’ il blocco nel quale avviene l’elaborazione dei dati e che coordina il funzionamento di
tutti i blocchi. E’ possibile scomporlo in una unità di controllo e in una ALU (Arithmetic
Logic Unit o Unità aritmetico-logica). L’unità di controllo gestisce la sequenza delle
operazioni che il calcolatore deve compiere, l’ALU ha il compito di eseguirle.
L’unita’ centrale e’ anche denominata CPU (che sta per Central Processing Unit) ed e’
denotata con Pc (che sta per Processore centrale).
• Memoria
E’ la parte del sistema in cui sono memorizzati i programmi e i dati e puo’ essere
realizzata con componenti di vari tipi.
• Dispositivi d’ingresso e dispositivi d’uscita
Sono anche chiamati dispositivi di I/O e sono costituiti dalle apparecchiature che
servono rispettivamente per acquisire dall’esterno i dati da elaborare e per fornire
all’esterno i risultati delle elaborazioni.

I blocchi sono interconnessi per mezzo di opportuni collegamenti fisici. La figura illustra i
percorsi seguiti dai dati (che comprendono sia le istruzioni dei programmi sia i dati in senso
stretto richiesti dalla loro esecuzione) ed i collegamenti lungo i quali “viaggiano” i segnali di
controllo che gestiscono il corretto funzionamento del calcolatore.

Nei calcolatori attuali, al fine di ottenere una maggiore flessibilità del sistema, i collegamenti
fra i vari blocchi sono attuati tramite un BUS, il quale permette una maggiore modularità
(fig. 1-2).

Capitolo 1 1.1
Appunti di CALCOLATORI ELETTRONICI 1

UNITA’ CENTRALE

SEGNALI DI CONTROLLO SEGNALI DI CONTROLLO

UNITA’ DI
CONTROLLO

DATI ALU DATI

SEGNALI DI
INDIRIZZI DATI CONTROLLO

DISPOSITIVI DISPOSITIVI
DI MEMORIA DI
INGRESSO USCITA
DATI DATI

Figura 1-1. Blocchi funzionali di un calcolatore elettronico

Unità centrale
Dati, Controlli,
Indirizzi

BUS

Dispositivi Dispositivi
di Memoria di
ingresso uscita

Figura 1-2. Collegamento tra i blocchi funzionali a mezzo bus

1.2 - CLASSIFICAZIONE DEI CALCOLATORI


E’ possibile effettuare una classificazione dei calcolatori per impieghi generici in base alle
loro caratteristiche:
• Supercalcolatori (o Super computer)
Capitolo 1 1.2
Appunti di CALCOLATORI ELETTRONICI 1

Sono calcolatori molto specializzati, per lo piu’ con poca dotazione di software e progettati
per svolgere operazioni matematiche molto velocemente.
• Mainframe
Sono calcolatori molto potenti utilizzati per collegare molti utenti dotati di terminali con
interfaccia grafica semplice. Attualmente si tende ad utilizzarli prevalentemente per
gestire grosse basi di dati.
• Minicalcolatori
Sono calcolatori che gestiscono un certo numero di utenti (10 -100). Sono per lo piu’
utilizzati come server e gli utenti collegati hanno una interfaccia grafica di tipo più
raffinato che nel caso dei mainframe.
• Workstation
Sono minicalcolatori dedicati ad un solo utente e dotati di un’interfaccia grafica ad alte
prestazioni.
• Personal computer
Sono calcolatori simili alle workstation ma con prestazioni ridotte.

L’unità centrale è per lo piu’ realizzata utilizzando uno o piu’ microprocessori.

1.3 - PRESTAZIONE DI UN CALCOLATORE


Nel caso il sistema di elaborazione abbia collegato a sé più utenti, ad esempio 3, è possibile
rappresentarne l’utilizzo nel tempo come in fig. 1-3.
Il calcolatore mette a disposizione di ogni utente collegato un certo intervallo di tempo che
viene utilizzato per eseguire le operazioni da esso richieste. Alla fine di tale intervallo passa
ad eseguire le operazioni richieste da un altro utente. Nei casi più complessi la durata
dell’intervallo di tempo assegnato può variare da utente a utente, oppure possono esistere
priorità per le operazioni di un utente rispetto ad un altro.
Si chiama tempo di esecuzione della richiesta di un utente l’intervallo di tempo individuato
dalla somma di tutti gli intervalli di tempo che il calcolatore ha messo a sua disposizione per
eseguire le operazioni richieste.
Si chiama tempo di risposta, dal punto di vista del calcolatore, l’intervallo di tempo che
intercorre tra l’istante in cui ha inizio l’elaborazione richiesta da un utente e l’istante in cui
tale elaborazione ha termine. Ovviamente nel caso si abbia un solo utente collegato tempo di
esecuzione e tempo di risposta coincidono. Nel Capitolo 7 si introdurra’ un’altra definizione:
il tempo di risposta dal punto di vista dell’utilizzatore.

T e m p o d i r isp o sta

TA TB TC

U1 U2 U3 U1 U2 U3 U1 U2 U3

T em po

In iz io o p e r a z io n e F in e o p e r a z io n e
r ic h ie sta d a ll’u te n te 1 r ic h ie sta d a ll’u te n te 1

T A + T B + T C = T em p o d i esecu z io n e

Figura 1-3. Avvicendamento degli utenti sul sistema di elaborazione

Capitolo 1 1.3
Appunti di CALCOLATORI ELETTRONICI 1

L’ordine di esecuzioni delle funzioni richieste dagli utenti è gestito da un programma che è
eseguito dal sistema di elaborazione e che viene chiamato sistema operativo (fig. 1- 4).
Il sistema operativo interviene alla fine dell’intervallo di tempo dedicato ad un utente per
predisporre l’esecuzione delle funzioni richieste dal successivo utente nell’intervallo di tempo
a lui dedicato. Il sistema operativo, inoltre, interviene anche all’interno dell’intervallo
dedicato ad un utente, ed in particolare viene richiamato dal programma utilizzato
dall’utente per svolgere funzioni particolari, per es. trasferimento dati con la memoria,
gestione di situazioni di errore.
Nel passaggio da un utente al successivo il sistema operativo deve “salvare” tutte le
informazioni che occorrono per poter far riprendere l’elaborazione interrotta dal punto al
quale era arrivata, senza cioe’ ripartire da capo, e ricuperare tutte le informazioni che
servono per far ripartire l’elaborazione successiva. Questa operazione viene denominata
context switching (cambio di contesto).
Si noti che quando “gira” il sistema operativo l’esecuzione del programma utente è sospesa
e viceversa (non girano contemporaneamente).

U1 U2 U3 U1 U2 U3

T em po

UTENTE 2

U 3

T e m p o u tiliz z a to d a l
siste m a o p e r a tiv o

Figura 1-4. Interventi del sistema operativo

E’ possibile definire un parametro che indica le potenzialita’ di un sistema di elaborazione:


tale parametro è chiamato prestazione, è indicato con P ed e’ definito dalla seguente
formula:
P = 1/Tesecuzione

Dati due calcolatori, A dotato di prestazione PA (e tempo di esecuzione TA per uno specifico
programma) e B dotato di prestazione PB (e tempo di esecuzione TB per lo stesso
programma), se PA >PB (=> TA < TB ) è possibile definire la percentuale di miglioramento

Capitolo 1 1.4
Appunti di CALCOLATORI ELETTRONICI 1

ottenuto col calcolatore A rispetto al calcolatore B. Questa percentuale e’ denominata speed-


up.

speed-up = (PA – PB)/ PB

Risulta anche

speed-up = (TB – TA)/ TA

Sul tema della prestazione e’ molto importante e utile la legge di Amdahl che afferma che il
miglioramento della prestazione che si ottiene in un calcolatore accelerando un qualsiasi
sottoinsieme delle operazioni che esso deve compiere è proporzionale alla percentuale di
tempo in cui tale sottoinsieme è utilizzato. In formula, se Tes.iniziale e’ il tempo di esecuzione
prima della accelerazione e Tes.finale e’ il tempo di esecuzione ottenuto grazie alla
accelerazione, si ha :

Tes.finale = p· (Tes.iniziale /a) + (1-p)· Tes.iniziale

dove p è la percentuale di tempo utilizzata dal sottoinsieme accelerato, ed a è il fattore di


accelerazione.

Si consideri il seguente esempio. Modificando l’ALU si riduce ad 1/10 il tempo richiesto da


un calcolatore per eseguire le operazioni aritmetiche in virgola mobile (si veda piu’ avanti,
Cap. 2). Si supponga che del tempo di esecuzione solo il 20 % venga utilizzato per eseguire
tali operazioni.
Dalla legge di Amdhal si ricava:

Tes.finale = 0,2· (Tes.iniziale /10) + 0,8· Tes.iniziale = 0,82· Tes.iniziale

Lo speed-up varrà in questo caso:

speed-up = (Tes.iniziale - Tes.finale )/ Tes.finale = (1 – 0,82)/ 0,82 =~0,22

Si vede come, pur avendo migliorato significativamente (10 volte) le prestazioni di un


sottoinsieme delle operazioni, il tempo di esecuzione risulta ridotto solo del 18% in quanto il
sottoinsieme considerato utilizza una frazione limitata del tempo totale di esecuzione. Si
potrebbero avere risultati molto piu’ interessanti se si agisse sulla parte restante delle
operazioni.

Il tempo di esecuzione di un programma su di un determinato calcolatore, d’altra parte, e’


esprimibile come
M
Tesecuzione = Tclock · (Σ Ni ·CPIi )
i=1

dove:
• Tclock = periodo di clock della macchina
E’ definito dal dispositivo (clock) che genera segnali periodici usati per la
sincronizzazione del funzionamento e dipende dalla tecnologia e
dall’organizzazione del sistema; ovviamente e’ l’inverso della frequenza del clock.
Attualmente ha valori espressi in nanosecondi (ns).
• M = numero di tipi di istruzioni disponibili sul calcolatore (aritmetiche, salti, ecc.); esse
costituiscono il set di istruzioni
• CPIi = numero di periodi di clock richiesti per l’esecuzione delle istruzioni di tipo i

Capitolo 1 1.5
Appunti di CALCOLATORI ELETTRONICI 1

Il CPIi andrebbe sempre misurato in quanto i costruttori forniscono spesso nella


documentazione, per tutti i tipi di istruzioni per i quali il tempo di esecuzione
varia per es. in funzione degli operandi, il valore minimo od un campo di valori.
Se le istruzioni sono di tipo semplice, si avrà un CPIi basso, se invece eseguono
operazioni più complesse si avrà un CPIi elevato.
• Ni = numero di istruzioni di tipo i presenti nel programma
Dipende dal set di istruzioni e dalla qualità dei compilatori (per qualità di un
compilatore si intende la sua capacità di ottimizzare il programma, ad es.
eliminando le istruzioni non necessarie). Se il set di istruzioni contiene istruzioni
di tipi semplici avremo un Ni alto; istruzioni di tipo più complesso permetteranno
invece di abbassare Ni (con un set di istruzioni di tipo semplice ne occorrono
infatti di più per svolgere le stesse funzioni).

Ogni modifica al set di istruzioni di un calcolatore al fine di farle diventare più complesse
porta generalmente alla necessità di aumentare i CPIi, e viceversa. Tenendo invece fisso il set
di istruzioni, ogni intervento che porta ad aumentare i CPIi generalmente diminuisce il Tclock
.
E’ chiaro come agire sulla tecnologia e sulla qualità dei compilatori per migliorare Tesecuzione
ma sui restanti aspetti bisogna trovare i compromessi migliori. La filosofia progettuale alla
base dei calcolatori RISC (= Reduced Instruction Set Computer) è quella di avere un set di
istruzioni molto semplici che mantengono basso il CPIi a scapito del valore di Ni, mentre
quella dei calcolatori CISC (=Complex Instruction Set Computer) è l’opposta. Attualmente vi
e’ una forte tendenza a progettare calcolatori RISC.

Il MIPS è una unita’ di misura che è talvolta usata per valutare le prestazioni di un sistema.
Esso corrisponde ad un milione di istruzioni eseguite al secondo ed il suo valore si puó
quindi calcolare utilizzzando un valore medio di CPI con la formula:
___
MIPS = (frequenza del clock in Hz)/(106·CPI)

Il valore ottenuto con questa formula e’ peraltro generico, ossia non applicabile a nessun
caso specifico. Infatti non considera parecchi elementi: non tiene conto per es. delle
possibilità offerte dal set di istruzioni (quanto più il set di istruzioni di una certa macchina è
potente tanto più è possibile accorciare i programmi che vengono eseguiti su di essa), e delle
percentuali delle diverse istruzioni all’interno di programmi reali (una macchina più veloce
in un programma può essere più lenta in un altro).
___
Se avessimo, per es., un calcolatore con frequenza di clock di 800 MHz e CPI=2, i MIPS
corrispondenti sarebbero

MIPS = 800·106/(106·2) = 400

Per caratterizzare i supercalcolatori si usa spesso un’altra unita’ di misura, il megaflop, che
rappresenta i milioni di operazioni in virgola mobile eseguite al secondo. E’ una misura che è
significativa se si utilizzano programmi nei quali la maggior parte delle operazioni sono di
tipo virgola mobile (si vedano al riguardo i paragrafi 2.6 e 2.7), come accade appunto spesso
nelle applicazioni dei supercalcolatori.

1.4 - LIVELLI DI UN CALCOLATORE


Un calcolatore puo’ essere studiato e descritto da diversi punti di vista, che sono detti
livelli. La fig. 1-5 presenta il quadro dei principali livelli, suddivisi tra livelli dell’hardware e
livelli del software dove con hardware si intende l’insieme delle apparecchiature che
Capitolo 1 1.6
Appunti di CALCOLATORI ELETTRONICI 1

costituiscono il calcolatore e con software si intende l’insieme dei programmi, delle


procedure, delle regole e della documentazione relativi al funzionamento del calcolatore. Si
parla convenzionalmente di “livelli alti” riferendosi a quelli piu’ vicini agli utenti e di “livelli
bassi” riferendosi a quelli piu’ vicini alla struttura fisica del calcolatore.

Da un programma scritto in un linguaggio ad alto livello, oppure in un linguaggio orientato


ai problemi, è possibile passare, utilizzando il compilatore (che è esso stesso un
programma), allo stesso programma scritto in linguaggio Assembler. Quest’ultimo, poi,
tramite l’assemblatore (anch’esso un programma) viene tradotto in linguaggio macchina, che
utilizza i soli simboli 0 ed 1, che è l’unico linguaggio “capibile” direttamente dalla macchina.
E’ anche possibile tradurre direttamente un programma scritto in linguaggio ad alto livello, o
in un linguaggio orientato ai problemi, direttamente in linguaggio macchina.
Il sistema operativo, anch’esso un programma, consente al programma scritto in linguaggio
macchina di essere eseguito, ma può essere “scavalcato” per consentire al programma in
linguaggio macchina di interagire direttamente con il livello Macchina convenzionale.

Linguaggi ad alto livello Linguaggi orientati ai problemi


(es. Pascal, C++) (es. LISP , SIMSCRIPT )

Compilatori

Passaggio
Passaggio Linguaggio Assembler diretto
diretto
Assemblatore

Linguaggio Macchina

Sistema Operativo

Fine dei livelli del


SOFTWARE

Inizio dei livelli dell’


Macchina HARDWARE
convenzionale

Logica Cablata Macchina


microprogrammata

Circuiti Logici

Figura 1-5. Livelli di un sistema di elaborazione dell’informazione

Capitolo 1 1.7
Appunti di CALCOLATORI ELETTRONICI 1

Le unita’ elementari (righe) di un programma in linguaggio ad alto livello od orientato ai


problemi od in linguaggio Assembler sono dette dichiarazioni mentre le unita’ elementari di
un programma scritto in linguaggio macchina sono dette istruzioni. Dato che le istruzioni
che costituiscono il linguaggio macchina sono rappresentate, come gia’ detto, da stringhe
binarie, per scrivere un programma direttamente in questo linguaggio è necessario avere la
possibilità di utilizzare un linguaggio dello stesso livello ma con istruzioni di tipo simbolico
più maneggevoli per il programmatore: l’Assembler ha precisamente questo ruolo e le sue
dichiarazioni sono in corrispondenza biunivoca con le istruzioni del linguaggio macchina.
Per alcuni linguaggi ad alto livello od orientati ai problemi la traduzione puo’ essere fatta
non da un compilatore ma da un interprete: questo e’ per es. il caso dei linguaggi BASIC e
JAVA. La differenza tra questi due tipi di traduttori e’ la seguente:
• Compilatore
Traduce l’intero programma sviluppato dall’utente (denominato codice sorgente) in
Assembler o in linguaggio macchina lasciando “traccia” della traduzione, ossia
producendo una copia fisica (in memoria) del programma tradotto (si tratta del cosiddetto
codice oggetto). Viene pertanto utilizzato una sola volta, quando si intende effettuare la
traduzione, dopodiché il programma è in grado di funzionare autonomamente: infatti non
è più necessario né il compilatore né il programma sorgente, ma solo il programma
tradotto.
• Interprete
E’ un programma tramite il quale si esegue un altro programma. Esso preleva una
dichiarazione alla volta, la esamina, la “interpreta” e la fa eseguire dal calcolatore, quindi
passa alla successiva dichiarazione, senza lasciare “traccia” del programma tradotto. Ogni
volta che si vuol fare eseguire il programma di partenza e’ quindi necessario sia il
programma sorgente che l’interprete.
Se per uno stesso linguaggio sono disponibili entrambi i tipi di traduttori, ma non e’ un caso
frequente, si puo’ osservare che l’interprete è generalmente più lento nel fare girare un
programma, ma risulta piu’ semplice da realizzare; il compilatore in compenso puo’ produrre
un codice oggetto di migliore qualita’. Gli interpreti in generale hanno il vantaggio di rilevare
subito eventuali errori e di poter eseguire lo stesso programma su macchine diverse.

I livelli relativi all’hardware verranno descritti piu’ avanti, parlando della unita’ di controllo.

1.5 - STRUTTURA DELL’UNITA’ CENTRALE

L’unita’ centrale contiene vari elementi, i principali dei quali sono riportati nella fig. 1-6. Le
loro funzioni sono le seguenti:
PC (program counter o contatore di programma)
Si tratta di un registro che contiene l’indirizzo della locazione di memoria in cui si trova la
successiva istruzione da eseguire.
IR (instruction register o registro di istruzione)
Si tratta di un registro che contiene l’istruzione da eseguire.
MAR (memory address register o registro di indirizzamento della memoria),
MDR (memory data register o registro dati per la memoria)
Sono registri che hanno rispettivamente il compito di inviare all’esterno o ricevere
dall’esterno dell’ unita’ centrale il valore dell’indirizzo e del dato coinvolti nei trasferimenti
tra memoria e unita’ centrale.
RF (register file o archivio di registri)
Insieme di registri utilizzati per memorizzare all’interno dell’unita’ centrale risultati
temporanei e informazioni di controllo, allo scopo di diminuire il numero di accessi alla
memoria esterna e di velocizzare il processo di elaborazione. In generale sono denotati con
la lettera R ed R1 è per es. il registro identificato dal numero 1 all’interno di RF.
A, B, P (accumulatori)

Capitolo 1 1.8
Appunti di CALCOLATORI ELETTRONICI 1

Si tratta di registri il cui contenuto, al contrario del contenuto dei registri sopra elencati,
non può essere modificato dal programmatore mediante istruzioni; essi sono cioe’
“invisibili”, al programmatore e svolgono la funzione di ospitare operandi e risultati
durante l’esecuzione delle operazioni dell’ALU.
PSW (processor status word o parola di stato del processore)
Si tratta di un registro che contiene bit che caratterizzano lo stato dell’unita’ centrale.
INDIRIZZI

MAR Memory Address Register

PC Program Counter

PSW Processor Status Word

RF
Register File
B
READ, WRITE
u
s

I A B Accumulatori
UNITA’ DI
CONTROLLO n
t
ACK
e
r ALU
n
o
P
Accumulatore
IR
Instruction
Register
MDR Memory Data Register

DATI

Figura 1-6. Schema a blocchi dell’unita’ centrale

Registri ed accumulatori sono messi in comunicazione tra loro attraverso un bus.


L’unità di controllo coordina il funzionamento di tutti gli elementi. In fig. 1-6 sono specificati
anche alcuni segnali che l’unita’ centrale utilizza per comunicare con l’esterno:
• DATI
Costituiscono le informazioni che vengono scambiate con l’esterno (segnali entranti ed
uscenti rispetto all’unita’ centrale).
• INDIRIZZI
Sono utilizzati per comunicare all’esterno un indirizzo di memoria (segnali solo uscenti).
• READ, WRITE
Vengono utilizzati dall’unita’ centrale per comunicare all’esterno l’intenzione di leggere o
scrivere un dato (segnali solo uscenti).
• ACK
Viene utilizzato per comunicare all’unita’ centrale che il dato precedentemente richiesto è
disponibile (segnalesolo entrante).

Capitolo 1 1.9
Appunti di CALCOLATORI ELETTRONICI 1

1.6 – SET DI ISTRUZIONI


Come si e’ gia detto, l’insieme di tutte le istruzioni eseguibili da una CPU prende il nome di
set delle istruzioni. Ogni istruzione è tipicamente costituita da un insieme di bit suddivisi in
due parti: il codice operativo e gli operandi.
Il codice operativo specifica il tipo di operazione che si vuole eseguire sugli operandi il cui
numero varia tipicamente da 0 a 3. Di seguito sono riportati esempi di istruzioni con i
diversi numeri di operandi:

ADD R1, R2, R3 Istruzione a 3 operandi che coinvolge 3 registri: in


R1 si inserisce la somma dei contenuti di R2 ed R3;
sorgenti ossia: R1 <= [R2]+ [R3]

destinazione

ADD R1, R2 Istruzione a 2 operandi che coinvolge 2 registri: in


R1 si inserisce la somma dei contenuti di R1 ed R2;
sorgente ossia: R1 <= [R1]+ [R2]

sorgente e
destinazion

INC R3 Istruzione ad un operando: incrementa di una unita’ il


contenuto del registro R3 ; ossia: R3 <= [R3] + 1

RETURN Istruzione senza operandi (ritorno da subroutine)

Nelle istruzioni con 2 od 1 operando i registri possono essere sostituiti da indirizzi di


memoria.
Le istruzioni a 3 operandi sono tipiche delle macchine RISC, mentre quelle a 2 operandi
sono tipiche delle macchine CISC.
Ogni istruzione che l’unita’ centrale deve eseguire viene divisa in più fasi. Per es. l’istruzione
a 3 operandi sopra riportata comprende le seguenti fasi :

⎧Il registro PC, tramite il bus , trasferisce l' indirizzo di memoria da caricare al MAR
⎪Viene inviato, verso l' esterno, il segnale di lettura (READ).

Fase di Fetch ⎨
⎪L' unità di controllo verifica la presenza del segnale ACK : se c' e' ACK si abilita MDR
⎪⎩ a trasferire, tramite il bus, l' istruzione in IR e si prosegue; altrimenti si attende ACK
⎧Il dato presente sul registro R 2 viene trasferito, tramite il bus, in A.
⎪Il dato presente sul registro R viene trasferito, tramite il bus, in B.
⎪ 3
Fase Execute⎨
⎪L' ALU esegue l' addizione e pone il risultato in P.
⎪⎩Il dato presente in P viene trasferito, tramite il bus, nel registro R 1 .

Le unita’ centrali di tipo RISC hanno poche fasi molto semplici per ogni istruzione, mentre le
CISC hanno molte fasi abbastanza complesse. E’ inoltre opportuno che le istruzioni siano
tutte della stessa lunghezza (stesso numero di bit), altrimenti la struttura interna della CPU
si complica. Le unita’ centrali RISC utilizzano istruzioni a lunghezza fissa, contrariamente
alle unita’ centrali di tipo CISC che, soprattutto per i vincoli posti dalla necessita’ di
preservare la compatibilità con il passato, utilizzano istruzioni a lunghezza variabile.

Capitolo 1 1.10
Appunti di CALCOLATORI ELETTRONICI 1

Se si intendessero utilizzare istruzioni a lunghezza fissa, ad esempio di 16 bit, ma con


numero di operandi variabili, è possibile utilizzare una codifica a espansione del codice
operativo che sfrutta al meglio i bit disponibili (fig. 1-7).

CODICE OP. 1 OP. 2 OP. 3 Istruzione a 3


operandi

1111 CODICE OP. 1 OP. 2 Istruzione a 2


operandi

1111 1111 CODICE OP. 1 Istruzione a 1


operando

1111 1111 1111 CODICE Istruzione senza


operandi

4 bit 4 bit 4 bit 4 bit

16 bit
Figura 1-7. Espansione del codice operativo
Come si ricava dalla figura:
• Per le istruzioni a 3 operandi esistono 15 codici operativi possibili: infatti si possono
utilizzare i codici da 0000 a 1110 mentre il codice 1111 non può essere usato perche’, nel
caso di istruzioni con meno di 3 operandi i primi 4 bit valgono 1111 e i secondi 4
diventano una prosecuzione del codice operativo;
• Per le istruzioni a 2 operandi il codice operativo e’ costituito dai primi 8 bit: sono pertanto
15 i codici possibili, da 1111 0000 a 1111 1110, e la configurazione 1111 dei secondi 4
bit serve per espandere ulteriormente il codice operativo;
• Per le istruzioni a 1 operando il codice operativo e’ costituito dai primi 12 bit: 15 codici
sono i codici possibili, da 1111 1111 0000 a 1111 1111 1110, sempre per consentire la
successiva espansione;
• Per le istruzioni senza operandi il codice operativo e’ costituito da tutti e 16 i bit: 16 sono i
codici possibili, da 1111 1111 1111 0000 a 1111 1111 1111 1111.
Complessivamente si arriva a 61 istruzioni (15+15+15+16). Questo tipo di codifica richiede
pero’ un’unita’ centrale più complessa che nel caso precedente di fig. 1-6.

I piu’ comuni tipi di istruzione sono i seguenti:


• Aritmetico
Rientrano in questa categoria anche le operazioni logiche tipo AND e OR. Nei calcolatori
piu’ complessi possono includere operazioni in virgola mobile. In ogni caso sono istruzioni
che utilizzano l’ALU.
• Confronto
Eseguono il confronto tra due dati, per es. per decidere se effettuare un salto ad un altro
punto del programma. In pratica non producono un risultato vero e proprio e nemmeno
effettuano un’azione: si limitano ad aggiornare solo alcuni bit di stato. Dalla lettura di
questi bit si ricava l’esito del confronto.
• Salto
Può essere assoluto o condizionato. Se è condizionato è preceduto da un’altra istruzione
che verifica la condizione, di solito un’istruzione di confronto.
• Salto a subroutine, ritorno da subroutine
Il salto a subroutine è un’istruzione che deve salvare tutte le informazioni correnti relative
al programma in esecuzione ed andare ad eseguire un altro segmento di programma
(subroutine). Quando incontra invece un’istruzione di ritorno da subroutine il calcolatore

Capitolo 1 1.11
Appunti di CALCOLATORI ELETTRONICI 1

riprende ad eseguire il programma interrotto a partire dal punto (istruzione) dove lo


aveva lasciato precedentemente.
• Trasferimento dati
Si tratta per es. del caricamento di registri dalla memoria e viceversa (da memoria a
registro comando LOAD, da registro a memoria comando STORE), del trasferimento di
dati da registro a registro.
• Istruzioni di I/O
Sono istruzioni che servono a trasferire dati all’esterno o ad acquisire dati dall’esterno del
calcolatore. Si possono realizzare in due modi:
(A) quando incontra un’istruzione di I/O, l’unita’ centrale informa le periferiche che
intende interagire con dispositivi esterni e, fornendo l’indirizzo, indica anche con
quale dispositivo intende interagire (fig. 1-8 caso A); in questo caso si utilizzano codici
specifici e indirizzi particolari;
(B) in alternativa è possibile riservare una zona nello spazio di indirizzamento della
memoria in modo che ogni volta che si va ad agire in questa zona (con un’istruzione
di trasferimento dati con la memoria) in realtà si interagisce con l’esterno (fig. 1-8
caso B); in questo caso il codice dell’istruzione è lo stesso usato per il trasferimento
dati.
• Istruzioni varie
Ad esempio istruzioni per gestire gli interrupt.

CPU MEMORIA

I/O

Caso A

CPU MEMORIA

I/O

Caso B

Figura 1-8. Modalita’ di indirizzamento dell’I/O

Capitolo 1 1.12
Appunti di CALCOLATORI ELETTRONICI 1

1.7 – MODI DI INDIRIZZAMENTO


Quando un’istruzione ha degli operandi è indispensabile indicare come reperire i dati
necessari alla sua esecuzione, cioè è necessario specificare il “modo di indirizzamento”.
Le modalita’ di indirizzamento sono diverse e si possono suddividere in due categorie:
indirizzamenti assoluti, se l’istruzione contiene l’indirizzo completo dell’operando, e
indirizzamenti relativi, in caso contrario.

Indirizzamenti Assoluti

• Immediato
Nell’istruzione viene fornito il valore dell’operando da utilizzare (il simbolo # indica il modo
di indirizzamento immediato). In effetti, quindi, non si ricorre ad alcun operando.
Esempi :
JMP # 153 (salto all’indirizzo 153)
LOAD R1, # 124 (carica nel registro R1 il numero 124)

• Diretto
Nell’istruzione viene fornito l’indirizzo dove è posto l’operando.
Esistono due modi di indirizzamento di tipo diretto: in memoria e in register file. Gli
esempi che seguono per semplicita’ prevedono istruzioni con due operandi ma la modalita’
di indirizzamento e’ applicabile anche al caso di tre operandi.
Esempi:
- in memoria: LOAD R1, 100
il contenuto della cella di memoria di indirizzo 100 viene trasferito nel registro R1;
se con M(x) si intende il contenuto della posizione di memoria M di indirizzo x si
puo’ scrivere: R1 <= [M(100)]
- in register file: ADD R1, R2
il risultato dell’operazione di addizione eseguita sui contenuti di R1 ed R2 viene
posto nel registro R1, ossia R1 <=[R1]+[R2]
LOAD R1, R2
in R1 si inserisce il contenuto di R2 ossia R1 <= [R2]

• Indiretto
Nell’istruzione viene fornito l’indirizzo dove è posto l’indirizzo dell’operando.
Esistono due modi di indirizzamento indiretto: su memoria e su registro (le parentesi
rotonde indicano la modalita’ di indirizzamento indiretto). Anche in questo caso gli esempi
prevedono due operandi ma la modalita’ di indirizzamento e’ applicabile a tre operandi; va
rilevato inoltre che la modalita’ di indirizzamento indiretto puo’ essere, in linea di
principio, utilizzata per ogni operando.
Esempi:
- su memoria LOAD R1 , (200)
inserisce, fig. 1-9, in R1 il contenuto della cella all’indirizzo di memoria indicato
nella cella 200; ossia R1 <= [M([200])]
- su registro LOAD R1, (R5)
inserisce in R1 il contenuto dell’indirizzo di memoria individuato da R5, ossia
R1 <= [M([R5])]

Capitolo 1 1.13
Appunti di CALCOLATORI ELETTRONICI 1

MEMORIA
LOAD R1, (200)

200 2500

2500 4
R1 = 4

Figura 1-9. Esempio di indirizzamento indiretto

• Autoincremento
Esempi:
LOAD R1, (R5) +
il contenuto del registro R5, dopo essere stato utilizzato per
l’indirizzamento indiretto, viene incrementato di 1
LOAD R1, (R5) -
come il caso precedente, solo che il contenuto del registro R5 viene
decrementato di 1
LOAD R1, + (R5)
in questo caso l’incremento viene fatto prima di utilizzare il registro R5,
cioè l’indirizzamento indiretto si ha sul valore dato dal contenuto di R5
incrementato di 1
LOAD R1, - (R5)
come il caso precedente, solo che il contenuto del registro R5 viene
decrementato di 1

Indirizzamento relativi

• Con registro indice


Per questa modalita’ di indirizzamento si utilizza un particolare tipo di registro, il registro
indice RI, che mentre su alcune CPU è dedicato, su altre è un qualsiasi registro.
Esempi:
LOAD R5, (R2+RI)
inserisce nel registro R5 il contenuto dell’indirizzo di memoria individuato dalla
somma dei contenuti di R2 ed RI, ossia: R <= [M([R2] + [RI])]
LOAD R1, (R3+R5)
come nel caso precedente, solo che invece del registro RI si utilizza un qualsiasi
registro del RF, ossia: R1 <= [M([R3] + [R5])]; come gia’ detto non tutte le unita’
centrali ammettono questo metodo di indirizzamento
LOAD R1, (RI+#1000)
inserisce nel registro R1 il contenuto della posizione di memoria all’indirizzo
ottenuto sommando 1000 al contenuto di RI, ossia: R <= [M([RI] + 1000)]

Questo tipo di indirizzamento si rivela utile nel caso si voglia operare su strutture dati a
matrice od a vettore. Se, ad esempio, si ha un vettore di dati che parte dall’indirizzo R2
(fig. 1-10) l’i-esimo elemento di questo vettore è in (R2 +i-1): se si pone RI = i-1 è possibile
operare facilmente su ogni elemento posto nella struttura solo che si aggiorni via via il
valore di RI.

Capitolo 1 1.14
Appunti di CALCOLATORI ELETTRONICI 1

R2

R2 + RI vi

Figura 1-10. Indirizzamento con registro indice

• Con registro base


Spesso in un’unita’ centrale il numero di bit utilizzati per rappresentare un dato è uguale
al numero di bit usati per definire una istruzione perché è più facile realizzare unita’
centrali fatte in questo modo. Ma i bit di indirizzo nell’istruzione cosi’ definita possono
essere insufficienti: in questo caso è possibile espandere il campo degli indirizzi
utilizzando il registro base.
Esistono due modi per utilizzare il registro base a questo fine: in affiancamento e in
sovrapposizione.

16 bit REGISTRO BASE

16 bit INDIRIZZO NELL’ISTRUZIONE

32 bit INDIRIZZO EFFETTIVO

Utilizzo del registro base in affiancamento

Figura 1-11. Impiego del registro base in affiancamento

In caso di affiancamento il registro base indica la parte più alta (i bit piu’ significativi)
dell’indirizzo effettivo, quello usato per indirizzare la memoria fisica, mentre l’indirizzo
presente nell’istruzione individua la parte più bassa dell’indirizzo effettivo. In pratica il
registro base ha la funzione di individuare una determinata zona (sezione) nello spazio
indirizzabile, mentre con l’indirizzo nell’istruzione è possibile puntare al singolo indirizzo
all’interno della sezione.
Utilizzando per esempio la struttura di registri della fig. 1-11 e supponendo che ogni
indirizzo contenga 1 byte e’ cosi’ possibile indirizzare 4 Gbyte (= 232 byte): si definiscono
infatti 216 (= 64 K) sezioni, distinte ciascuna dal valore assunto dal registro base, ed
ognuna di esse e’ composta da 64 Kbyte (fig. 1-12).
Si ricordi che in campo informatico si usa il simbolo K (maiuscolo) per indicare un
moltiplicatore di valore 1024 ma si usano gli stessi simboli del Sistema Internazionale di
unita’ per i moltiplicatori superiori, con significato pero’ diverso. Cosi’ per esempio M sta
per 1048576, e non 106, e G sta per 1073741824, e non 109.

Capitolo 1 1.15
Appunti di CALCOLATORI ELETTRONICI 1

MEMORIA TOTALE 4 Gbyte

64 K
Sezione (=64 Kbyte)
sezioni
da 64
Kbyte

Figura 1-12. Uso del registro base in affiancamento

In caso di sovrapposizione, cioe’ se vi sono bit dell’indirizzo presenti in entrambi i registri,


l’indirizzo effettivo è ottenuto come somma dei contenuti dei due registri.

In alcuni calcolatori si possono trovare usati insieme sia il registro base sia il registro indice:
in tal caso l’indirizzo effettivo si ottiene come somma di tre elementi. La fig. 1-13
rappresenta un possibile meccanismo di utilizzazione di registro base e registro indice nella
definizione dell’indirizzo effettivo.

REGISTRO BASE

REGISTRO INDICE

INDIRIZZO NELL’ISTRUZIONE

INDIRIZZO EFFETTIVO

Figura 1-13. Uso di registro indice e registro base

1.8 - RAPPRESENTAZIONE DI DATI NEI CALCOLATORI

I moderni calcolatori sono realizzati con registri che contengono un certo numero di byte
(tipicamente 4 byte ossia 32 bit) e le operazioni sono eseguite su tale insieme di byte. Questo
insieme di byte e’ detto parola. Teoricamente ogni byte e’ indirizzabile ma in ogni operazione
di lettura e scrittura, anche se viene fornito l’indirizzo di un byte, sono in realta’ coinvolti
tutti i byte di una parola: l’indirizzo e’ quindi quello del primo dei byte.
Premessa questa definizione, si esamineranno le modalita’ di memorizzazione dei vari tipi di
dati che un calcolatore puo’ trattare.

• Numeri interi
Si rappresentano in base 2 (sistema binario). Sono anche detti “numeri in virgola fissa” (in
inglese “fixed point”) in quanto la virgola e’ come se cadesse sempre alla destra del bit

Capitolo 1 1.16
Appunti di CALCOLATORI ELETTRONICI 1

meno significativo. Il numero di bit utilizzati è uguale o doppio dei bit della parola del
calcolatore.
• Numeri con virgola
Sono anche detti “numeri in virgola mobile” (in inglese “floating point”) in quanto
trascrivendone il valore nel modo tradizionale la virgola puo’ cadere in un punto qualsiasi
della sequenza di bit. Un numero con virgola e’ espresso come:

± mantissa · base± esponente

La base è 2 o 16. Possibili esempi (in base 10) sono i seguenti:


3,14 espresso come +0,314·101
-0,00218 espresso come –0,218·10-2
La rappresentazione solitamente utilizzata all’interno dei calcolatori e’ costituita da 3
campi (la base e’ sottintesa ed il segno dell’esponente e’ incluso nel campo dell’esponente):

Segno Esponente Mantissa


1 num.negativo
0 num. positivo

Esistono degli standard di rappresentazione, ma non tutti i calcolatori li seguono. Si parla


solitamente di singola precisione, doppia precisione, precisione estesa quando si
usano per rappresentare un numero rispettivamente 32, 64, 80 bit.
• Variabili booleane
Si rappresentano con 1 bit o con 1 byte. Nel caso si usi un byte esso assume i valori
00000000 o 11111111. L’impiego di un byte semplifica le operazioni di test ed
aggiornamento ma comporta un maggiore impegno di memoria.
• Caratteri
Vengono rappresentati con 8 bit (1 byte) secondo due convenzioni: una e’ detta codice
ASCII (dove ASCIII sta per American Standard Code for Information Interchange; e’ anche
detto ISO-8, dove ISO sta per International Standards Organization); l’altra, utilizzata in
calcolatori costruiti dalla societa’ IBM, e’ detta codice EBCDIC (EBCDIC sta Extended
Binary Coded Decimal Interchange Code).
• Stringhe di caratteri
Con questo termine di definiscono successioni di caratteri. Esistono diversi metodi per
rappresentare le stringhe.

Rappresentazione impaccata: e’ un metodo semplice da utilizzare, ma si presta poco a


modifiche della stringa. Se, per es., si vuole allungare una stringa impaccata può essere
necessario spostare tutti i caratteri in quanto la parte di memoria attigua può essere
stata utilizzata per altri scopi. Nell’esempio sono presenti 4 caratteri per parola. Per
indicare la fine di una stringa si puo’ ricorrere all’uso di un carattere particolare, che
ovviamente non deve essere usato all’interno della stringa.

Capitolo 1 1.17
Appunti di CALCOLATORI ELETTRONICI 1

M E M O R IA

S T R I
S im bolo
dello
N G A b
s pazio

D I b C

A R A T

S tringa Im paccata

Rappresentazione linkata: in ogni parola si memorizza un carattere nonché l’indirizzo di


memoria (puntatore) dove si trova il successivo carattere seguente della stringa. Si tratta
in sostanza di una lista semplice. Questa rappresentazione permette di fare delle
modifiche molto facilmente a scapito di un notevole utilizzo di memoria (il puntatore porta
via molto più spazio del carattere). In questo caso il termine della stringa e’ di solito
indicato da un puntatore di valore particolare (per es. nullo).

MEMORIA

Prossimo
carattere

Stringa Linkata

Rappresentazione a blocchi con puntatore: si tratta di un metodo intermedio (quanto a


flessibilita’ ed occupazione di memoria) tra i due visti in precedenza, che permette di fare
modifiche in modo relativamente facile e di risparmiare spazio rispetto alla
rappresentazione linkata. Si puo’ avere un ulteriore miglioramento utilizzando blocchi di
dimensione variabile: in questo caso, pero’, occorre inserire in ogni blocco un parametro
che ne definisca la lunghezza.

Capitolo 1 1.18
Appunti di CALCOLATORI ELETTRONICI 1

MEMORIA

S T R I

N G A b

PUNTATORE

D I b C

A R A T

PUNTATORE

Stringa a blocchi
con puntatori

• Vettori
Il modo più semplice per indirizzare gli elementi di un vettore consiste nell’utilizzare il
registro indice. Indicando un elemento del vettore come ai, con l ≤ i ≤ u, si avrà che
l’indirizzo dove esso è posto varrà:
IND(ai)= start + (i - l) = k + i
dove start e’ l’ indirizzo dove è posto il primo elemento del vettore e k e’ una costante.
MEMORIA

Inizio (start)

Indice
Vettore

• Matrici
∗ Matrice a 2 dimensioni
Supponendo che ogni elemento occupi una posizione di memoria, l’elemento generico
della matrice si indica con aij dove gli indici i, j sono tali che:
li ≤ i ≤ ui e lj ≤ j ≤ uj.
Vi sono uj - lj +1 sezioni, ciascuna dedicata ad una colonna, ed in ogni sezione ci sono ui -
li +1 elementi, che corrispondono alle diverse righe (fig. 1-14).
L’indirizzo di aij si ha con la formula:
IND(aij )= start + (ui - li +1)·(j -lj)+ (i - li) = k + (k1 · j)+ i
con start, k, k1 costanti.

Esempio. Data una matrice a con 4 righe e 3 colonne in cui 0≤ i ≤3 e 1≤ j ≤3, con
start=100, il secondo elemento della terza riga si trova all’indirizzo
IND(a3,2) = 100 + (3-0+1)·(2-1) + (3-0) = 107
come indicato nel diagramma della pagina seguente (fig. 1-14).

Capitolo 1 1.19
Appunti di CALCOLATORI ELETTRONICI 1

MEMORIA

Start
Prima sezione MEMORIA
formata da
ui - li + 1 100 (start) a0,1 ⎫
uj - lj + 1 elementi a1,1 ⎪
(tutti gli ⎬ Colonna 1
sezioni,
elementi della a2,1 ⎪
ciascuna ⎭
formata da prima a3,1
colonna)
ui - li + 1 a0,2 ⎫
elementi Sezione a1,2 ⎪
successiva ⎬ Colonna 2
a2,2 ⎪
107 a3,2, ⎭
a0,3 ⎫
a1,3 ⎪
⎬ Colonna 3
a2,3 ⎪
a3,3 ⎭

Figura 1-14. Matrice a due dimensioni

∗ Matrice a 3 dimensioni
Sempre supponendo che ogni elemento occupi una posizione di memoria, il generico
elemento della matrice si indica con aijk, con i, j, k tali che:
li ≤ i ≤ ui , l j ≤ j ≤ u j e l k ≤ k ≤ u k .
Con le stesse considerazioni fatte in precedenza si avrà:
IND(aijk)=start+(ui -li +1)·(uj -lj +1)·(k-lk)+(ui -li +1)·(j -lj )+(i -li )= c+c1·k+c2·j+i

dove start, c, c1, c2 sono costanti.

Al fine di rendere l’accesso agli elementi della matrice più veloce ed agevole, a scapito però
di un maggiore impiego di memoria, è possibile utilizzare dei puntatori ed impiegare una
struttura detta ad indicizzazione marginale, rappresentata in fig. 1-15.
Nel caso di figura si ha 0 ≤ i ≤ 2 , 0 ≤ j ≤ 1 e 0 ≤ k ≤ 3 , cioè la matrice è composta da 24
elementi, ma la indicizzazione marginale richiede 36 posizioni di memoria per
rappresentarla. Le tabelle T1, T2, T3, T4 e T5 contengono solo puntatori.
Se, per es., si e’ inserito in R1 l’indirizzo iniziale start e si usa il registro R2 per
l’indirizzamento, volendo estrarre l’elemento a2,1,3 si devono inserire ordinatamente 2 in
Ri, 1 in Rj, 3 in Rk ed eseguire le seguenti operazioni:

LOAD R2, (R1 + Rk) ossia R2 <= [M([R1] + [Rk])]


LOAD R2, (R2 + RJ) ossia R2 <= [M([R2] + [Rj])]
LOAD R2, (R2 + Ri) ossia R2 <= [M([R2] + [Ri])]

Grazie all’utilizzo dei puntatori le tabelle T1,...,T5 possono essere messe in qualsiasi parte
della memoria.
Il vantaggio, rispetto alla rappresentazione precedente, è che per determinare l’indirizzo
della posizione di memoria che contiene il componente cercato non bisogna effettuare dei
calcoli (due moltiplicazioni e tre addizioni) ma e’ sufficiente eseguire prelievi successivi.

Capitolo 1 1.20
Appunti di CALCOLATORI ELETTRONICI 1

1.9 - RAPPRESENTAZIONE DI NUMERI NEGATIVI

Esistono diversi metodi per rappresentare i numeri negativi:


- Segno e valore
- Con polarizzazione
- Segno e complemento a R (radice) del numero
- Segno e complemento a R - 1 (radice diminuita di 1) del numero

• La rappresentazione di un numero negativo con segno e valore utilizza un bit per il


segno e i rimanenti bit per indicare il valore assoluto del numero. Corrisponde a quella
normalmente utilizzata nei calcoli manuali.

• La rappresentazione di un numero negativo con polarizzazione ha la proprietà di


generare un altro numero senza segno (sempre positivo). Se, ad esempio, si utilizzassero 8
bit, e si adottasse la rappresentazione con polarizzazione in base 128, si avrebbe:

1 1 1 1 1 1 1 1 -> corrisponde a 255 in decimale, ma nella rappresentazione con


polarizzazione viene assunto uguale a 127
......................
1 0 0 0 0 0 0 0 -> corrisponde a 128 in decimale, ma si assume come 0
......................
0 0 0 0 0 0 0 0 -> corrisponde a 0 in decimale, ma viene assunto uguale a -128

In pratica per ottenere la rappresentazione di un numero con m bit tramite la polarizzazione


in base 2m-1 si deve sommare 2m-1 al numero (nell’esempio, essendo m=8, si somma 128).

• In numerosi calcolatori i numeri negativi sono rappresentati con i complementi (ad R


o ad R-1), con vantaggi che si vedranno di seguito.
Le formule generali, valide cioe’ per qualunque radice (o base), sono le seguenti:

Numero intero : N = ( nk-1 ..... n1 n0 )R (ossia per un numero di k cifre in base R)


Complemento a R di N: CR = Rk - N
Complemento a R-1 di N: CR-1 = ( Rk - 1 ) - N = CR -1

Numero frazionario: N’ = ( 0 , n-1 ..... n-m )R (ossia per un numero di m cifre in base R)
Complemento a R di N’ : C’R = 1 - N’
Complemento a R-1 di N’: C’R-1 = ( 1 - R-m ) - N’ = C’R - R-m

Esempi con numeri nel sistema decimale (R=10):


1. N = 384 e di conseguenza k=3
C10 = 1000 - 384 = 616 (e’ detto complemento a 10)
C9 = 999 - 384 = 615 (e’ detto complemento a 9)
2. N’ = 0,118 e di conseguenza m = 3
C’10 = 1 - 0,118 = 0,882
C’9 = 1 - 0,001 - 0,118 = 0,881
Esempio con numero nel sistema binario (R=2):
3. N = 001011 e di conseguenza k = 6.
C2 = 1000000 - 001011 = 110101 (e’ detto complemento a 2)
C1 = 111111 - 001011 = 110100 (e’ detto complemento a 1)

Nel caso R=2 si possono ricavare due semplici regole pratiche per ottenere i complementi:
per il complemento ad 1 di un numero basta sostituire nel numero del quale si vuole trovare
il complemento ogni 1 con 0 ed ogni 0 con 1;

Capitolo 1 1.21
Appunti di CALCOLATORI ELETTRONICI 1

per il complemento a 2 si puo’ ricavare dapprima il complemento ad 1, come sopra indicato,


e poi sommare 1 nella posizione meno significativa, ignorando un eventuale riporto che
dovesse nascere di conseguenza dalla posizione piu’ significativa.

a000
a100
a200
i

a010
a110
a210

i
a001
[0]
[1] a101
j T2 a201

start [0] i
[0]
[1] [1]
a011
[2]
[3] j T3 a111
a211
k [0]
T1
[1] i
j T4 a002
a102
[0] a202
[1]
i
j T5
a012
a112
a212

i
a003
a103
a203

a013
a113
a213

i
Figura 1-15. Esempio di indicizzazione marginale

Capitolo 1 1.22
Appunti di CALCOLATORI ELETTRONICI 1

Dato per es. il numero 00100101 si ha:


Complemento a 1: 11011010
Complemento a 2: 11011011

Il complemento a 2 in pratica e’ l’unico utilizzato. Entrambi i complementi sono molto utili


per rappresentare il valore dei numeri negativi, perché in questa maniera l’operazione di
addizione algebrica (addizione di numeri con segno) si riconduce sempre ad una normale
addizione, come si vedra’ in seguito.

Si immagini di rappresentare i numeri interi con i formati di fig. 1-16 utilizzando 8 bit per
ciascun numero.
Numeri positivi

O Valore assoluto

Numeri negativi

1 Complemento a 1 o 2

Figura 1-16. Esempio di rappresentazione di numeri binari

Utilizzando per i numeri negativi i complementi ad 1 si avrà che lo 0 può essere


rappresentato in due modi diversi: 00000000 (+0) e 11111111 (-0), mentre usando i
complementi a 2 lo 0 sarà rappresentato in maniera univoca: 00000000. Infatti
considerando lo 0 positivo e complementandolo si ottiene ancora lo 0 positivo:

0 0 0 0 0 0 0 0 (rappresentazione positiva)
1 1 1 1 1 1 1 1 + (complemento a 1)
1
0 0 0 0 0 0 0 0

Di conseguenza se i numeri binari sono rappresentati con n cifre (bit), utilizzando i


complementi a 1 per i numeri negativi, si potranno rappresentare i valori del seguente
intervallo:
2n-1-1 ⇔ - (2n-1-1)
mentre utilizzando i complementi a 2 si avrà il campo:
(2 n −1
)
− 1 ⇔ − 2 n −1
Per n=8 con i complementi ad 1 per i numeri negativi si va quindi (in termini di valori
decimali equivalenti) da +127 a –127 e con i complementi a 2 da +127 a –128.

Nel caso si voglia allungare di un bit la rappresentazione di un numero positivo, è sufficiente


aggiungere uno 0 alla sua sinistra. Parallelamente per allungare di un bit la
rappresentazione di un numero negativo con complemento a 1 od a 2, basta aggiungere un
1 alla sua sinistra.
Esempio: 3 dec = 0 0 1 1 = 0 0 0 1 1
- 3 dec = 1 1 0 1 = 1 1 1 0 1

Un numero negativo rappresentato in complemento a 1 o a 2 può essere trasformato nel


relativo numero positivo applicandogli lo stesso algoritmo che esegue il complemento.
Esempio: 1 1 0 1 1 ( = - 5 in compl. a 2)
1 1 0 1 1
0 0 1 0 0 + (complemento a 1)
1
0 0 1 0 1
Capitolo 1 1.23
Appunti di CALCOLATORI ELETTRONICI 1

Per analizzare l’impiego dei complementi nelle addizioni algebriche si fara’ riferimento, negli
esempi che seguono, ad una rappresentazione che impiega 5 bit, il piu’ significativo per il
segno: sarà possibile, quindi, trattare oltre allo 0 numeri interi positivi da 1 a 15 e numeri
interi negativi da -15 a -1 nel caso di rappresentazione con complementi a 1 e da -1 a -16
nel caso di rappresentazione con complementi a 2.

Primo esempio: somma di due numeri negativi rappresentati con i complementi a 1


Si vuole eseguire l’operazione -2 + -3.

-2 -----> 2dec= 0 0 0 1 0bin. ----> -2dec = 1 1 1 0 1bin. compl.a 1


-3 -----> 3dec= 0 0 0 1 1bin. ----> -3dec = 1 1 1 0 0 bin. compl. a 1

La somma viene effettuata come al solito iniziando dal bit più a destra e sommando i bit
corrispondenti nei due addendi. L’eventuale riporto generato è portato a sinistra di una
posizione, come avviene nell’usuale somma decimale. Nell’aritmetica in complemento a 1
l’eventuale riporto generato dall’addizione sul bit più a sinistra è aggiunto al bit più a destra.

1 1 1 0 1 +
1 1 1 0 0 =
1 1 1 0 0 1 +
1 =
1 1 0 1 0

Il risultato correttamente non e’ altro che - 5dec in complemento a 1.

Secondo esempio: somma di due numeri negativi rappresentati con i complementi a 2


Si vuole eseguire l’operazione -4 + -5.

-4 -----> 4dec= 0 0 1 0 0bin. ----> -4dec = 1 1 0 1 1bin. compl.a 1 + 1 = 1 1 1 0 0bin. compl.a 2


-5 -----> 5dec= 0 0 1 0 1bin. ----> -5dec = 1 1 0 1 0 bin. compl. a 1+ 1 = 1 1 0 1 1bin. compl.a 2

Nell’effettuare l’operazione si tenga presente che nell’aritmetica in complemento a 2 il riporto


generato dall’addizione sul bit più a sinistra va scartato.
1 1 1 0 0 +
1 1 0 1 1 =
1 1 0 1 1 1
Il risultato è 1 0 1 1 1, cioè -9dec.

Terzo esempio: somma di due numeri positivi).


Si vuole eseguire l’operazione +11 + +6.

+11 -----> 0 1 0 1 1
+6 -----> 0 0 1 1 0
0 1 0 1 1 +
0 0 1 1 0 =
1 0 0 0 1
Il risultato è -15 dec ed è errato: infatti la somma avrebbe dovuto fornire un risultato al di
fuori dell’intervallo rappresentabile (+17). In situazioni di questo tipo si parla di errore di
overflow.

Quarto esempio: somma di due numeri negativi rappresentati con i complementi a 2


Si vuole eseguire l’operazione -9 + -10.

- 9 ------> 9dec= 0 1 0 0 1bin. ----> -9dec = 1 0 1 1 0bin. compl.a 1 + 1 = 1 0 1 1 1bin. compl.a 2


Capitolo 1 1.24
Appunti di CALCOLATORI ELETTRONICI 1

- 10 -----> 10dec= 0 1 0 1 0bin. ----> -10dec = 1 0 1 0 1 bin. compl. a 1+ 1 = 1 0 1 1 0bin. compl.a 2


1 0 1 1 1 +
1 0 1 1 0 =
1 0 1 1 0 1

Il risultato, quindi, è +13 ed e’ errato perche’ anche in questo caso, come nel precedente, c’è
overflow.

La condizione di overflow si puo’ rilevare in uno dei due seguenti modi:


1) si ha overflow se S1 = S2 e S1≠SR, con S1 bit del segno del 1° operando, S2 bit del segno
del 2° operando e SR bit del segno del risultato (corrisponde, per es., all’ovvia considerazione
che la somma di due numeri negativi non può essere un numero positivo).
2) si ha overflow se il riporto generato dai bit nella posizione piu’ significativa (quella dei
segni) e’ diverso dal rapporto generato dai bit nella posizione immediatamente meno
significativa.

Il metodo 1) di rivelare l’overflow conduce alla equazione:


( )( ) ( )(
Overflow = S1 ⊕ S2 ⋅ S1 ⊕ S R = S1 ⊕ S2 ⋅ S2 ⊕ S R )
Il metodo 2), invece, se gli n bit dei due numeri sono individuati da indici che vanno da 0 (il
meno significativo) ad n-1 (il piu’ significativo), conduce alla equazione:
Overflow = (C n ⊕ C n −1 )
con la consueta convenzione di denotare con Cn-1 il riporto generato dai bit nella posizione
n-2 e con Cn quello generato dai bit nella posizione n-1.

Esempio: si vuole eseguire l’operazione 9 + 11.


9dec= 0 1 0 0 1bin
10dec= 0 1 0 1 1bin
0 1 0 0 1 +
0 1 0 1 1 =
1 0 1 0 0
Il risultato è - 12. Si ha overflow ed entrambe le formule evidenziano l’errore:
Overflow = ( 0 ⊕ 0) ⋅ ( 0 ⊕ 1) = 1
Overflow = ( 1 ⊕ 0) = 1 (in questo caso n=5, C4=1, e C5=0).

Esempio: si vuole eseguire l’operazione 9 - 5.


9dec= 0 1 0 0 1bin
- 5 -----> 5dec= 0 0 1 0 1bin ----> -5dec = 1 1 0 1 0 bin compl. a 1+ 1 = 1 1 0 1 1bin compl.a 2
0 1 0 0 1 +
1 1 0 1 1 =
1 0 0 1 0 0
Il risultato è + 4 e nessuna delle due formule rileva, correttamente, alcun errore:
Overflow = ( 0 ⊕ 1) ⋅ ( 0 ⊕ 0) = 0
Overflow = ( 1 ⊕ 1) = 0

1.10 – SCALAMENTI

Dato un numero in base R, scalarlo verso sinistra di una posizione equivale a moltiplicarlo
per R mentre scalarlo verso destra, sempre di una posizione, equivale a dividerlo per R.

Capitolo 1 1.25
Appunti di CALCOLATORI ELETTRONICI 1

Nel caso del sistema binario (R=2) lo scalamento verso sinistra di un numero lo moltiplica
per 2, e comporta l’inserimento di 0 nella posizione che si libera. Cosi’ per es.
00110 (che corrisponde a 6 in base 10)
dopo lo scalamento diventa
001100 (che corrisponde a 12 in base 10).
La regola di esecuzione dello scalamento si complica se si deve tenere conto del segno,
dell’impiego eventuale di complementi e della condizione di overflow che si puo’ verificare
avendo a disposizione un numero prestabilito di cifre per rappresentare i numeri.

Lo scalamento verso destra di un numero binario equivale a dividere per 2 il numero,


ovviamente inserendo o nella posizione che si libera. In questo caso non si incorre in alcun
rischio di overflow e le uniche complicazioni derivano dalla presenza del segno o di
complementi. Va inoltre tenuto presente che, sempre a seguito della disponibilita’ di un
numero prestabilito di cifre, la divisione per 2 puo’ portare ad un troncamento con
conseguente approssimazione del valore. Per es. se si ha
00101
nello scalamento verso destra si ottiene, se si hanno a disposizione solo 5 cifre,
00010
e quindi dal valore 5 in base 10 si passa al valore 2.

Capitolo 1 1.26

Potrebbero piacerti anche