DK>MB>>From: Mervyn Baldwin
DK> > According to my reference ("PC Interrupts" by Ralf Brown & Jim
DK> > Kyle), all registers except for CS:IP get destroyed on return
DK> > from an int 2Eh... however you could do something like this:
DK> > ******
DK> > .DATA
DK> > SaveSS dw ?
DK> > SaveSP dw ?
DK> > SaveBP dw ?
DK> > .CODE
DK> > SafeInt2Eh:
DK> > MOV [SaveSS], SS
DK> > MOV [SaveSP], SP
DK> > MOV [SaveBP], BP
DK> > INT 2Eh
DK> > CLI ; make sure the restoration of the registers in
DK> > ;uninterrupted
DK> > MOV AX, SEG _DATA
DK> > MOV DS, AX
DK> > MOV SP, [SaveSP]
DK> > MOV SS, [SaveSS]
DK> > MOV BP, [SaveBP]
DK> > STI ; registers restored, so interrupts OK
DK> > RET
DK> > ******
DK> > Normally you might PUSH registers to preserve them before an
DK> > interrupt, but since SS:SP is also destroyed, you have to take
DK> > different precautions.
DK> > ((Cloud))
DK>To simplify even further, you could have SaveSS, SaveSP, SaveBP all in the
DK>Code segment (rather than in the _DATA segment). In your example above,
DK>you have NOT saved the caller's DS and have effectively blown it away.
DK>Doing it my way, you don't need to touch any segment registers.
DK>.CODE
DK>SaveSS dw 0
DK>SaveSP dw 0
DK>SaveBP dw 0
DK>SafeInt2Eh:
DK> MOV CS:[SaveSS], SS
DK> MOV CS:[SaveSP], SP
DK> MOV CS:[SaveBP], BP
DK> INT 2Eh
DK> CLI ; make sure the restoration of the registers is
DK>;uninterrupted
DK> MOV SP, CS:[SaveSP]
DK> MOV SS, CS:[SaveSS]
DK> MOV BP, CS:[SaveBP]
DK> STI ; registers restored, so interrupts OK
DK> RET
You still need to restore DS! This part might not need it, but much of the
rest of your program will probably need to know where the data segment is...
If you're doing this in protected mode, you'd probably get a GPF the next
ime
you tried to access something in the data segment. There are three ways that
the DS register can be restored:
1. The way I showed above, which make your assembler add a reference in the
appropriate FIXUPP record so that the place in your code where you specified
it will be replaced at runtime by the appropriate value for DS.
2. Declare another code segment variable, SaveDS, and do the save & restore
y
your method.
3. You can PUSH DS, then save the stack... when the stack is restored, you
an
pop DS... You could also do similarly for BP... and if you're calling this
from a C program, you might want to preserve SI and DI also.
((Cloud))
MauveCloud@juno.com
* OLX 2.2 * Corruption. The most infallible symptom of liberty.
--- PCBoard (R) v15.3/M 10
---------------
* Origin: Next time, Dial The Wrong Number! (209) 943-1880 (1:208/205)
|