MS-DOS 6.22 Secondary Shell Program Execution

MS-DOS 6.22 executes programs within secondary command shells by leveraging hierarchical process management, low-level interrupt routines, and structured memory allocations. When a user or application invokes an additional instance of COMMAND.COM, the operating system treats it as a child process, allocating a distinct memory block, duplicating environment variables, and establishing a parent-child execution chain. This article details the exact mechanics MS-DOS 6.22 uses to spawn secondary shells, allocate resources, load target binaries through interrupt services, and safely restore the system state upon program completion.

Spawning the Secondary Shell

A secondary shell is instantiated when an active program or user executes COMMAND.COM from the existing command line or via an application call. This is commonly done interactively or using parameters like /C (execute command and terminate) or /K (execute command and remain active).

To launch the shell, the current process invokes MS-DOS Interrupt 21h, Function 4Bh (known as the EXEC function). The caller passes an EXEC parameter block containing pointers to:

  • The environment block to be inherited or created.
  • The command line tail (the arguments passed to COMMAND.COM).
  • Default File Control Blocks (FCBs).

MS-DOS creates a new Program Segment Prefix (PSP) for the secondary COMMAND.COM, initializes its transient and resident components in memory, and transfers control to the new shell's entry point.

Memory Allocation and the MCB Chain

MS-DOS manages memory linearly using Memory Control Blocks (MCBs). When the secondary shell loads, MS-DOS modifies the MCB chain:

  1. Space Allocation: The operating system searches the conventional memory pool (the first 640 KB) for a free block large enough to house the secondary shell and its requested environment space.
  2. PSP Creation: A 256-byte PSP is placed at the base of this allocated segment. The PSP contains the parent process ID (the segment address of the caller's PSP), critical interrupt vectors, and the file handle table.
  3. Environment Duplication: By default, the secondary shell receives a copy of the parent's environment block. Any changes made to environment variables within the secondary shell affect only this copy, leaving the parent's environment intact.

Executing Target Programs

Once active, the secondary shell evaluates commands using its own internal parser. When an external program (.COM, .EXE, or .BAT) is called:

  1. Locating the Binary: The secondary shell checks the current directory, followed by directories listed in its localized PATH variable.
  2. Issuing the Nested EXEC Call: Once the file is located, the secondary shell calls INT 21h, Function 4Bh again.
  3. Binary Loading:
    • .COM Files: Loaded directly into a single 64 KB segment adjacent to the new PSP, with execution beginning at offset 0100h.
    • .EXE Files: MS-DOS parses the file's MZ header, relocates internal segment pointers according to the relocation table, points the Stack Segment/Stack Pointer (SS:SP) to the specified stack area, and jumps to the entry point defined by the Code Segment/Instruction Pointer (CS:IP).
  4. Vector Hooking: MS-DOS copies three vital interrupt vectors from the active shell into the target program's PSP:
    • INT 22h: Termination Address
    • INT 23h: Ctrl+C Handler
    • INT 24h: Critical Error Handler

Program Termination and Control Return

When the executed program completes, it terminates by calling INT 21h, Function 4Ch, passing an exit code (accessible via ERRORLEVEL).

MS-DOS handles cleanup systematically:

  1. Restoring Interrupts: MS-DOS restores INT 22h, INT 23h, and INT 24h from the values stored inside the terminating program's PSP back to the secondary shell's context.
  2. Deallocating Memory: The memory blocks occupied by the terminating program are marked as free in the MCB chain.
  3. Returning to the Secondary Shell: Control jumps to the address specified by the restored INT 22h vector, resuming the secondary shell.

If the secondary shell was invoked with /C, the shell detects completion of the primary task and immediately issues its own INT 21h, Function 4Ch. MS-DOS then unloads the secondary shell, reclaims its memory, and transfers execution back to the primary shell or original host program waiting at the base of the chain.