home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #19 / NN_1992_19.iso / spool / comp / os / msdos / programm / 8951 < prev    next >
Encoding:
Internet Message Format  |  1992-09-01  |  4.6 KB

  1. 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
  2. Newsgroups: comp.os.msdos.programmer
  3. Subject: Trapping INT 21 is easy.
  4. Message-ID: <1992Aug31.230136.2195@brandonu.ca>
  5. From: dueck@brandonu.ca
  6. Date: 31 Aug 92 23:01:36 CST
  7. Organization: Brandon University, Brandon, Manitoba, Canada
  8. Lines: 135
  9.  
  10.  
  11. Its strange how things come together.
  12.  
  13. There has been a thread in this newsgroup about trapping interrupt 21.
  14. Coincidentally, I have been writing a system in which trapping int 21
  15. is essential. I need to both front-end and back-end the interrupt.
  16.  
  17. In essence, here is what happens:
  18.  
  19. newint21:
  20.    save regs
  21.    do some stuff
  22.  
  23.    restore regs
  24.    call old int 21
  25.    save result flags
  26.    save result regs
  27.  
  28.    do some more stuff
  29.  
  30.    restore result regs
  31.    move result flags into stack frame
  32.    iret
  33.  
  34. Prior to calling old int 21, all regs must be the same as they
  35. were supplied from the application. The call itself is simulated
  36. by a pushf and call far, since the old handler will iret.
  37.  
  38. One exception: function 4B (exec) blows away the SS:SP, so continuing
  39. upon return becomes a little dicey. So for 4B (exec), the filter jumps to
  40. the old interrrupt handler rather than calling it (see below). This can be
  41. fixed, but the application doesn't require it, so I let it ride.
  42.  
  43. This solution works perfectly. It ensures that the regs
  44. of the caller are passed on to the interrupt routine and that the
  45. result regs and flags are passed back to the caller.
  46.  
  47. Then one day it failed. Specifically, the MEM command broke.
  48. It said (approximately):
  49.  
  50.   Runtime error r6002
  51.   Floating point library not loaded
  52.  
  53. I logged all interrupt 21 calls along with regs ax, bx, cx, and dx
  54. (out the network, onto the vax, and into a log file, but that's another
  55. story). The upshot of this was that just prior to the interrupt 21
  56. calls that produced the error message came a series of function 35/25 calls
  57. (getvect and setvect).
  58.  
  59. The assumption was that somehow my filter was interfering with these calls.
  60. So the filter was modified:
  61.  
  62. newint21:
  63.    cmp    ah, 25h
  64.    je    jmpoldint21
  65.    cmp    ah, 35h
  66.    je    jmpoldint21
  67.  
  68.    other filter code as above
  69.    iret
  70.  
  71. jmpoldint21:
  72.    db    02eh,0ffh,02eh            ; cs: jmp far
  73.    dw    offset sd.oldint21
  74.  
  75. Klugey, but it works. This solves the problem with MEM, but doesn't
  76. explain why it failed in the first place. By the way, I found this
  77. problem by coding a range check and jumping to everything inside
  78. the range. The range could be modified from debug, so I didn't have
  79. to reboot each time. By changing the range, I could determine a range
  80. of jumps for which the MEM command would succeed or fail.
  81.  
  82. Using Bolzano bisection on a range of 0 through 7F, and modifying just the
  83. upper bound zeroed in on int 35 as the upper bound. Modifying just
  84. the lower bound gave int 25.
  85.  
  86. But other situations that arose during debugging gave rise to the following
  87. bizarre suggestion: Is it possible that the contents of the flags on
  88. INPUT to int 21 are important? Easy enough to check, and it turns out that,
  89. yes, they are and the problem is solved.
  90.  
  91. So here is what works:
  92.  
  93. _int21hook:
  94.     push    ax
  95.     pushf
  96.     pop    ax
  97.     mov    cs:_sd.flags, ax
  98.     pop    ax
  99.  
  100.     The call to the old handler is
  101.  
  102.     push    cs:_sd.flags
  103.     call    cs:[_sd.oldint21]    ; far call
  104.  
  105. Beaming with delight, I continued with other work. Who would have
  106. believed that the flags were that important? I can see, just barely,
  107. passing information back in the flags, but passing information
  108. via flags into an interrupt handler??? It makes no sense. But it works.
  109.  
  110. Then it broke.
  111.  
  112. It happened this way. I have a command to log out from the network
  113. and disable the computer by entering a hard loop:
  114.  
  115. here:    jmp    here
  116.  
  117. This makes it impossible to continue after logging out without rebooting.
  118. For a variety of reasons, this is what I want to happen.
  119. Usually I CTRL-ALT-DELETE to reboot. Some times I press the reset button.
  120. Sometimes I turn off the computer and go have a beer.
  121.  
  122. With the interrupt 21 filter in place, CTRL-ALT-DELETE has NO EFFECT.
  123. It is ignored! What gives? Back to the drawing board!
  124.  
  125. Here is what works: instead of restoring the old flags before the
  126. far call, set the z flag:
  127.  
  128.     push    ax                      ; save
  129.     mov    ax, 0
  130.     cmp    ax, 0            ; obviously equal
  131.     pop    ax            ; restore w/o mod'ing flags
  132.     pushf                ; save flags: garbage + Z=1
  133.     call    cs:[_sd.oldint21]    ; far call
  134.  
  135. This allows CTRL-ALT-DELETE while the cpu is in a hard loop.
  136. And MEM still works. No way you say? Way!, I say.
  137.  
  138. Thus ends the saga. Until the next time it breaks. In the meantime,
  139. can anyone out there in net land give me some insight? It started
  140. off as such a simple problem and ended up so really wierd.
  141.  
  142. Gery Dueck
  143. dueck@brandonu.ca
  144.  
  145.