home *** CD-ROM | disk | FTP | other *** search
- Path: sparky!uunet!usc!sdd.hp.com!uakari.primate.wisc.edu!caen!destroyer!ubc-cs!unixg.ubc.ca!kakwa.ucs.ualberta.ca!access.usask.ca!ccu.umanitoba.ca!ciit85.ciit.nrc.ca!brandonu.ca!dueck
- Newsgroups: comp.os.msdos.programmer
- Subject: Trapping INT 21 is easy.
- Message-ID: <1992Aug31.230136.2195@brandonu.ca>
- From: dueck@brandonu.ca
- Date: 31 Aug 92 23:01:36 CST
- Organization: Brandon University, Brandon, Manitoba, Canada
- Lines: 135
-
-
- Its strange how things come together.
-
- There has been a thread in this newsgroup about trapping interrupt 21.
- Coincidentally, I have been writing a system in which trapping int 21
- is essential. I need to both front-end and back-end the interrupt.
-
- In essence, here is what happens:
-
- newint21:
- save regs
- do some stuff
-
- restore regs
- call old int 21
- save result flags
- save result regs
-
- do some more stuff
-
- restore result regs
- move result flags into stack frame
- iret
-
- Prior to calling old int 21, all regs must be the same as they
- were supplied from the application. The call itself is simulated
- by a pushf and call far, since the old handler will iret.
-
- One exception: function 4B (exec) blows away the SS:SP, so continuing
- upon return becomes a little dicey. So for 4B (exec), the filter jumps to
- the old interrrupt handler rather than calling it (see below). This can be
- fixed, but the application doesn't require it, so I let it ride.
-
- This solution works perfectly. It ensures that the regs
- of the caller are passed on to the interrupt routine and that the
- result regs and flags are passed back to the caller.
-
- Then one day it failed. Specifically, the MEM command broke.
- It said (approximately):
-
- Runtime error r6002
- Floating point library not loaded
-
- I logged all interrupt 21 calls along with regs ax, bx, cx, and dx
- (out the network, onto the vax, and into a log file, but that's another
- story). The upshot of this was that just prior to the interrupt 21
- calls that produced the error message came a series of function 35/25 calls
- (getvect and setvect).
-
- The assumption was that somehow my filter was interfering with these calls.
- So the filter was modified:
-
- newint21:
- cmp ah, 25h
- je jmpoldint21
- cmp ah, 35h
- je jmpoldint21
-
- other filter code as above
- iret
-
- jmpoldint21:
- db 02eh,0ffh,02eh ; cs: jmp far
- dw offset sd.oldint21
-
- Klugey, but it works. This solves the problem with MEM, but doesn't
- explain why it failed in the first place. By the way, I found this
- problem by coding a range check and jumping to everything inside
- the range. The range could be modified from debug, so I didn't have
- to reboot each time. By changing the range, I could determine a range
- of jumps for which the MEM command would succeed or fail.
-
- Using Bolzano bisection on a range of 0 through 7F, and modifying just the
- upper bound zeroed in on int 35 as the upper bound. Modifying just
- the lower bound gave int 25.
-
- But other situations that arose during debugging gave rise to the following
- bizarre suggestion: Is it possible that the contents of the flags on
- INPUT to int 21 are important? Easy enough to check, and it turns out that,
- yes, they are and the problem is solved.
-
- So here is what works:
-
- _int21hook:
- push ax
- pushf
- pop ax
- mov cs:_sd.flags, ax
- pop ax
-
- The call to the old handler is
-
- push cs:_sd.flags
- call cs:[_sd.oldint21] ; far call
-
- Beaming with delight, I continued with other work. Who would have
- believed that the flags were that important? I can see, just barely,
- passing information back in the flags, but passing information
- via flags into an interrupt handler??? It makes no sense. But it works.
-
- Then it broke.
-
- It happened this way. I have a command to log out from the network
- and disable the computer by entering a hard loop:
-
- here: jmp here
-
- This makes it impossible to continue after logging out without rebooting.
- For a variety of reasons, this is what I want to happen.
- Usually I CTRL-ALT-DELETE to reboot. Some times I press the reset button.
- Sometimes I turn off the computer and go have a beer.
-
- With the interrupt 21 filter in place, CTRL-ALT-DELETE has NO EFFECT.
- It is ignored! What gives? Back to the drawing board!
-
- Here is what works: instead of restoring the old flags before the
- far call, set the z flag:
-
- push ax ; save
- mov ax, 0
- cmp ax, 0 ; obviously equal
- pop ax ; restore w/o mod'ing flags
- pushf ; save flags: garbage + Z=1
- call cs:[_sd.oldint21] ; far call
-
- This allows CTRL-ALT-DELETE while the cpu is in a hard loop.
- And MEM still works. No way you say? Way!, I say.
-
- Thus ends the saga. Until the next time it breaks. In the meantime,
- can anyone out there in net land give me some insight? It started
- off as such a simple problem and ended up so really wierd.
-
- Gery Dueck
- dueck@brandonu.ca
-
-