[comp.sys.ibm.pc] More assembly questions about TSR development.

alanr@tekigm2.MEN.TEK.COM (Alan Rovner) (04/26/89)

Thanks to everyone who helped out with my previous questions regarding
assembly language issues.  But having crunched on that for awhile, I
have more questions regarding TSR development...

1.  Can a TSR be a .EXE file instead of a .COM file, at least during
development?  I use CodeView a lot to test the things I'm writing and it
only works with .EXE files.  If not, how does one go about testing their
TSRs?  Speaking of CodeView, is it possible to debug an Interrupt Service
Routine?  I don't think so, but I haven't explored it that closely.

2.  I've looked at a couple examples of working TSRs and noticed something
interesting.  They don't have a stack segment defined.  There is an
ASSUME CS:CODE,DS:CODE statement near the top but the stack isn't looked
at anywhere.  In fact, the linker gives a warning that the stack segment
is missing.  It doesn't seem to matter though, after running EXE2BIN it
works fine.  I'm a little confused about this.

3.  In order to do a TSR exit from a routine, one of the parameters needed
by DOS is the memory size to be reserved in 16-byte paragraphs.  I've seen
what look like tricky ways to determine this.  Is there an easy way to
find where the end of your code is and I guess divide that by 16 to get the
number of paragraphs?  I'm also a little confused about this too.

Thanks again for the help.  I can't seem to find any assembly gurus around
here.

Al Rovner
Tektronix Inc.
Vancouver, Wash.

pgaughan@dante.nmsu.edu (Patrick Gaughan) (04/27/89)

Q: Can a TSR be an .EXE?

Yes.

Q: Why is there no stack segment defined in the TSR source listings I've seen?

The TSR listings you have been looking through have been .COM TSR's.  In a 
.COM file there can only be one segment and CS, DS, ES, and SS all point to
that segment on program startup.  EXE2BIN will not work if more than one
segment is defined.  But, if you want your TSR to be a .EXE, don't bother 
to use EXE2BIN.  

Also, a few more differences between .COM's and .EXE's:
  .COM's have a ORG 100h at the beginning of the code segment to make room
         for the PSP (Program Segment Prefix).  .EXE's do not need this 
         since DOS allocates a PSP for them on startup.
  .EXE's can have an entry point anywhere within the code segment while .COM's
         must start at 100h (right after the ORG).
  Since .COM files are limited to 1 segment, this generally implies 64k is the
         limit on the size of the final code (although I'm sure there is a way
         around this...)

Also, when developing TSR's, using DOS function calls (INT 21h) on interrupt 
is a very tricky business and many articles should be read before doing it
yourself...

Suggested references:
PC magazine - whenever they have a TSR utility, read the article
DOS Technical Reference Manual
The Waite Group's MS-DOS Developer's Guide
MS-DOS Advanced Programming

Disclaimer:"I know NOTHING! NOTHING!" (German accent implied...)

Brought to you by the developer of TSR NCSA Telnet,
(Please don't flood me with mail, a 256k TSR is not that useful yet...)

Patrick Gaughan		Programmer of Gor
pgaughan@nmsu.edu	New Mexico State University

tomj@hpccc.HP.COM (Tom Johnson) (04/28/89)

/ hpccc:comp.sys.ibm.pc / alanr@tekigm2.MEN.TEK.COM (Alan Rovner) /  7:58 am  Apr 26, 1989 /

>1.  Can a TSR be a .EXE file instead of a .COM file, at least during
>development?  I use CodeView a lot to test the things I'm writing and it
>only works with .EXE files.  If not, how does one go about testing their
>TSRs?  Speaking of CodeView, is it possible to debug an Interrupt Service
>Routine?  I don't think so, but I haven't explored it that closely.

Yes, a TSR can be an .EXE file.  The reason to go to an .EXE file would
be to use different segments for data and code.  Since TSR's are usually
(hopefully) pretty small, this shouldn't matter.  There is also a lot
of extra work when DS, ES, and CS are different.  For example, if you're
in an interrupt and you need to access a variable, that variable has to
be in the CS segment. (mov cs:var1,ax).

I wouldn't do this just to run with CodeView though.  CodeView ain't too
good for TSR debugging.  As far as I could tell, once you "terminate and
stay resident," CodeView is done and you can't debug your actual routine.
I'm also pretty sure you can't debug the interrupts with CodeView.

>2.  I've looked at a couple examples of working TSRs and noticed something
>interesting.  They don't have a stack segment defined.  There is an
>ASSUME CS:CODE,DS:CODE statement near the top but the stack isn't looked
>at anywhere.  In fact, the linker gives a warning that the stack segment
>is missing.  It doesn't seem to matter though, after running EXE2BIN it
>works fine.  I'm a little confused about this.

Lets see if I can remember this.  When a .COM program is loaded, all the
segment registers point to the same segment (including SS).  The stack
pointer should point to the end of the segment (0ffffh or something close).
Therefore it doesn't do any good to define a stack.  If you're writing a
TSR as an .EXE file, then you need a stack, or at least set up your
SS and SP registers when the program loads.

>3.  In order to do a TSR exit from a routine, one of the parameters needed
>by DOS is the memory size to be reserved in 16-byte paragraphs.  I've seen
>what look like tricky ways to determine this.  Is there an easy way to
>find where the end of your code is and I guess divide that by 16 to get the
>number of paragraphs?  I'm also a little confused about this too.

If it's a .COM file it's easy. Put a label at the start of the program
and another one at the point where you want to release the memory, then
subtract the first from the second.  This gives the number of bytes between
the two labels.  Convert to paragraphs and you're set.

Tom Johnson
Hewlett-Packard
tomj@hpccc.hp.com

gbm@gbmatl.UUCP (gary mckenney) (05/01/89)

In article <210@opus.NMSU.EDU> pgaughan@dante.UUCP (Patrick Gaughan) writes:
>Also, when developing TSR's, using DOS function calls (INT 21h) on interrupt 
>is a very tricky business and many articles should be read before doing it
>yourself...
>
	Very tricky business.  If you have file I/O be extremely careful.
	It seems that MicroSoft and Borland don't support file I/O nor 
	really admit to support TSR when things get beyond a local pop-up
	screen.

	MicroSoft will send you an example TSR  .exe program example upon
	request.  It is quite useful.
>
>Suggested references:
>PC magazine - whenever they have a TSR utility, read the article
>DOS Technical Reference Manual
>The Waite Group's MS-DOS Developer's Guide
     -------------------------------------- >  Good Choice.
>MS-DOS Advanced Programming
>

PC magazine DOS POWER TOOLS Techniques, Tricks and Utilities.  Excellent
reference for alot.

C Power User's Guide...  So So...  Some help.

Also   Essential Software, Inc.  supposedly has a library of functions that
support TSR's.  I've called and talked to them but chose not to buy it 
since I had already developed 95 % of what I needed.

I do use their Essential Communications Library and it is a pretty good work.

Good Luck,  You'll need it.  Most references you'll find will keep alot of
questions unanswered.  There really is a need for a book or manual soley
based on TSR programming.  Any volunteers ?  I would be willing to throw in
my TSR experiences to date.

gbm

irv@blackwidow.rutgers.edu (Irving N. Rabinowitz) (05/01/89)

An excellent book about the subject is

   "Memory Resident Programming on the IBM PC", by Thomas A. Wadlow, 
    Addison-Wesley 1987.  My copy says $24.95.
-- 

                                                    --Irv
  +--------------------------------------------------------------------------+
  | uucp: {backbone}!rutgers!aramis.rutgers.edu!irv                          |
  | arpa: irv@aramis.rutgers.edu                        phone: (201)932-2002 |
  | mail: Irving N. Rabinowitz, Department of Computer Science,              |
  |                             Rutgers University, New Brunswick, NJ 08903  |
  +--------------------------------------------------------------------------+

cgs@umd5.umd.edu (Chris G. Sylvain) (05/06/89)

In article <5060057@hpccc.HP.COM> tomj@hpccc.HP.COM (Tom Johnson) writes:
>
>I wouldn't do this just to run with CodeView though.  CodeView ain't too
>good for TSR debugging.  As far as I could tell, once you "terminate and
>stay resident," CodeView is done and you can't debug your actual routine.
>I'm also pretty sure you can't debug the interrupts with CodeView.
>

I've used CodeView for TSR debugging. If fact, my TSR installed an interrupt
handler which I debugged with CodeView.

You're right, once your program has invoked the TSR call, all CodeView
reports in the return value from the call (you're not still using INT 27h,
are you??)... To continue debugging, you need to modify CodeView's CS:IP.

Set CS:IP to the address of your interrupt handler (of course, don't attempt
any of this if you've taken over the keyboard handler). Single-step your
way through until you reach your IRET. Voila! You've just used CodeView
to debug an interrupt handler.
-- 
--==---==---==--
.. Came whiffling through the tulgey wood, ..
   ARPA: cgs@umd5.UMD.EDU     BITNET: cgs%umd5@umd2
   UUCP: ..!uunet!umd5.umd.edu!cgs

stephen@ziebmef.uucp (Stephen M. Dunn) (05/07/89)

In article <4550@tekigm2.MEN.TEK.COM> alanr@tekigm2.MEN.TEK.COM (Alan Rovner) writes:
:1.  Can a TSR be a .EXE file instead of a .COM file, at least during dev't?
   Yes, but there are some problems in using an EXE.  The biggest such problem
is that upon calling the DOS TSR service, you must say how many paragraphs
(16-byte chunks of memory) you wish to remain in memory.  With a COM, it's
easy; divide the length of your file by 16 and round up.  With an EXE, where
you have many segments, it's not as easy.  If you can find a way to do your
TSR in a COM file (or, if that isn't possible, in a one-segment EXE), you'll
find it's much easier to call the TSR function.

:2.  I've looked at a couple examples of working TSRs and noticed something
:interesting.  They don't have a stack segment defined.  There is an
:ASSUME CS:CODE,DS:CODE statement near the top but the stack isn't looked
:at anywhere.  In fact, the linker gives a warning that the stack segment
:is missing.  It doesn't seem to matter though, after running EXE2BIN it
:works fine.  I'm a little confused about this.

   This is quite normal, in fact it's required for a COM file.  In a COM
file, you are only allowed one segment, so you normally want CS and DS to
point into that segment as both your code and your data are there.  You
don't define a stack segment; DOS gives you one when your COM is loaded 
into memory.  The linker will always give such a warning when linking a
program with no stack segment.  The reason why is that you might not want
to turn the EXE into a COM and it's just reminding you that you don't have
a stack segment.  I believe EXE2BIN will scream if you hand it an EXE with
a stack segment.

:3.  In order to do a TSR exit from a routine, one of the parameters needed
:by DOS is the memory size to be reserved in 16-byte paragraphs.  I've seen
:what look like tricky ways to determine this.  Is there an easy way to
:find where the end of your code is and I guess divide that by 16 to get the
:number of paragraphs?  I'm also a little confused about this too.

   This is where it really benefits you to have only one segment.  Assuming
you have a COM file, you can put a label (e.g. FILEND) at the end of your
segment and calculate the number of paragraphs to reserve like this:

        NUM_2_RESERVE = (FILEND + 15) / 16 + 10H

You add 15 to make sure that should FILEND fall in the middle of a para-
graph, you chop the memory off after that paragraph rather than before it.
Division by 16 is for an obvious reason; adding 10H is to allow space for
the Program Segment Prefix (PSP; for more info, see Duncan's _Advanced
MS-DOS Programming_ or one of Norton's books).  I would imagine the same
would apply for a one-segment EXE, but I'm not sure.  BTW, to give credit
where credit is due, the above formula is copied from memory but originally
cam from the Duncan book cited above.

   Hope this helps.  At the moment I'm studying TSRs because I want to
write a print spooler (why?  just for the pleasure of it :-), so my
memory of the above should be correct.

   Regards, Steve


-- 
-------------------------------------------------------------------------------
! Stephen M. Dunn              stephen@ziebmef.UUCP ! DISCLAIMER:  Who'd ever !
! (I am currently pondering a witticism to go here) ! claim such dumb ideas?  !
-------------------------------------------------------------------------------

stephen@ziebmef.uucp (Stephen M. Dunn) (05/07/89)

In article <210@opus.NMSU.EDU> pgaughan@dante.UUCP (Patrick Gaughan) writes:
:  Since .COM files are limited to 1 segment, this generally implies 64k is the
:         limit on the size of the final code (although I'm sure there is a way
:         around this...)

   Okay, you asked for it! (:-)  It's easy enough to do, as there are no run-time
checks made on your segment registers.  First, you shrink your memory allocation
down to whatever size your program really is (remembering to include the
stack and, if you aren't using the full 64K, remembering also to move the
stack to its new location).  Then, you allocate whatever memory you want and
store its segment somewhere and play around with the rest of your memory to
your heart's desire.

   BTW, there obviously is a way to do this because COMMAND.COM does it.
The .EXE loader (i.e. relocating loader) is found in COMMAND.COM, and it has
to be able to load in .EXE files of any size, often >64K.

   Regards, Steve


-- 
-------------------------------------------------------------------------------
! Stephen M. Dunn              stephen@ziebmef.UUCP ! DISCLAIMER:  Who'd ever !
! (I am currently pondering a witticism to go here) ! claim such dumb ideas?  !
-------------------------------------------------------------------------------

bright@Data-IO.COM (Walter Bright) (05/11/89)

In article <210@opus.NMSU.EDU> pgaughan@dante.UUCP (Patrick Gaughan) writes:
:  Since .COM files are limited to 1 segment, this generally implies 64k is the
:         limit on the size of the final code (although I'm sure there is a way
:         around this...)

Not true. COM files are not limited to one segment. The fact that most
COM files are only one segment does not mean it has to be this way.

COM files are only limited in that the size of the .COM *file* is limited
to 64k minus some overhead bytes. Proof of this is that the Zortech C compiler
generates .COM programs that have 2 segments (code and data).

You can use multiple segments by doing the segment relocation yourself
(which the EXE file loader does for you).

For more info, read the MS-DOS Tech Ref manual under "DOS Program Segment".