TIP: Click on subject to list as thread! ANSI
echo: 80xxx
to: SYLVAIN LAUZON
from: DENIS BOYLES
date: 1997-04-03 22:32:00
subject: dosdebug.asm

Hi Sylvain,
SL>PROGRAM: DOSDEBUG.ASM
SL> AUTHOR: Denis Boyles
SL>PURPOSE: a quick and dirty example of hooking into the DOS interrupt (21h)
SL>  NOTES: displays AH function register's value in hex on the screen
SL>         ** COLOR VIDEO RAM ONLY - USE WITHIN DOS AND TEXT APPS **
SL>Remember about this program? Well it doesn't look easy to understand but
Yep, I remember, I wondered if it got lost in the FidoNet void or not, guess
not. It's actually a pretty simple program in essence. INT 21h is "hooked"
by my own routine which "intercepts" the function calls in AH. Then it uses
direct video writing to print out the value for the desired function in AH.
After printing the value, the DOS interrupt continues on to do whatever it
was supposed to do. In a sense, I'm kinda "updating" the DOS interrupt to
include some of my own code.
The IMPORTANT thing to remember is to make sure your stack is pushed/poped
right. A wrong stack value or SS/SP location would crash the computer. Also
it's IMPORTANT that the registers aren't changed before/after the call.
Otherwise they could give wrong values to/from DOS and the interrupted
program.
SL>it work without hang the computer. By writing directly to video, it 
overides
SL>all special cares about dos flags. But i need to use easy cmd like 
t21/09
It's not so much of an override, but rather a way around a particular
problem. Since DOS isn't re-entrant, you can't call DOS when you are in
DOS. Imagine something like this:
Program:
  mov  AH,09h
  mov  DX,offset message
  int  21h ----|
               |
               |
INT 21h:      <-            <----
  mov  AH,09h                   |
  mov  DX,offset message        |   goes into infinate loop?
  int  21h                   ---|
Say PROGRAM was a program that was currently running and was going to print
something via a DOS interrupt. Then say you also had a TSR hooked into the
DOS interrupt that was also going to print something. You'll end up in a
loop where the DOS code calls itself over and over....
The DOS flag is one way to avoid this, by checking the flag you can
determine if it's safe to call DOS. Though I haven't dealt with that yet,
I've only done simple TSR programs so far.
SL>Glen told me about saving SS. Done! But halfway only. I need to get SP? 
from
SL>my own handler and not the SP from the caller routine. i am
SL>not very sure yet what procedure i need to write. If
That's not to difficult, depending on your program. I'll assume a COM file
format where all the segments are at the same location. Firstly reserve
some space for the stack in your program.
ie:
    stack   db 0100h dup(?)            ;256 bytes stack
EndStack:
Then initialize the stack and the rest of your program and then save it's
location into local memory. Remember to disable the interrupts during the
transfer so things aren't disturbed.
ie:
    MyStack   dd ?                     ;stack of my program, DWORD size
    ...
    mov     IP,offset EndStack         ;initialize IP to end of my stack
    ...
    cli                                ;disable interrupts
    mov     word ptr [MyStack][2],SS   ;save my stack segment
    mov     word ptr [MyStack][0],SP   ;save my stack pointer
    sti                                ;enable interrupts
Then make sure that when you TSR the program, your stack and your stack's
local memory pointer are kept in memory.
You'll also want to have another DWORD of local memory put away to store
the interrupted programs' stack.
ie:
    YourStack dd ?                     ;interrupted programs stack
Then when your TSR kicks in, just save the current interrupted stack into
memory. Then replace it with the stack from your own program which you
setup earlier. Again, remember to disable the interrupts between the
exchange.
NOTE: You'll need to use a CS override to access your local data or
      conversely copy CS to DS.
ie:
    cli                                   ;disable interrupts
    mov word ptr CS:[YourStack][2],SS     ;save their stack segment
    mov word ptr CS:[YourStack][0],SP     ;save their stack pointer
    mov SS,word ptr CS:[MyStack][2]       ;load my stack segment
    mov SP,word ptr CS:[MyStack][0]       ;load my stack pointer
    sti                                   ;enable interrupts again
    ...
Upon exiting your TSR program, just reverse the process to switch the
stacks back.
ie:
    ...
    cli                                   ;disable interrupts
    mov SS,word ptr CS:[YourStack][2]     ;restore their stack segment
    mov SP,word ptr CS:[YourStack][0]     ;restore their stack pointer
    sti
Cheers,
  Denis Boyles
 * OLX 2.1 TD * C Borg:Pointers are irrelevant,you shall be dereferenced
--- Maximus/2 3.01
---------------
* Origin: Frog Hollow Port Moody BC 604-469-0264/0284 (1:153/290)

SOURCE: echomail via exec-pc

Email questions or comments to sysop@ipingthereforeiam.com
All parts of this website painstakingly hand-crafted in the U.S.A.!
IPTIA BBS/MUD/Terminal/Game Server List, © 2025 IPTIA Consulting™.