02 gennaio 2004
 |
|
Perchè utilizzare il Segment-override
CS: |
|
 | La scrittura di un sorgente ASM
non può fare a meno di definire variabili,
tabelle,
testi...
 | nella realizzazione di
eseguibili di tipo EXE
è prevista per default la disponibilità di 4 distinti
segmenti (cioè aree da 64k, 65536
locazioni consecutive di memoria) e, a questa categoria di informazioni, è
destinato per intero uno di questi, puntato
dal registro di segmento
DS (i rimanenti
segmenti sono destinati al codice
eseguibile (=istruzioni), allo stack
e agli
ExtraDati, puntati rispettivamente
dai registro CS,
SS e
ES) |
 | la creazione di
eseguibili di tipo COM,
tipica di ogni sorgente pubblicato su questo sito, prevede per default
la presenza di un unico segmento,
imponendo in esso l'insindacabile presenza di tutti e 4 i tipi d'informazione;
la logica conseguenza di questo fatto si riflette nel valore dei 4 registri
di segmento, ora ovviamente uguali tra loro, CS=DS=ES=SS |
|
 |
In ogni caso
(EXE o COM) è il registro DS
quello chiamato a puntare (e quindi localizzare) gli indirizzi delle etichette
di
variabili, tabelle,
testi...o , più genericamente, dei
dati del programma assembly. |
 |
In conclusione:
 |
in condizioni di default
(cioè senza alcuna aggiunta specifica
al sorgente), se si scrive l'istruzione MOV
AL,[SI] il compilatore
sarà costretto ad utilizzare il registro
DS
per
codificare gli indirizzi del dato
puntato da SI, dando per scontato che
l'effettivo puntatore logico completo sia DS:SI |
 | le istruzioni MOV
AL,[SI]
e MOV
AL,DS:[SI] sono
dunque logicamente identiche, nel senso che il codice
macchina generato sarà il medesimo, nell'esempio i 2 bytes
8A04 |
 | la presenza il segment-override
DS:
è dunque di norma irrilevante, a maggior ragione nei sorgenti chiamati a
generare un eseguibile COM, nella gestione del quale il segmento
Dati (puntato da
DS)
coincide con il segmento Codice
(puntato da CS=DS)
|
|
 | Ma veniamo al nocciolo della discussione... |
 | Per una scelta personale
(probabilmente discutibile, come spesso
accade per le posizioni intellettuali schierate) ho deciso di utilizzare il segment-override
CS: per puntare,
all'interno dell'unico segmento
previsto dalla creazione di
eseguibili di tipo COM, le locazioni di
memoria destinate ad ospitare le variabili;
di fatto esse:
 | sono inserite all'interno
del codice, subito dopo la prima istruzione, di solito un
JMP main,
con l'etichetta main
ad indicare l'inizio effettivo del
programma principale |
 | sono dunque parte integrante dell'informazione puntata
dal registro di segmento
CS |
 | sono comunque associate dal compilatore al
registro di segmento
DS,
in questo caso assolutamente uguale a CS |
|
 |
La scelta di forzare (con l'intervento dell'override
CS:)
il puntatore delle
variabili da DS:<indirizzo>
a CS:<indirizzo>
è dunque sostanzialmente inutile, se
l'obiettivo è quello di realizzare un eseguibile di tipo COM. |
 | Dunque sembrerebbe una scelta
scriteriata... |
 | In realtà, consapevoli che, in sua assenza, il compilatore
genererebbe un codice che obbliga il processore ad usare il
registro
DS
per puntare le variabili,
pur costando un byte di codice macchina ogni volta che viene
utilizzata, essa può rivelarsi importante
almeno in 2 casi: se il codice COM prodotto
è relativo ad un programma TSR (cioè
lasciato parzialmente in memoria anche quando
è terminato) oppure ad un oggetto di libreria
(cioè è al corpo di una Procedura). |
 | In entrambi i casi quando il codice sarà in esecuzione non
si ha la certezza che il contenuto del
registro di segmento
DS sia ancora uguale a
CS, specialmente nel secondo caso. |
 |
Se non ci fosse
l'override
CS:
le locazioni delle
variabili (come detto
incluse tra le istruzioni) non verrebbero trovate (perchè cercate
in un segmento diverso (DS) da quello in cui sono
effettivamente presenti) provocando sicuri malfunzionamenti o,
addirittura, il blocco del computer. |
|