Overview  
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
second).
  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
...and...
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
program.
  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
PSP:100.

  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
later.
  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.
- -

Program Startup & Exit