|
Lettura della Tabella dei Vettori con
la funzione 35H del DOS
La prima tecnica è senz'altro la più efficiente, avendo a che
fare direttamente con un servizio assicurato dal sistema operativo;
come detto la funzione assume
in ES:BX l'indirizzo effettivo
(vettore di interruzione) della procedura di servizio associata all'Interrupt
il cui numero xy è predisposto in ingresso
in AL; il resto del codice assembly
deve provvedere al salvataggio di questa preziosa informazione.
La prima variante assume e salva il
puntatore del Gestore originale nelle 4 locazioni locali [old_INT];
da notare che, essendo le locazioni destinazione di tipo
DWORD (32 bit),
l'inserimento di un dato più piccolo (il
contenuto di registri a 16 bit) produrrà segnalazione d'errore da parte
del compilatore se non si specifica l'operatore
Word Ptr:
PUSH ES
PUSH AX
PUSH BX
MOV
AL,xy
MOV
AH,35H
INT
21H
MOV
Word Ptr [old_INT],BX
MOV
Word Ptr [old_INT][2],ES
POP
BX
POP
AX
POP
ES |
|
la seconda variante salva il
puntatore del Gestore originale nelle 4 locazioni locali [old_SEG]/[old_OFF];
da notare che essendo ora entrambe le locazioni destinazione di tipo
WORD non è necessario
specificare l'operatore
Word Ptr per le istruzioni
MOV, essendo
BX e ES della
stessa loro dimensione: |
PUSH ES
PUSH AX
PUSH BX
MOV
AL,xy
MOV
AH,35H
INT
21H
MOV [old_OFF],BX
MOV [old_SEG],ES
POP
BX
POP
AX
POP
ES |
|
|
Lettura della Tabella dei Vettori con
tecniche tradizionali [1 di
2]
Il secondo modo di assumere l'indirizzo desiderato
è legato alle tecniche tradizionali di lettura della memoria; in questo
caso però utilizza un metodo piuttosto sofisticato (e probabilmente
eccessivo...) per localizzare le informazioni desiderate:
|
con l'aiuto della pseudooperazione
SEGMENT AT, definisce
un segmento (la solita area di 64k) tale da coprire
le prime 65536 locazioni della memoria Convenzionale in cui trova posto
appunto la Tabella dei Vettori, e lo chiama TABint |
| individua al tempo stesso, con l'etichetta INT_xy,
l'esatta locazione del vettore associato al servizio INT
xyH; nelle 2 varianti che seguono questa etichetta (LABEL) è
prima di tipo
DWORD (4bytes) e poi di tipo
WORD (2bytes). |
|
con
la pseudooperazione
ASSUME sovrappone
logicamente l'area di memoria appena definita (TABint) al
registro di segmento ES, consentendo
all'assemblatore di calcolare con correttezza l'indirizzo effettivo di
ciascuna etichetta inclusa nel segmento stesso; così ogni riferimento a
INT_xy sarà realmente un riferimento a
ES:[INT_xy], anche se
non esplicitamente dichiarato con il
segment-override. |
| le prime istruzioni del codice di cattura vettore saranno
quelle che inizializzano anche fisicamente registro di segmento ES
per puntare la Tabella dei Vettori, operazione realizzata con l'aiuto si
AX. |
|
Con questa premessa, per
salvare il vettore originale sono
disponibili le stesse 2 varianti di prima; la prima variante assume e salva il
puntatore del Gestore originale nelle 4 locazioni locali [old_INT];
da notare che essendo sia le locazioni sorgente
che quelle destinazione di tipo
DWORD (32 bit),
l'inserimento di un dato più piccolo (i 16 bit del registro
AX) produrrà segnalazione d'errore da parte
del compilatore se non si specifica l'operatore
Word Ptr: |
TABint
SEGMENT AT 0000H
ORG
00xy*4
INT_xy LABEL DWORD
;<<<<<< NB
TABint ENDS
ASSUME ES:TABint
;------------------------------
PUSH ES
MOV AX,TABint
MOV ES,AX
MOV
Word Ptr AX,[INT_xy]
MOV
Word Ptr [old_INT],AX
MOV
Word Ptr AX,[INT_xy][2]
MOV
Word Ptr [old_INT][2],AX
POP
ES |
La seconda variante salva il
puntatore del Gestore originale nelle 4 locazioni locali [old_SEG]/[old_OFF];
da notare che essendo sia le locazioni sorgente
che quelle destinazione di tipo
WORD non è necessario
specificare l'operatore
Word Ptr per le istruzioni
MOV, essendo
AX della
stessa loro dimensione: |
|
TABint
SEGMENT AT 0000H
ORG
00xy*4
INT_xy LABEL WORD
;<<<<<< NB
TABint ENDS
ASSUME ES:TABint
;------------------------------
PUSH ES
MOV AX,TABint
MOV ES,AX
MOV AX,[INT_xy]
MOV [old_OFF],AX
MOV AX,[INT_xy][2]
MOV [old_SEG][2],AX
POP
ES |
|
|
Lettura della Tabella dei Vettori con
tecniche tradizionali [2 di
2]
Anche il terzo modo di assumere l'indirizzo
desiderato è legato alle tecniche tradizionali di lettura della memoria,
ma in questo
caso evita di definire ed assegnare particolari segmenti per localizzare
la Tabella dei Vettori; lo sviluppo del programma è certamente più autonomo:
| la localizzazione delle locazioni da cui estrarre il
vettore è fatta ora in modo immediato
con l'aiuto di 2 assegnazioni costanti,
con la pseudooperazione
EQU associata alle etichette TABint
e
INT_xy |
| Il registro di segmento ES è caricato fisicamente con
l'indirizzo del segmento (area di 64k) che copre
le prime 65536 locazioni della memoria Convenzionale in cui trova posto
appunto la Tabella dei Vettori, definito TABint
(=0000H) |
| il puntatore del Gestore originale, [INT_xx+02]:[INT_xx],
segment:offset, viene salvato nelle 4 locazioni locali [old_SEG]/[old_OFF];
poichè tutte le locazioni (sorgente
e destinazione) di tipo
WORD non è necessario
specificare l'operatore
Word Ptr per le istruzioni
MOV, essendo
AX della stessa loro
dimensione; è invece necessario aggiungere
esplicitamente il
segment-override ES:
per le locazioni sorgente, mentre
per le locazioni
destinazione si può aggiungere facoltativamente il
segment-override CS:: |
TABint
EQU 0000H
INT_xy EQU
0009*4
PUSH ES
MOV AX,TABint
MOV ES,AX
MOV AX,ES:[INT_xy]
MOV [old_OFF],AX
MOV AX,ES:[INT_xy][2]
MOV [old_SEG],AX
POP
ES |
|