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)
|