|
 |
Il Processore e il Debugger |
PROCESSORE 80x86 9/14
[20 di 60] |
 |
|
I Registri di Segmento - Indirizzi Logici e Indirizzi Fisici |
|
 | Il processore 8086 prevede 4
registri di segmento (Segment Registers); il loro nome è
CS, DS,
ES e SS, tutti
a 16 bit, indivisibili. |
 | Il concetto di segmento è presente in moltissime pagine di
questo sito per cui un link univoco all'argomento sembra impossibile; è più
semplice ribadire che si tratta di un'area di memoria di
65536 (64k) locazioni
consecutive, utilizzata dal sistema per allocare i programmi, in attesa di
ceder loro il controllo. |
 | A questo proposito è utile leggere l'argomento
Come viene trattato il file EXE dal Loader del DOS
del Capitolo 2, che sottolinea come una
importante caratteristica dei files EXE consiste
nel poter disporre di una quantità di memoria grande
fino a
4 segmenti, di solito, associati
al codice (e puntati con
CS), allo
stack (SS),
ai dati (DS) e
ad altri dati extra (ES). |
 | Risulta comunque chiaro che i
registri di segmento servono per individuare
le rispettive aree da 64k, nelle quali si svolgono attività
vitali per la vita dei programmi in esecuzione |
 | Un altro concetto chiave legato a questi registri è quello
di indirizzo logico e
indirizzo fisico. Il problema è sorto fin
dall'inizio: i progettisti dell'8086 si sono trovati a gestire un
bus d'indirizzi di 20 linee con
registri a 16 bit; in pratica era evidente
la necessità di porre un indirizzo valido sul rispettivo bus ma non era
possibile farlo perchè gli strumenti a disposizione (registri) erano troppo
piccoli. |
 | Da questa esigenza è nata la tecnica della
segmentazione della memoria, un abile
sotterfugio per poter puntare ogni indirizzo con 2
registri a 16 bit:
 | il primo (detto appunto registro
di segmento) individua un'area di 64kBytes consecutivi, dentro lo
spazio indirizzabile del processore, ed è uno di quelli descritti un questa
pagina. |
 | il secondo (detto registro di
offset) è in grado di scorrere ciascuna delle 65536 locazioni
contenute nel segmento, in virtù dei diversi possibili valori che può
assumere (essendo a 16 bit, 216=65536=64k), ed è uno di quelli
descritti della pagina seguente (per poter continuare la descrizione ne
prenderemo in prestito uno, il registro puntatore
d'istruzione IP). |
|
 | Dunque con un indirizzo logico,
cioè con una coppia di registri di tipo Segment:Offset,
per esempio CS:IP
(notare la forma con cui si esprime l' indirizzo logico) è
possibile ottenere un indirizzo fisico;
basta imparare il meccanismo che la CPU usa, internamente, per ricostruirlo. |
 |
L'indirizzo fisico (cioè il numero binario a
20 bit
che sarà posto sul bus
address) si ottiene
sommando
il valore di un registro di segmento moltiplicato per 16 con il
valore di un registro di offset; la coppia di registri a
16 bit
coinvolta nell'operazione può essere messa in evidenza nella forma
Segment:Offset, cioè nella forma tipica di un indirizzo logico. |
 | Da notare che, per rendere leggibili gli
indirizzi (sia
fisici che logici), è prassi
comune accorpare i bit
a 4 a 4, sostituendo ogni
quaterna con un simbolo del sistema di
numerazione esadecimale:
 | tali simboli sono sedici (appunto exadeci..): i numeri da
0 a 9
e le lettere da A a
F |
 | ciascuno di essi è dunque codificato da 4 bit (cioè è
codificato dall'unità di misura logica detta nibble
= 4 bit) |
 | così per esempio 00010010010001000000
(numero assurdamente illeggibile, espresso in binario) diventa
12440,
espresso in esadecimale |
 | per distinguere con certezza il tipo di codifica
utilizzato per esprimere l'informazione si aggiunge una
H (per Hexad...), cosicché
00010010010001000000
(binario) = 12440H
(in esadecimale) |
|
 | Lo schema seguente mostra questa tecnica: si osserva che
moltiplicare per 16 significa
aggiungere a destra
del valore esadecimale del registro di segmento
4 bit di valore nullo (un nibble
uguale a 0): |
|
Indirizzo fisico
(20 bit) = Registro di Segmentox16+Registro
di Offset |
|
Se CS=1234H
e IP=0100H
dall'indirizzo logico CS:IP si ricava l'indirizzo fisico:
CS*16 +
1234H*10H +
12340H +
IP =
0100H =
0100H =
----------------------------------
indirizzo fisico >>> 12440H |
 | Va sottolineato che, per ogni
indirizzo fisico, i valori dei 2
registri Segment:Offset
che concorrono a definire l'indirizzo logico
possono assumere numerosissime combinazioni (in pratica ben 65536..); lo
schema seguente mostra altre 5 possibilità: |
|
10000H
+
2440H =
---------
12440H |
11110H
+
1330H =
---------
12440H |
12000H
+
0440H =
---------
12440H |
11FF0H
+
0450H =
---------
12440H |
12440H
+
0000H =
---------
12440H |
 | La scelta dei valori da associare ai 2 registri è dunque
del tutto irrilevante; personalmente preferisco quella proposta per ultima,
nell'esempio precedente, che lascia nel registro di offset un numero
0000H e in quello di segment la parte
rimanente: è la proposta più vicina alla logica della memoria segmentata,
nella quale l'offset punta l'inizio (0000H)
del segmento a sua volta puntato dal segment (1244H). |
 | Per facilitare l'esercizio mentale legato a questa
conversione è disponibile l'eseguibile Calcola.COM,
che puoi
scaricare o
eseguire cliccando qui. |
 | Dei registri di offset
parleremo nella pagina successiva; in questa riassumiamo i compiti dei
4 registri di segmento; di solito
è il Loader (caricatore dei programmi in memoria) del
Sistema Operativo che
si occupa di caricare in questi registri i valori corretti per l'esecuzione
del programma stesso:
 | CS,
Code Segment: punta l'area di 64k
destinata a contenere i bytes del codice eseguibile, la traduzione in
linguaggio macchina delle nostre istruzioni; in ogni momento (insieme a
IP, come vedremo) punta il codice operativo
dell'istruzione che sta per essere eseguita. Non esistono istruzioni per
cambiarne direttamente il valore, sebbene la cosa sia possibile, in modo
indiretto, correttamente con JMP
, CALL
o RET
e impropriamente (e a rischio) con la coppia PUSH
rS / POP
CS . Se si desidera avere una copia del valore di CS, per
esempio in AX, possiamo usare senza danno la sequenza di istruzioni
PUSH CS / POP
AX . |
 | SS,
Stack Segment: punta l'area di 64k
destinata a contenere i bytes destinati allo
stack, l'area
nella quale il processore annota gli indirizzi a cui tornare in caso di
esecuzione di CALL
o INT
; in ogni momento (insieme a SP, come vedremo) punta
la prima locazione disponibile ad essere utilizzata. Modificare il valore di
questo registro è assurdo e sconveniente: il risultato è il probabile crash
del programma in esecuzione (se non del computer stesso). |
 | DS,
Data Segment: punta l'area di 64k
destinata a contenere i dati del programma in esecuzione e può essere
modificato senza rischio dal programmatore, per esempio con la sequenza di
istruzioni
MOV AX,nnnnH / MOV
DS,AX o con la coppia
PUSH AX / POP
DS ; numerose istruzioni danno per scontato che questo sia
il registro di segmento delle locazioni sorgente
( MOVS
, LODS
) dei dati da esse trattati. |
 | ES,
Extra Segment: punta l'area di 64k
destinata a contenere i dati del programma in esecuzione (oltre a quelli
puntati da DS)
e può essere modificato senza rischio dal programmatore, per esempio con la
sequenza di istruzioni
MOV AX,nnnnH / MOV
ES,AX o con la coppia
PUSH AX / POP
ES . Di solito è utilizzato per puntare particolari zone
di memoria: la sovrapposizione di un segmento ad una determinata area ne
facilita la gestione (si pensi per esempio alla
RamVideo);
numerose istruzioni danno per scontato che questo sia il registro di
segmento delle locazioni
destinazione ( MOVS
, STOS
) dei dati da esse trattati. |
|
 | Con l'avvento dei processori a 32
bit (cioè con bus dati interno, e quindi registri, a 32 bit), a partire
dal 80386, i sistemi hanno cominciato a
gestire la memoria con altre tecniche e il
problema della segmentazione ha perso
importanza; i registri di segmento sono
utilizzati in 2 diverse modalità, dette real mode e
protected mode. |
 | In ogni caso, poichè la parte
offset dell'indirizzo logico può
essere ora anche a 32 bit, ciascun segmento può arrivare alla dimensione di 4
GBytes. |
 | Il primo dei 2 modi (real mode, che si rifà alla descrizione
appena conclusa) è comunque garantito, per assicurare portabilità verso il
basso, e sarà da noi ampiamente utilizzato con soddisfazione, specialmente per
puntare le locazioni del primo mega di memoria,
straordinariamente ricco di informazioni e zone utili. |
 | Solo per completezza, a partire
dal 80386 sono disponibili altri 2 registri di segmento,
GS e FS,
comunque a 16 bit. |
©
2001-2010 - Studio Tecnico
ing. Giorgio OBER
Tutti i diritti sono riservati
|