Sei sulla pagina 1di 11

1 LA MEMORIA 1

Approfondimenti sulla memoria


Questo documento contiene approfondimenti sull’organizzazione della memoria. In particola-
re, viene esaminato il problema dell’indirizzamento degli integrati di memoria con riferimento
a differenti architetture (Intel, RISC, ..).

Sarò grato a chi mi segnalerà eventuali errori o suggerirà miglioramenti (giacomo.bucci@unifi.it)


Aggiornato il 1 ottobre 2013

1 La memoria
Con riferimento allo schema di Figura 1 si facciano queste assunzioni:
• La memoria è costituita da parole1 di ampiezza p bit, pari al grado di parallelismo del bus dei dati.
Ad ogni cella è assegnato un indirizzo univoco.
• La lettura/scrittura di una cella richiede la presentazione del suo indirizzo sul bus degli indirizzi.
Se m è il numero delle linee di indirizzo lo spazio di memoria è ampio M = 2m .
Si noti che abbiamo assunto che gli indirizzi siano assegnati alle parole, indipendentemente dal grado di
parallelismo2 . Al Paragrafo 1.1 modificheremo questa assunzione assegnando gli indirizzi ai byte.

Figura 1: Schematizzazione della memoria.

Di norma non tutto lo spazio di memoria viene utilizzato e, comunque, si può sempre presentare la
possibilità che occorra costruire un blocco di memoria di una certa dimensione a partire da una posizione
prestabilita.3 Supponiamo di disporre di integrati di memoria con parallelismo p, di dimensione B = 2b
(ovvero con b linee di indirizzo). Assumiamo che gli integrati presentino un piedino di abilitazione CS
(Chip Select). Con n integrati potremo costruire un blocco di memoria di nB parole contigue.
Un indirizzo di memoria può essere sempre considerato come composto da due parti: il numero
di blocco e l’indirizzo entro il blocco. Figura 2 mostra questa schematizzazione. Ne consegue che la
dislocazione naturale di un blocco di B parole all’interno dello spazio di memoria M è quella che lo alloca
ad un indirizzo di partenza multiplo di B (incluso lo 0), come schematizzato a sinistra in Figura 3.
Ciò equivale a immaginare lo spazio di memoria come suddiviso in blocchi della dimensione dell’in-
tegrato. Corrispondentemente l’indirizzo può essere cosı̀ interpretato: le linee di indirizzo Ab−1 − A0
rappresentano l’indirizzo entro il blocco, le linee Am − Ab identificano il blocco. Ne consegue che le linee
Ab−1 − A0 vanno portate ai piedini degli indirizzi dell’integrato, mentre le restanti verranno decodificate
in modo da selezionare l’integrato attraverso il piedino CS.
1A volte si usano anche i termini “celle”,“posizioni” e “locazioni”
2 Da questa convenzione segue che una memoria a 8 bit di ampiezza M contiene M byte, mentre una memoria a 32 bit
di ampiezza M contiene 4M byte.
3 È il caso della memoria ROM contenete il codice di inizializzazione del sistema.
1 LA MEMORIA 2

Figura 2: Interpretazione dell’indirizzo di una parola.

Figura 3: Interpretazione dell’indirizzo e schematizzazione del problema della selezione e


dell’indirizzamento.

Vale solo la pena di osservare che, se con integrati di capacità B volessimo costruire un blocco di
memoria a partire da un indirizzo non multiplo di B, saremmo nella situazione schematizzato nella parte
destra di Figura 3, dove si è supposto di allocare l’integrato di capacità B a cavallo tra il blocco 0 e
il blocco 1 nello spazio degli indirizzi. La selezione comporta il riconoscimento del blocco di indirizzi
corrispondente alla dislocazione dell’integrato (si vedano a tale scopo gli Esercizi 10.7, 10.10 e 10.12 del
testo). La soluzione ovvia per costruire un blocco di memoria ampio B a partire da un indirizzo non
multiplo di B consiste nell’usare integrati di taglia inferiore, in modo che essi vengano allocati in modo
“naturale” nello spazio di memoria. Con riferimento all’esempio di Figura 3 si tratta di usare due integrati
di capacità B/2. Ovviamente questi integrati avranno b − 1 linee di indirizzo, mentre il bit b − 1 (che
prima faceva parte dell’indirizzo all’interno dell’integrato) andrà a far parte degli ingressi della logica di
selezione dell’integrato.

1.1 Lo standard: l’indirizzamento al byte


Sopra si è assunto che gli indirizzi fossero assegnati alle parole. Nella pratica corrente gli indirizzi sono
assegnati ai byte. Il motivo è ovvio: mantenere la stessa modalità di indirizzamento nell’evoluzione
architetturale, per esempio nel passare da un parallelismo a 16 a un parallelismo a 32 bit. Assegnare
gli indirizzi ai byte permette la piena compatibilità almeno per quanto riguarda l’indirizzamento dei
programmi.
Per esempio, con riferimento all’architettura ×86, l’istruzione mov ax,mem ha la stessa codifica su
8088, 80886, 80386, ecc., sebbene si tratti di macchine aventi differente parallelismo. Se gli indirizzi
fossero stati associati alle parole corrispondenti alla dimensione del bus, il campo mem avrebbe dovuto
essere dimezzato nel passare dall’8088 all’8086, come pure nel passare dall’8086 all’80386. In altre parole
la codifica di macchina sarebbe stata differente, rendendo i programmi non portabili.
D’ora in avanti assumeremo che gli indirizzi siano associati ai byte.
Per semplicità nella parte che segue, nella costruzione dei banchi di memoria, faremo riferimento
a integrati Byte-wide (l’impiego di altri formati non comporta complicazioni concettuali; si veda per
esempio l’esercizio 10.9).
2 PARALLELISMO 3

2 Parallelismo
2.1 Parallelismo di 1 byte
La forma più semplice di memoria è quella con parallelismo a 8 bit. I microprocessori della prima gene-
razione (8080, Z80, 6800) avevano tipicamente un bus dati a 8 bit. Lo schema della memoria corrisponde
è esattamente a quello di Figura 3 dove si devono assumere parole di 8 bit.

Esempio 1
In una memoria a 8 bit e capacità di 1 MB, i blocchi di 256 KB hanno come posizioni naturali quelle
che iniziano agli indirizzi 0, 256 K, 512 K, 768 K. L’indirizzo entro il blocco è dato attraverso le linee
A17 − A0 , mentre le linee A19 − A18 servono a specificare il blocco. Per esempio, il blocco di memoria 1
(quello che va dall’indirizzo 256 K all’indirizzo 512-1 K) viene selezionato con CS1 = A19 · A18 .

2.2 Parallelismo superiore al byte


In Figura 4, viene schematizzata una memoria a 32 bit, ovvero con un parallelismo di 4 byte. Stabiliamo
la convenzione di denotare con il termine “parola” il numero di bit (o byte) corrispondenti all’ampiezza
del bus4 .
Lo schema di figura è rigido, nel senso che i byte di una fascia verticale della memoria transitano
sempre sulla medesima corsia del bus dati. Faremo riferimento a questo schema, anche se più avanti
verrà fatto un accenno alla soluzione generale in cui questa è rimossa, con possibilità di transito su
qualunque corsia da parte di qualunque byte.

Figura 4: Schematizzazione di una memoria a 32 bit. Si è assunta la convenzione little endian. Tra
parentesi sono indicati i numeri di parola. La parola 1 è all’indirizzo 4, la parola 2 è all’indirizzo 8, ecc.

Con una macchina avente parallelismo pari a k byte, con k potenza del 2, si dice che una parola di
memoria è allineata se il suo byte meno significativo è a un indirizzo multiplo di k (nel caso di figura: 0,
4, 8, 12, ·· ). L’indirizzo di un byte può essere interpretato come il numero d’ordine della parola più lo
scostamento del byte entro la parola, come schematizzato in Figura 5. Seguendo la schematizzazione di
Figura 5, le linee Am−1 − Ak contengono il numero d’ordine della parola5 .
Alternativamente si può guardare la memoria come divisa in k fasce verticali (di parallelismo 1 byte)
e riguardare il numero su Am−1 − Ak come l’indirizzo effettivo del byte nella fascia considerata.

Problemi posti dal parallelismo


Con il parallelismo è superiore ad 1 (byte) si pongono alcuni problemi relativamente a:
4 Con riferimento all’architettura Intel, l’8088 aveva il bus dati a 8 bit; l’l8086 e il 286 a 16 bit; il 386 e il 486 a 32 bit.

Dal Pentium il parallelismo è passato a 64 bit, anche se per molto tempo i registri interni sono rimasti a 32 bit. Per motivi
storici, Intel e gli altri produttori di Micro di architettura ×86 designano come parola i 16 bit, come doppia parola i 32 bit
e come quadrupla parola i 64 bit.
5 Formalmente si tratta del numero d’ordine della parola, nella pratica si parla di indirizzo di parola. Qui e nel seguito,

quando non c’è rischio di confusione, parleremo di indirizzo di parola intendendo riferirci al numero d’ordine della parola
stessa. In Figura 5 l’effettivo indirizzo di parola sarebbe dato dal numero d’ordine della parola e due “0” alla sua destra.
3 INTERFACCIA CON LA MEMORIA 4

Figura 5: Interpretazione dell’indirizzo di un byte come numero d’ordine del byte entro la parola. A sua
volta la parola è individuata attraverso il suo numero d’ordine entro un blocco.

• Possibilità di leggere/scrivere non solo a parole, ma anche a frazioni (in byte) di parole (con
riferimento alla Figura 4: un byte, una semiparola (16 bit) o una parola).
• Possibilità di trasferire parole (o semiparole) non allineate.

• Possibilità di trasferire la frazione di parola di memoria in/da differenti porzioni di registri di CPU.
In ogni caso, risulta evidente che, quando è possibile il trasferimento di una frazione di parola, in
appoggio al bus degli indirizzi occorrono ulteriori linee di controllo per selezionare gli specifici byte da
leggere/scrivere.
Nel paragrafo 3 vengono esposte differenti soluzioni in riferimento ai tre punti precedenti, .

3 Interfaccia con la memoria


3.1 Lettura/scrittura di dati allineati
Facciamo riferimento a una macchina di tipo RISC a 32 bit, ovviamente con registri a 32 bit. Assumiamo
che le istruzioni siano sempre su parole allineate e che le letture/scritture avvengono sempre per parole
allineate, per semiparole allineate o per byte.
Le istruzioni di lettura siano cosı̀ schematizzabili:

• LDW: trasferisce in un registro di CPU la parola contenuta nella locazione indirizzata (indirizzo
multiplo di 4); schematicamente: R31−0 ← mW, dove R31−0 rappresenta i 32 bit del (generico) registro
R, mentre mW rappresenta la parola di memoria (allineata) indirizzata.
• LDH: trasferisce nella parte bassa di un registro di CPU la semi parola contenuta nella locazione
indirizzata (indirizzo multiplo di 2); la parte alta del registro viene azzerata; schematicamente:
R31−16 ← 0 e R15−0 ← mH, dove mH rappresenta la semi parola di memoria (allineata) indirizzata.

• LDB: trasferisce negli 8 bit meno significativi di un registro di CPU il byte indirizzato (indirizzo
qualunque); i restanti bit del registro vengono azzerati; schematicamente: R31−8 ← 0 e R7−0 ← mB,
dove mB rappresenta il byte di memoria indirizzato.
(Si noti che, dal punto di vista della memoria, le operazioni di fetch equivalgono a LDW.)
Le istruzioni di scrittura siano cosı̀ schematizzabili:
• STW: trasferisce il contenuto di un registro di CPU nella parola indirizzata (indirizzo multiplo di
4); schematicamente: mW ← R31−0 .

• STH: trasferisce la parte bassa di un registro di CPU nella semi parola indirizzata (indirizzo multiplo
di 2); schematicamente: mH ← R15−0 .

• STB: trasferisce li 8 bit meno significativi di un registro di CPU nel il byte indirizzato (indirizzo
qualunque); schematicamente: mB ← R7−0 .

Qualunque sia l’entità trasferita, alla memoria viene trasmesso l’indirizzo di parola, cioè i bit A31 − A2
e altri segnali di controllo per individuare la dimensione e la specifica entità trasferita.
Si può stabilire che la CPU, in base all’operazione effettuata, generi due segnali, ENW (Enable Word )
e ENH (Enable Halfword ), di cui la Tabella 3.1 specifica la combinazione dei valori in rapporto alla
3 INTERFACCIA CON LA MEMORIA 5

Entità di memoria trasferita ENW ENH


Byte 0 0
Word 1 0
Halfword 0 1
Non permesso 1 1

Tabella 1: Codifica dei segnali ENH e ENW in rapporto all’indirizzamento delle differenti entità di
memoria. La combinazione 11 non è consentita. Ovviamente ENW è asserito su le istruzioni LDW e
STW e sulle operazioni di fetch; ENH sulle istruzioni LDH e STH.

dimensione del dato trasferito; il posizionamento dell’entità trasferita è invece determinato dai bit A1 e A0
dell’indirizzo.
La logica per i trasferimenti è schematizzata in Figura 6 e Figura 7. Esse evidenziano il bus interno
e il bus esterno dei dati. Lettura/scrittura da/in memoria richiedono che i dati vengano incanalati dalla
sorgente alla destinazione posizionandoli secondo la precedente convezione circa gli effetti delle specifiche
istruzioni LD/ST. Per non appesantire le due figure si è evitato di riportare i necessari AND di ENW e
ENH con i comandi di lettura della memoria (RDM) e di scrittura della memoria (WRM), generati dalla
CPU, al pari dei segnali ENW e ENH, nell’esecuzione delle istruzioni LD/ST.
La Figura 6 mostra la logica relativa alle operazioni LD. e Si può osservare che un’operazione di lettura
può essere sempre eseguita come lettura dell’intera parola, con selezione della porzione da trasferire e suo
incanalamento verso la parte bassa del registro di destinazione nel passaggio da bus esterno a bus interno.
Per la lettura dell’intera parola basta che il comando di lettura della memoria (RDM) facia asserire tutti
i chip select degli integrati relativi alle 4 fasce.
Nel caso delle operazioni di scrittura (Figura 7), la situazione è più complessa, in quanto, ad esempio,
la scrittura di un byte deve andare a modificare il contenuto dello specifico byte indirizzato e non l’intera
parola di memoria. Ovvero, occorre asserire selettivamente i chip select delle fasce contenenti i byte da
aggiornare. Con riferimento alla Figura 7 sono possibili due diversi tipi di soluzione:

1. Si portano alla memoria le due linee ENW e ENH, ma anche le linee A0 e A1 e si ricostruisce la
rete che asserisce opportunamente i CS relativi alle quattro fasce.

2. Dalla CPU si fanno uscire direttamente quattro segnali di controllo, che denomineremo BE3 , BE2 ,
BE1 , BE0 , che selezionano, rispettivamente, la fascia dalla più significativa alla meno significativa.
Questi segnali di controllo vengono generati da una rete equivalente a quella del punto precedente,
con la differenza che tale rete è parte della CPU.

Nelle macchine di tipo RISC si preferisce la prima soluzione. La seconda soluzione è tipica dell’architettura
×86 e viene utilizzata anche per le operazioni di lettura.
Vale la pena di trovare l’espressione dei BEi in funzione di ENW, ENH, A1 e A0 . A titolo di esempio
consideriamo BE1 , assumendo che i 4 segnali in questione siano coerenti in uscita dalla CPU, ovvero
assumendo che:

a) la configurazione ENW= 1, ENH= 1 non si presenti mai;


b) in presenza di ENW, allora sicuramente A1 = 0, A0 = 0, ovvero l’indirizzo è quello di una parola
allineata;
c) in presenza di ENH, allora sicuramente la coppia (A1 A0 ) vale (0 0) o (1 0), ovvero l’indirizzo è
quello di una semiparola allineata.

In queste ipotesi

BE1 = EN W + EN H · A1 · A0 + EN W · EN H · A1 · A0
= EN W + EN H · A1 · A0 + EN H · A1 · A0
3 INTERFACCIA CON LA MEMORIA 6

Le espressioni per gli altri BEi si calcolano in modo analogo6 .

3.2 Entità di memoria non allineate


Sebbene l’allineamento sia spesso consigliato per motivi di efficienza, molte architetture consentono il
trasferimento di dati non allineati. Un tipico esempio è l’architettura ×86 alla quale faremo riferimento
in questo paragrafo, considerando in particolare il caso di bus a 32 bit (386 e 486).
Si consideri l’istruzione mov eax,m32 che ha l’effetto di portare nel registro eax la parola di 32 bit
che ha il suo byte meno significativo all’indirizzo simbolico m32. Non è richiesto che questo indirizzo
sia un multiplo di 4, ovvero che la parola sia allineata. Con riferimento alla Figura 4, se per esempio
l’indirizzo è un multiplo di 4 più 1, la parola avrà 3 byte all’indirizzo m32, mentre il quarto byte (quello
più significativo si troverà nel byte meno significativo della successiva parola allineata, ovvero all’indirizzo
m32+3; se l’indirizzo è un multiplo di 4 più 3, la parola avrà il byte meno significativo della posizione più
significativa della parola allineata indirizzata e i tre byte più significativi nelle tre posizioni a destra della
successiva parola allineata (che si trova all’indirizzo m32+1).
Analoghi ragionamenti si applicano per le semiparole (e.g. istruzione mov ax,m16). Esse possono trovarsi
nei due byte centrali di una parola allineata oppure a cavallo (ma contigui) tra due parole (allineate)
contigue.
Nell’eseguire, per esempio, l’istruzione mov eax,m32 a un indirizzo non multiplo di quattro, si
rendono necessari due cicli di lettura della memoria: un primo ciclo per leggere la porzione (1, 2 o 3
byte) che corrisponde alla parte meno significativa della parola, un secondo ciclo per leggere la porzione
(rispettivamente 3, 2 o 1 byte) che corrisponde alla parte più significativa della parola. Poiché la struttura
della memoria è quella di Figura 4, la prima porzione, letta nella parte più significativa del bus, deve
essere portata nella parte meno significativa del registro, mentre la seconda porzione, letta nella parte
meno significativa del bus, deve essere portata nella parte più significativa del registro. In altre parole si
rende necessario il riordino di quanto letto in due tempi per formare la parola da trasferire nel registro.
Al Paragrafo 3.1 si è supposto che i trasferimenti di un byte interessassero sempre il byte meno
significativo del registro di CPU coinvolto e che il trasferimento di una semiparola interessasse sempre la
metà meno significativa del registro. L’architettura ×86 ha un pizzico di flessibilità in più nel senso che è
possibile trasferire un byte anche in AH (BH, CH, ..) oltre che in AL (BL, CL, ..). Non è però possibile
coinvolgere nel trasferimento di un byte i due byte più significativi di un registro, né, tantomeno, nel
trasferimento di 16 bit non è possibile coinvolgere la metà più significativa dei registri a 32 bit. Questa
minimo di flessibilità in più ha ragioni storiche, derivando dall’originale repertorio 8086/88, che appunto
prevedeva il trasferimento di byte indifferentemente da/verso il byte più significativo dei registri a 16 bit.
Nella versione a 64 bit, si possono ancora effettuare i trasferimenti di 8, 16, 32 bit nella porzione a destra
dei registri di 64 bit. Nel caso del trasferimento di 8 bit è ancora possibile usare AH (BH, CH, ..), ma
con qualche limitazione dovuta al fatto che non è possibile codificare tutti i possibili trasferimenti verso
AH quando la macchina lavora in modalità 64 bit7 .
In conclusione, rispetto al parallelismo dei trasferimenti tra registri e memoria, l’architettura ×86,
nella versione 64 bit, prevede questi classi di trasferimento (esemplificate in riferimento all’istruzione
“mov” e al registro A)
mov al,m8
mov ah,m8
mov ax,m16
mov eax,m32
6 Si noti che per garantire la coerenza tra i 4 segnali ENW, ENH, A e A la CPU deve essere equipaggiata con la logica
1 0
corrispondente. Vale la pena approfondire questo aspetto. In base alle ipotesi fatte circa il funzionamento della nostra
CPU, in corrispondenza di ogni indirizzamento (fetch, istruzioni load e store):
• per le operazioni di fetch e per le istruzioni (LDW/STW) deve essere A1 = 0, A0 = 0;
• per le istruzioni (LDH/STH) deve essere A1 = 0, A0 = 0, oppure A1 = 1, A0 = 0.
Per le istruzioni (LDB/STB) non ci sono vincoli su A1 e A0 .
Assumiamo che se le precedenti condizioni non sono verificate la logica di CPU generi l’eccezione EccAllnm (eccezione di
allineamento). La condizione di eccezione è dunque esprimibile in questo modo.

EccAllnm = ENW · (A1 · A0 ) + ENH · (A1 · A0 + A1 · A0 ) = ENW · (A1 + A0 ) + ENH · A0


Si noti che allo stesso risultato (EccAllnm = ENW · (A1 + A0 ) + ENH · A0 ) si perviene direttamente se si ragiona sulle
condizioni che devono verificarsi per avere l’eccezione.
Se l’eccezione EccAllnm non si verifica, i quattro segnali ENW, ENH, A1 e A0 , presentati all’esterno dalla CPU, sono
coerenti.
7 Ci riferiamo alla cosiddetta architettura 64 bit ottenuta come estensione di IA-32.
3 INTERFACCIA CON LA MEMORIA 7

Figura 6: Schema per il caricamento dalla memoria di una parola, una semiparola o un byte con ri-
ferimento all’architettura ipotizzata all’inizio del paragrafo 3.1 (la numerazione è little endian). Si fa
l’ipotesi di leggere sempre una parola allineata. Per non appesantire la figura si è evitato di riportare il
comando di lettura (che ovviamente è in AND con ENW e ENH). Il dato viene messo sul bus interno
dopo essere stato selezionato tramite i segnali ENW e ENH (Tabella 3.1). Il segnale di ENW comanda il
trasferimento di un’intera parola. Quando si richiede il trasferimento di una semiparola e asserito ENH,
mentre ENW è disasserito. In tal caso il buffer con uscita a 16 bit mantiene a zero i 16 bit più significativi
sul bus interno, mentre ENH abilita il trasferimento sulla metà bassa del bus interno della semiparola
selezionata tramite A1 . Se ambedue i segnali ENW e ENH sono disasseriti, il byte selezionato in base
al valore di A0 e A1 , viene trasferito sulle linee D7−0 , mentre vengono portati a 0 anche i bit D15−7 .
Ovviamente, la combinazione 11 per ENW, ENH non è consentita: la logica di macchina deve garantire
che tale combinazione non si possa mai manifestare.
3 INTERFACCIA CON LA MEMORIA 8

Figura 7: Schema per la memorizzazione di una parola, una semiparola o un singolo byte (la numerazione
è little endian). Si tratta dello schema duale di quello di Figura 6. Per non appesantire la figura si è
evitato di riportare il comando di scrittura (che è ovviamente sottinteso, ovvero in AND con ENW e
ENH). Per selezionare il dato da scrivere in memoria, si usano gli stessi segnali di controllo usati per
la lettura. I segnale ENW e ENH hanno il significato di Tabella 3.1. A differenza della lettura, nel
caso di scrittura occorre necessariamente trasmettere A0 e A1 , oltre che ENW e ENH, alla memoria per
selezionare la porzione di parola da scrivere.
3 INTERFACCIA CON LA MEMORIA 9

mov rax,m64
Una CPU ×86, ad ogni ciclo di lettura/scrittura della memoria asserisce i segnali che selezionano
la striscia verticale su cui leggere. Nell’8086 e 286, le due fasce erano individuate dal segnale BHE e
dal bit A0 dell’indirizzo. Nel 386 e nel 486 attraverso i 4 segnali BE3 , BE2 , BE1 , BE0 . A partire dal
Pentium il bus dati è diventato a 8 byte, per cui il bus indirizzi è diventato A31 − A3 , mentre le linee di
selezione di fascia sono diventate 8 (BE7 , BE6 , ··, BE0 )8 . Si noti che, diversamente da quanto ipotizzato
al Paragrafo 3.1 e in particolare in Figura 6, i segnali BE sono asseriti anche sulle operazioni di lettura.
Essi identificano le sezioni del bus che, in un trasferimento, contengono dati validi.
Con riferimento alla Figura 4, si supponga di dover leggere la parola (32 bit) non allineata che inizia
all’indirizzo 9, come schematizzato in Figura 8. Cioè supponiamo che si abbia l’istruzione
mov eax, <9>
essa determina due cicli di lettura:

a) nel primo ciclo, sul bus degli indirizzi (A31 −A2 ) viene asserito il numero 2 e vengono asseriti BE3 ,
BE2 e BE1 ;
a) nel secondo ciclo, sul bus degli indirizzi (A31 −A2 ) viene asserito il numero 3 e il solo BE0 .

Figura 8: La parola formata dai byte B3, B2, B1 e B0 non è allineata. L’ipotesi di figura è che la parola
inizi all’indirizzo (di byte) 9. Ovvero, il byte meno significativo (B0) si trova in posizione 1 nella parola
(di indirizzo) 2, mentre il byte più significativo è nella posizione 0 alla parola 3.

In Figura 9 viene schematizzato il meccanismo di posizionamento dei byte in ingresso alla CPU (cioè
per le letture). Nell’architettura ×86 il riordinamento delle porzioni di parola non allineata, lette/scritte
in due fasi, è interamente svolto all’interno della CPU.

Figura 9: Schematizzazione del meccanismo di posizionamento dei byte.

In passato sono state costruite macchine che, pur prevedendo l’indirizzamento di parole non allineate,
lasciavano la ricostruzione della parola alla logica esterna (al controllore di memoria)9 .
8 Vale la pena di osservare che fino all’introduzione della modalità di funzionamento a 64 bit, i registri di CPU erano 32

bit, mentre dal Pentium in poi il bus era a 64 bit. Non stupisca la differenza tra parallelismo dei registri e parallelismo del
bus dati. Di fatto la CPU legge/scrive, di norma in cache. Dunque il bus a 64 bit serviva ad aumentare la banda passante
tra memoria e cache. Peraltro la CPU (Pentium e successive), per quanto si riferisce alle operazioni di fetch delle istruzioni,
legge dalla cache parole di 128 bit.
9 La CPU comandava una sola operazione di lettura/scrittura e attendeva che il controllore esterno (al quale spettava il

compito di incrementare l’indirizzo di parola) compisse l’intera operazione.


3 INTERFACCIA CON LA MEMORIA 10

Dimensione Abilitazione Corsie del bus attive


dato SIZ1 SIZ0 A1 A0 D31−24 D23−16 D15−8 D7−0
Byte 0 1 0 0 B − − −
0 1 0 1 − B − −
0 1 1 0 − − B −
0 1 1 1 − − − B
Semi 1 0 0 0 B B − −
Parola 1 0 1 0 − − B B
Parola 0 0 − − B B B B
Linea 1 1 − − B B B B

Tabella 2: Trasferimenti tra CPU e memoria e loro codifica per la CPU 68040.

Oggi i manuali Intel raccomandano vivamente di allineare le parole (quelle di 64 bit a indirizzi multipli
di 8, quelle a 32 a indirizzi multipli di 4, quelle a 16 bit a indirizzi multipli di 2). Vengono forniti numeri
impressionanti (cicli di clock persi) circa il peggioramento delle prestazioni a causa del non allineamento.

3.3 Altre soluzioni architetturali


Architettura 68000
Per l’esattezza, ci riferiamo al modello 68040. Si tratta di una CPU a 32 bit, con bus dati e indirizzi a
32 bit. Nei trasferimenti con la memoria la CPU asserisce, oltre all’intero indirizzo sulle linee A31 −A0 ,
due segnali SIZ1 e SIZ0 che danno la dimensione del dato trasferito. Questi ultimi due segnali, assieme
a A1 e A0 vengono collettivamente indicati come segnali di “abilitazione” dei byte. La Tabella 2 illustra
la loro interpretazione.
Si noti che:

• I singoli byte, com’è ovvio, possono essere trasmessi su qualunque corsia del bus dati.

• Le semi parole possono essere trasmessi sulla parte alta o sulla parte bassa.
• La parola occupa le 4 corsie.

Inoltre

• La configurazione SIZ1 = SIZ0 = 0 rende A1 e A0 irrilevanti e determina il trasferimento di una


parola allineata (individuata tramite A31 −A2 ).

• La configurazione SIZ1 = SIZ0 = 1 (per la quale A1 e A0 sono pure irrilevanti) viene impiegata per
comandare il trasferimento di una parola nella lettura di una linea da portare in cache10 .

• Infine si faccia attenzione alle corsie del bus associate alle codifiche di A1 , A0 .
Con la precedente codifica delle abilitazioni se una parola non è allineata a un indirizzo pari, occorrono
tre cicli di lettura/scrittura. Con riferimento all’esempio di Figura 8, occorre:
a) un primo ciclo per trasferire il byte B0;

b) un secondo ciclo per trasferire la semiparola formata dai byte B2 e B1;


c) un terzo ciclo per trasferire B3.

PowerPC
Per l’esattezza, ci riferiamo al modello 601, ma quanto detto vale per tutte le CPU della famiglia. Si
tratta di una CPU RISC con registri interni a 32 bit, bus indirizzi a 32 bit e bus dati a 64 bit.
Sebbene si tratti di una macchina RISC c’è alta flessibilità nei trasferimenti. A tale scopo la CPU
trasmette all’esterno un indirizzo su 32 bit e tre segnali SIZ2 , SIZ1 e SIZ0 , usati per dare la dimensione del
10 La cache ha linee di 16 byte (4 parole). Il trasferimento di una linea avviene di norma in burst mode, ma ci sono delle

situazioni in cui è possibile che il trasferimento avvenga come una successione di 4 (normali) letture della memoria. Su tali
letture viene asserita la configurazione SIZ1 = SIZ0 = 1
3 INTERFACCIA CON LA MEMORIA 11

dato trasferito. Questi tre segnali, combinati con i tre bit meno significativi del bus indirizzi determinano
esattamente cosa viene trasferito in un ciclo di accesso alla memoria. Sono possibili trasferimenti da 1
a 8 byte. Trasferimenti di 16, 32 o 64 bit non allineati comportano due cicli di lettura/scrittura se la
quantità trasferita attraversa un confine di allineamento a 64 bit.