[net.micro.pc] To those who write background resident code.....

greenber@phri.UUCP (Ross Greenberg) (01/03/86)

Arghhhh!  Where is net.flame when ya need it?


FLAME ON......

This is an official flame, after spending hours tracking down a bug
only to find out that it wasn't mine!  And I always thought
Borland did decent code!  Boy, I guess you get what you pay for!

Take their Sidekick program, for example.  Now, if you're gonna steal
an interrupt, there are two ways to do it.  The "MS-DOS, golly, let's
not do anything to system memory approach" (int 21 with ah=25), which
just feels like a kludge, but isn't. ( Actually this approach really
has some good reasons for being, especially with the *possible* design
of the 80286 and upwards, and the idea of vector tables in unknown
locations....)

Then there is the way most people do it (myself included, when I'm
being lazy, and *not*writing*code*for*the*rest*of*the*world*, but only
for my machine where I control the vertical and the horizontal),
where you simply say "Turn off interrupts, futz with the vectors directly,
and turn interrupts back on".  This second way, btw, is the way that
most of the resident pieces of code do their thing.

Wouldn't it be nice if everybody used the int21, ah =25 approach above?
Then somebody could write a piece of code to take over dos, intercept
these calls and make up a nice little service routine that politely
makes each interrupt service routine think that it really, truly is
a direct result of an int xx call.  Why such a piece of code would be
nifty, right?  If only the folks that brought you BASICA followed their
own advice, and used int 21, ah =25.  They used the "I'm the only program
that matters approach".  The one that beginners use.


Ok.  Back to the service routines whic is alread in progress:

Of course you're gonna save what was there originally, and make
sure to call it via a FAR CALL, right?  And you'll do it in such a
fashion that no one will know you're there, right?  NOT BORLAND!
Not SideKick! Not Microsoft! Not BASICA (is that really a program, or
instead someone's idea of a joke?).

Lissen you Borland guys (are they on the net? --- if not I'll
T*Y*P*E**L*O*U*D*E*R) don't you realize that there are some
very good reasons for turning off interrupts?  How 'bout them
Microsoft guys!  Don't you believe in resetting the Comm ports
to their original settings after you give up the ghost to
COMMAND.COM.

Lets put SK and BASICA together and see what happens:

1)	Sidekick takes over the timer tick, some of the dos-vectors
	and the keyboard.  Where do they check for Cntrl-Alt? In
	the timer tick, of course.  Where else would you check for
	a key? (Hint: the harware keyboard-interrupt routine might be a good
	spot, since you take it over anyway!)

2)	Basica takes over the timer tick, the comm ports (what? You
	don't have comm ports? Makes no difference to BASICA --
	it meta-magically must GIVE you an AST board, since it takes
	over the comm port vectors, anyway), ups the clock count and
	calls the original timer-tick (which is really SideKick which
	in turn calls the original timer tick and the user timer tick)
	every now and then.  It also calls the user timer tick.
	Wait....does that mean that the user timer tick gets called
	more frequently than it should.  Sure does!  But if you
	look closer, you'll find some dangerous stuff going on.

3)	Both of the above "programs" decided to turn the interrupts
	ON when FAR CALLING the timer tick. What could this mean?
	Well, first thing is that certain pieces of code that expect
	to see the actual condition of the flag word on the stack
	won't see what they're lookin' for. Since an interrupt routine
	expects to be called by an int xx instruction or a hardware
	event, it is not unreasonable to expect that interrupts will be
	disabled.  That means you can play with ss and sp, and take your
	time about it. 

	Since both of these series of bytes mentioned above decide 
	"I don't care.....I'll turn on interrupts whenever I feel like it!",
	and *then* push the flags, you never get a decent idea of what 
	is truly happening. You certainly wouldn't be able to tell
	if interrupts were on or off *before* the interrupt.

	Of course, getting an interrupt when you are between the 
	mov ss, my_stack_segment  and mov sp, top_o_my_stack instructions
	can have interesting results.  All you need do is simply curse
	the dasterdly program (after spending a few days debugging),
	remember that even beginner-programmers have a mortgage,
	and stick in a CLI in self defense.

4)	But wait! There's more.  Seems that basica doesn't restore
	vectors when it exits.  But that isn't a problem: they turn off
	interrupts in COM1:.  HEY!!! MICROSOFT!!! THERE ARE SOME PEOPLE
	OUT IN REAL WORLD THAT HAVE SOMETHING TIED INTO COM2, YOU
	DUNDERHEADS!!  GUESS WHAT HAPPENS WHEN SIDEKICK TURNS ON
	INTERRUPTS, A CHARACTER COMES IN ON COM2, AND YOUR MACHINE
	STARTS VECTORING TO *RANDOM* CODE THAT SAYS: 
	"FIRST, ERASE THE FAT...."??

To all resident programmers out there: give back the interrupts
when you're finished, turn off interrupts, and pass the TRUE flag word:

MY_INT:
	push	bp 
	mov	bp, sp 
	push	[bp + 8]   ----> Lots tougher than "pushf", right Phillipe?
	call	dword ptr [old_int]
	pop	bp
	the rest of your code
	iret


FLAME OFF.

Golly....I feel better now.  Thanks for listening.

ross m. greenberg
ihnp4!allegra!phri!sysdes!greenber

jsdy@hadron.UUCP (Joseph S. D. Yao) (01/17/86)

In article <2106@phri.UUCP> greenber@phri.UUCP (Ross Greenberg) writes:
>FLAME ON......
>	Of course, getting an interrupt when you are between the 
>	mov ss, my_stack_segment  and mov sp, top_o_my_stack instructions
>	can have interesting results.  ...
>FLAME OFF.

This must have been one of the original 8086's.  I didn't read it
here originally (I can't find my original source), but in Stephen
P. Morse's _The_8086_8088_Primer_ (Hayden 1982, AKA "the red book"),
pp 89-90, subtitle \fB An 8086 Mistake \fP:
	[ describes the above problem ]
	This mistake was not discovered until after the 8086
	was designed and built.  After the mistake was dis-
	covered, the 8086 was modified so that it will not
	accept any interrupts immediately after executing an
	instruction that moves a new value into SS.
Says nothing about whether old chips were recalled, or what ...
-- 

	Joe Yao		hadron!jsdy@seismo.{CSS.GOV,ARPA,UUCP}