Program Startup & Exit

  DOS is able to load and execute two types of program files -- COM and EXE.

  Because of the segmented address space of the Intel 8088/80x86 CPUs and
  the fact that JMPs and CALLs are address-relative, either type of program
  may be loaded and executed at any paragraph address in conventional
  memory.  Thus, code can be made resident in "low" memory and other code
  can be loaded and executed above it in memory.  Programs are never written
  with the assumption that they'll be loaded at a certain address (except
  the boot sector and some self-booting, copy-protected games).

  ■ A COM-format file is a binary image of the code and data of the
    program.  The file must be less than 64K, and no segment-address
    relocation takes place.

  ■ An EXE-format file contains an EXE Header that directs the loader in
    performing adjustments to segment references in a load module.

█▌All Programs▐█
  Before either a COM- or EXE-format program is loaded, DOS selects a
  segment address, called the PSP (Program Segment Prefix) as the load base
  for the program.  By default, DOS selects the lowest available address in
  conventional memory, but it is possible to control the location via DOS
  fn 58H.  Then DOS performs these steps:

  ■ It makes a duplicate of the current DOS Environment for the program.
    DOS Fn 4bH (EXEC) lets a parent program create a different environment.
    For instance, a program can run COMMAND.COM, setting the DOS prompt to
    include the text "Use EXIT to return to UltraProg>".

  ■ It places a text string identifying the program's load path at the end
    of the environment (in DOS 3.0+).

  ■ It fills the fields of the PSP with information useful to the program
    (See Program Segment Prefix for a complete layout):
    • The amount of memory available to the program
    • The segment address of the DOS Environment
    • 0-2 unopened File Control Blocks (FCBs) as parsed from the command
      line (Note: if you open the first FCB, it will overwrite part of the
    • The command parameters: text entered in the command line after the
      program name (examine this for options and filename parameters)
    • The previous vectors for INT 22H, INT 23H, and INT 24H

  ■ It sets the default Disk Transfer Address (DTA) to PSP:0080

  ■ It sets the AX register to indicate the validity of the drive IDs (if
    any) of the filespec parameters entered on the command line:
    • if AL=0ffH, then the first drive ID was invalid
    • if AH=0ffH, then the second drive ID was invalid

█▌EXE Programs▐█
  EXE-format programs define multiple program segments, including a code,
  data, and stack segment.  The EXE file is loaded starting at PSP:0100.  As
  it is loaded, a bunch of information is read from the EXE Header at the
  start of file and segment address-relocation is performed.  This means
  that references such as...

           mov     ax,data_seg
           mov     ds,ax
           call    my_far_proc

  ...must be adjusted to allow for the fact that the program is being loaded
  into an arbitrarily-selected memory segment.  See EXE Header for details
  of the header and the relocation process.

  After relocation, control is passed to the load module via a FAR jump to
  the CS:IP that was read from the EXE header.

  When the EXE-format program gets control:
  ■ DS and ES are set to the PSP
  ■ CS, IP, SS, and SP are set to values indicated in the EXE Header
  ■ The PSP.wNextSeg field is set to a value in the EXE header.  Normally,
    all of available memory is allocated to the program.

█▌COM Programs▐█
  COM-format programs define a single segment.  The bytes of the COM file
  are read from disk and stored into memory starting at PSP:0100.  Note that
  a COM program can use multiple segments, but it must calculate or derive
  segment addresses, using the PSP segment as a base.

  Traditionally, COM programs have been preferred over EXE programs for
  short assembly language utilities.  They load faster since no segment
  relocation is needed, and they take less disk space since the bytes of
  the EXE header and the stack segment need not be present in the load
  module.  However, COM programs are starting to be phased out, since you
  can't write OS/2- or Windows-specific programs in COM format.

  Compilers and linkers may refer to COM programs as those using the "tiny"
  memory model.

  ■ CS, DS, ES, and SS are set the same as the PSP.
  ■ SP is set to the end of the PSP segment (usually 0fffeH, but it will be
    lower if a full 64K is not available).  The word at offset 06H of the
    PSP is set to indicate how much of the program segment is available.
  ■ All system memory above the Program Segment is allocated to the
  ■ A word of 00H is pushed onto the stack.
  ■ IP is set to 100H (the first byte of the load module) by a JMP to

█▌Exiting a Program▐█
  At one time (back in the days of DOS 1.1), it took several pages to
  explain the Rube Goldberg scheme DOS provided for exit from a program.
  It got easier starting with DOS 2.0.  You can exit by:

  ■ Using DOS Fn 4cH (EXIT) at any time, regardless of register values.
  ■ Using DOS Fn 00H or INT 20H  when your CS is the same as the PSP

  Prior to DOS 2.0, you needed to save the PSP segment at startup.  Then to
  exit, you would PUSH it on the stack, PUSH a word of 00H, then do a FAR
  RETurn.  This sends control to PSP:0000 which contains the opcodes for
  INT 20H.  This ensures that CS is set as expected by DOS.

  DOS Fn 4cH eliminates this complication, and it lets you return an
  exit code to the parent process (usually COMMAND.COM) which can be tested
  by the parent program or the "IF ERRORLEVEL" batch file command.

  You may also terminate a program and make it permanently memory resident
  (TSR), by using either INT 27H or DOS Fn 31H (KEEP).  The latter has the
  advantages that you can make more than 64K resident and you can return an
  exit code that can be tested by the parent process.

  TSR programs are handy for installing custom patches to various DOS and
  BIOS services.  It is the concept used by popup utilities such as SideKick
  and TECH Help! (to name two popular instances).

  When a program exits:
  ■ All of its memory is freed, including the allocation for its copy of
    the environment.  Exception: When exiting via TSR exits (INT 27H and
    fn 31H) the specified memory and your environment memory is preserved.
    TSRs should explicitly free their environment if they won't need it
  ■ Its files are closed and file buffers flushed.
  ■ Redirection, if any, is cancelled.
  ■ Critical error handler (INT 24H), Ctrl+Break handler (INT 23H), and
    Terminate (INT 22H) vectors are restored from the PSP.
  ■ Control is passed back to the parent, via a FAR JMP to the address that
    was previously in the INT 22H vector.

See Also: Process Control Functions .. index of DOS Startup and Exit fns
          Program Segment Prefix ..... detailed layout of the PSP
          TSR ........................ submenu of popup-program topics
          DOS Fn 26H ................. build a PSP
          DOS Fn 4bH (EXEC)........... load and execute programs
          DOS Fn 62H ................. obtain PSP of the current program
          DOS Fn 2fH ................. obtain current Disk Transfer Address
          DOS Environment ............ determine the drive and directory
                                       from which you were loaded, etc.
          DOS Functions
          TECH Topics