Article View: comp.os.msdos.programmer
Article #1193Trapping INT 21 is easy.
From: dueck
Date: Tue, 01 Sep 1992 05:01
Date: Tue, 01 Sep 1992 05:01
134 lines
4900 bytes
4900 bytes
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
Technical Details
Message-ID:
<1992Aug31.230136.2195@brandonu.ca>Path:
arc1-ca.pugleaf.net!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!dueckShow Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!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