• Please review our updated Terms and Rules here

TSR techniques to save space

cr1901

Veteran Member
Joined
Dec 28, 2011
Messages
817
Location
NJ
Let's be honest: In DOS, every byte actually matters. This is especially apparent when it comes to TSRs!

For those around during the era, what programming techniques/special assembler directives (creative uses of ORG?) did you use to code your TSRs to save space?

In particular, here's one I've been batting around: One technique that NASM suggests is to do the following:
Code:
org     100h               ; it's a .COM program 

        jmp     setup              ; setup code comes last 

        ; the resident part of the TSR goes here 
setup: 
        ; now write the code that installs the TSR here 

absolute setup 

runtimevar1     resw    1 
runtimevar2     resd    20 

tsr_end:

I.e. use the setup code as the .bss. I'm not sure if this is possible using MASM- is it? Regardless, I think we could do even better! Unfortunately, due to this being a COM program, we lose 256 bytes to the PSP, and I'm pretty sure we don't get that back after making the TSR syscall. If we relocate the resident code to the start of the segment, all offsets are off by 0x100, unless we manually fix the offsets. I wonder if it's worth the effort to create a small relocator for the resident portion/whether someone has actually done it?

If so, I wonder: can it be done in both MASM/NASM?
 
Sure it is. I never use MASM anymore, but this technique is still extremely common when doing non-OS programming. For example, I write a fair number of bootloaders and other bootsector oriented stuff (either to eliminate the OS and its overhead, to bypass the OS or to load and boot the OS). This is done all of the time.
 
Agreed--I've written a lot of TSR code where the initialization is longer than the actual "guts" of the code. After initialization, you use the code area for storage and give back the rest to DOS for re-use. Device drivers (which are really a type of TSR) employ a similar scheme.
 
Another approach is to use a two-file two-stage loader/runtime. You put the startup and a loader routine into one file, and once the setup is done the loader pulls your runtime from disk placing it OVER the startup code.
 
If you're not using the environment, you can free it (INT 21h/AH=49h) and then allocate a single paragraph to replace it, containing just the program name:
Code:
db ' ',0,0,1,0,'ProgName',0
 
If your TSR involves a lot of static data, oftentimes you can save some space by doing some simple (e.g. repeated byte) compression--and then decompressing as needed.
 
Back
Top