Terminate and Stay Resident (TSR) is a system call in DOS operating systems that returned control to the system as if the program had quit, but kept the program in memory. Many software vendors use the call to create the appearance of multitasking, by transferring control back to the terminated program on automatic or externally-generated events. Some TSR programs are effectively device drivers for hardware not directly supported by MS-DOS, while others are small utility programs offering frequently-used functionality such as scheduling and contact directories.
Normally, in the DOS operating system, only one program can be running at any given time, and when it wants to stop running, it relinquished the control to DOS’s shell program, COMMAND.COM, using the system call INT 21H/4CH. The memory and system resources used by the program are marked as unused, effectively making it impossible to summon parts of it again. However, if a program ended with the system call INT 27H or INT 21H/31H, the operating system does not reuse a certain, specified, part of the program’s memory.
The original call, INT 27H, is called ‘Terminate But Stay Resident’, hence the name ‘TSR’. Using this call, a program can make only up to 64KB of its memory resident. MS-DOS version 2.0 introduced an improved call, INT 21H/31H (‘Keep Process’), which removed this limitation and also let the program return an exit code. Before making this call, the program can install one or several interrupt vectors pointing into itself, so that it can be called again. Installing a hardware interrupt vector allows such a program to react to hardware events; a software interrupt vector allows it to be called by the currently running program; using a timer interrupt allowed a TSR to be summoned periodically.
By chaining the interrupt vectors TSR programs could take complete control of the computer.
A TSR could have one of two behaviours:
Take complete control of an interrupt by not calling other TSRs that had previously altered the same interrupt vector.
Cascade with other TSRs by calling the old interrupt vector. This could be done before or after they executed their actual code. This way TSRs could form a chain of programs where each one calls the next one.
The ‘Terminate and Stay Resident’ method was used by most MS-DOS viruses which could either take control of the PC or stay at the background. Viruses would react on disk I/O or execution events by infecting executable (.EXE or .COM) files when they were run and data files when they were opened.
A TSR program can be loaded at any time; sometimes, they are loaded immediately after the operating system’s boot, by being explicitly loaded in either the AUTOEXEC.BAT or CONFIG.SYS scripts, or alternatively at the user’s request (for example, Borland’s SideKick and Turbo Debugger). These programs will, as ‘TSR’ implies, stay resident in memory while other programs are executing. Most of them do not have an option for unloading themselves from memory, so calling TSR means the program will remain in memory until a reboot. However unloading is possible externally, using utilities like the MARK.EXE/RELEASE.EXE combo by TurboPower Software or soft reboot TSRs which will catch a specific key combination and release all TSRs loaded after them.