|
 |
Le
PseudoOperazioni di MASM |
SCHEDA n° 02 [
19
di 26] |
Aggiornato 02 gennaio 2004
e 11 aprile 2006
 |
|
Gestione dei Segmenti - ASSUME
e Segment-override |
|
 | Con il concetto di segment-override
andiamo a rivisitare le nozioni relative all'influenza di ASSUME
sul codice creato per l'indirizzamento delle variabili. |
 | Per evitare malintesi
ricordo che la posizione logica
delle locazioni di memoria destinate alle
variabili dipende dal tipo di eseguibile realizzato:
 | se di tipo EXE (plurisegmentale)
alle variabili, di norma, è
destinata un'intera area di memoria da 64k (segmento) puntata per default
dal registro
DS |
 | se di tipo COM (intasegmentale)
le variabili sono inserite inevitabilmente
nell'unico segmento disponibile in
questo caso, chiamato a servire sia il codice, sia i dati, sia lo stack
(definito con l'etichetta _prog, nei miei
sorgenti); le variabili sono
ancora puntate per default dal registro
DS ma poichè il segmento è unico, tutti i
registri di segmento puntano ad esso (CS=DS=ES=SS),
per cui potrebbero essere localizzate anche con
CS... |
|
 |
In condizioni di default
(cioè senza alcuna particolare aggiunta al sorgente) il compilatore usa il registro DS per
codificare gli indirizzi delle etichette di
dato; le istruzioni
MOV
AL,[SI] e MOV
AL,DS:[SI] sono
dunque logicamente identiche, nel senso che il codice
macchina generato sarà il medesimo (8A04)
rendendo pleonastica la presenza dell'override DS: |
 | Vediamo ora in che misura influisce la (eventuale) presenza
della direttiva ASSUME
e della tecnica di segment-override;
analizziamo i vari casi con l'aiuto di Debug:
 | Nessuna direttiva ASSUME:
il riferimento esplicito al
simbolo (=etichetta) ,[#],
è codificato come se avesse override
DS:
a conferma del fatto che, per default, le variabili sono codificate come
se fossero nel segmento dati (indirizzato per default da
DS);
la forzatura esplicita con l'override
CS:,[*],
obbligherà il processore a puntare il
dato con il nuovo registro di segmento, con il costo di un
byte macchina
in più (2EH):
MAIN: MOV AL,[ATTRIB] [#]
MOV AL,DS:[ATTRIB]
MOV AL,CS:[ATTRIB]
[*] |
A00301 MOV
AL,[0103]
A00301 MOV AL,[0103]
2EA00301 MOV AL,CS:[0103] |
|
 | Dichiarazione di ASSUME
CS:_prog: in realtà, per evitare la
segnalazione d'errore, non possiamo fare a
meno di dichiarare almeno questa assegnazione; la sua presenza
obbligherà
l'assemblatore a codificare ogni riferimento al simbolo
senza override,[#],
come se avesse override
CS:.
Sebbene ci costi un byte macchina in più (2EH)
la cosa è desiderabile e da'
sicurezza perchè garantisce che il processore troverà
il nostro dato in ogni situazione; possiamo sottolineare inoltre che la
scrittura esplicita dell'override
CS:non costa nulla di più, per cui
conviene abituarci a scrivere l'istruzione in questo modo, [*].
In questo caso la dichiarazione esplicita dell'override
DS:
([@])
ci permette di risparmiare un byte macchina, ma può rendere precario il
rilevamento del dato (vedi nota dedicata):
MAIN: MOV AL,[ATTRIB] [#]
MOV AL,DS:[ATTRIB]
[@]
MOV AL,CS:[ATTRIB]
[*] |
2EA00301
MOV AL,CS:[0103]
A00301 MOV AL,[0103]
2EA00301 MOV AL,CS:[0103] |
|
 | Dichiarazione di ASSUME
CS:_prog, DS:_prog: questa
scelta è
solo in apparenza contraddittoria; entrambi
i registri di segmento CS e
DS sono chiamati, in sequenza, a diventare
riferimento per le etichette del segmento _prog,
quindi quello che prevale sembra essere DS (così come sembra inutile,
dunque, dichiarare prima CS). In realtà con questa
sequenza di dichiarazioni
CS si occuperà
delle etichette con i 2 punti, associate agli entry-point
(indirizzi near) presenti nelle
istruzioni del programma, mentre
DS , definito per ultimo, sarà
usato per codificare gli indirizzamenti alle variabili di _prog.
Come nel caso di default, il riferimento al simbolo
senza override,[#],
è codificato come se avesse override
DS:,
[@];
in questo caso per garantire al processore di trovare il nostro dato in ogni
situazione diventa fortemente consigliato riferirsi
alle variabili con dichiarazione esplicita dell'override
CS:,[*],
anche se, come è noto, ci costa ogni volta un byte macchina in più (2EH):
MAIN:
MOV AL,[ATTRIB] [#]
MOV AL,DS:[ATTRIB] [@]
MOV AL,CS:[ATTRIB] [*] |
A00301 MOV
AL,[0103]
A00301 MOV AL,[0103]
2EA00301 MOV AL,CS:[0103] |
|
 | Come con
CS:,
in ogni caso, con o senza direttive ASSUME,
la forzatura esplicita con
override diversi da DS:
obbligherà il compilatore a generare un codice macchina con un byte in
più (36Hper
SS:e
26H per
ES:):
MOV AL,SS:[ATTRIB]
MOV AL,ES:[ATTRIB] |
36A00301 MOV
AL,SS:[0103]
26A00301 MOV AL,ES:[0103] |
|
 | In ogni caso, inoltre, il riferimento a locazioni del
segmento tramite registro senza
override è comunque codificato come se avesse override
DS:,[@]; anche in questo caso diventa
fortemente consigliato riferirsi alle variabili con
dichiarazione esplicita dell'override
CS:,[*]:
MOV AL,[SI]
MOV AL,DS:[SI]
[@]
MOV AL,CS:[SI]
[*]
MOV AL,ES:[SI]
MOV AL,SS:[SI] |
8A04 MOV AL,[SI]
8A04 MOV AL,[SI]
2E8A04 MOV AL,CS:[SI]
268A04 MOV AL,ES:[SI]
368A04 MOV AL,SS:[SI]
|
|
|
 |
Tutte
le istruzioni di tipo MOV
AL,[ATTRIB] o MOV
AL,[SI]sono
codificare con il registro di segmento specificato dall'ultima
direttiva ASSUME associata al segmento che le contiene. |
 | Nei miei programmi (compresi quelli offerti in
ogni parte di questo Sito) ho utilizzato sempre l'override
CS:
nella lettura e scrittura di ogni locazione definita
nell'unico segmento disponibile; abbiamo imparato che la cosa non è ovvia come sembra,
sebbene sia nella gran parte dei casi non
strettamente necessaria... (vedi nota dedicata). |
©
2001-2010 - Studio Tecnico
ing. Giorgio OBER
Tutti i diritti sono riservati
|