How MS-DOS 6.22 Executes Nested Batch Files with CALL

This article explains the internal mechanics of the CALL command in MS-DOS 6.22, detailing how the operating system handles control flow, execution state, and memory when nesting batch files. By default, invoking a batch file from within another terminates the parent script prematurely. Using CALL allows the parent script to pause, transfer execution to a child script, and safely resume once the child finishes.

The Problem: Default Batch File Chaining

In MS-DOS 6.22, the command interpreter (COMMAND.COM) processes batch files sequentially. When a batch file invokes another batch file directly by name (e.g., simply entering SUBFILE.BAT), COMMAND.COM does not run it as a subroutine. Instead, it performs an unconditional chain:

  1. COMMAND.COM closes the file handle of the calling batch file.
  2. It replaces the current batch context with the new batch file.
  3. Once the target batch file completes, execution stops entirely. Control never returns to the original script.

How the CALL Command Solves Chaining

To execute a secondary batch file as a true subroutine, MS-DOS provides the internal CALL command. Its syntax is:

CALL [drive:][path]filename [batch-parameters]

When COMMAND.COM encounters the CALL statement, it preserves the execution state of the calling batch file rather than overwriting it, allowing nested execution trees.

Internal Execution Mechanics of CALL

When CALL executes in MS-DOS 6.22, the shell executes the following steps:

  1. State Preservation: COMMAND.COM records the current state of the parent batch file. This includes:

    • The full path and filename of the calling script.
    • The exact file seek offset (the byte position in the file where the parent left off).
    • The current batch parameters (%0 through %9).
    • The state of conditional statements (such as active FOR or IF blocks).
  2. Stack Allocation: This saved execution context is pushed onto an internal memory structure (a batch context block) managed by COMMAND.COM. MS-DOS allocates memory from its transient program area to keep track of these nested levels.

  3. Context Switching: COMMAND.COM reassigns its internal file pointer to the target script specified in the CALL statement, parses any arguments passed to it, and maps them to parameters %1 through %9 for the duration of the child script's execution.

  4. Child Execution: The child batch file runs line-by-line using the primary command processor's environment.

  5. Context Restoration: When COMMAND.COM encounters the physical end-of-file (EOF) of the child script, it detects that it is executing within a nested context. It pops the top context block from the internal stack, reopens the parent batch file, seeks to the saved byte offset, and continues processing the next command immediately following the original CALL line.

Environment Variable Scope

Unlike modern shells that may isolate subshell environments, MS-DOS 6.22 uses a single, global environment segment for the active instance of COMMAND.COM. Any variable modifications, additions, or deletions made inside a called batch file via the SET command alter the parent's environment directly. When control returns to the parent file, those variable changes persist.

Nesting Limits and Recursion

MS-DOS 6.22 supports deep nesting and recursion using CALL, provided there is sufficient conventional memory to store the batch context blocks. If a script recurses indefinitely without a termination condition, MS-DOS will eventually deplete its internal memory structures or stack space, causing a batch file error or freezing the command interpreter.