How MS-DOS 6.22 Handles SET Environment Variables
In MS-DOS 6.22, the SET command is an internal function
of the command processor (COMMAND.COM) used to create,
modify, and delete environment variables stored in a dedicated memory
block. When a user or batch script executes SET, the
operating system parses the input, converts variable names to uppercase,
and updates a contiguous, null-delimited segment of memory allocated for
environment data. If the block lacks sufficient space, DOS returns an
"Out of environment space" error, making the size and location of the
environment block critical to system operation.
Command Parsing and Formatting
When COMMAND.COM encounters the SET
command, it processes the text following the command keyword:
- Displaying Variables: If
SETis executed without parameters,COMMAND.COMreads the entire environment segment from the first byte to the double-null termination and prints each entry to standard output. - Key and Value Separation: If parameters are
provided, the parser searches for the first equal sign (
=). The text to the left becomes the variable name, and the text to the right becomes the value. - Case Normalization: MS-DOS converts the variable name to uppercase characters before storing it. The value assigned to the variable preserves its original casing, spaces, and special characters.
- Deletion: If a variable name is followed by an
equal sign with no trailing value (e.g.,
SET VAR=),COMMAND.COMtreats this as a removal instruction.
Memory Layout of the Environment Block
MS-DOS stores environment variables in a dedicated memory segment managed via Memory Control Blocks (MCBs). The structure follows a strict format:
- Format of Entries: Each variable is stored as an
ASCII string formatted as
NAME=VALUE, terminated by a single null byte (00h). - End-of-Block Marker: The final variable in the list
is terminated by an additional null byte (
00h), creating a double-null sequence that signals the end of the environment data. - Program Path Information: In MS-DOS 6.22, a word count followed by the fully qualified path of the currently executing program is placed directly after the terminating double null.
Adding, Modifying, and Deleting Entries
When modifying the environment, COMMAND.COM scans the
memory block sequentially from the beginning:
- To Modify an Existing Variable: If the variable name already exists, MS-DOS removes the old entry. If the new value requires the same or fewer bytes, it updates the space in place. If the new entry is larger, DOS shifts subsequent data downward in memory to accommodate the larger string, provided the overall environment limit is not exceeded.
- To Delete an Existing Variable: DOS locates the
NAME=VALUEstring, deletes it, and shifts all remaining entries up toward the beginning of the block to eliminate the gap. The end-of-block null markers are adjusted accordingly. - To Add a New Variable: DOS searches for the double-null sequence marking the end of the data. If the remaining allocated memory accommodates the new string, the string is appended, followed by the terminating null bytes.
Memory Size Limits and the PSP
By default, MS-DOS 6.22 allocates an environment block of 256 bytes
for the primary shell. If a SET command requires more bytes
than remain in the allocated block, the operation fails, and DOS outputs
the error: Out of environment space.
System administrators increase this allocation by modifying
CONFIG.SYS using the SHELL command:
SHELL=C:\DOS\COMMAND.COM C:\DOS\ /E:1024 /P
The /E:size switch defines the master environment block
size in bytes (ranging from 160 to 32,768 bytes).
Environment Inheritance
Each process launched under MS-DOS receives its own copy of the
environment. The Program Segment Prefix (PSP) of an executing program
contains a pointer at offset 2Ch that holds the segment
address of its environment block.
When a program or secondary shell launches, DOS creates a snapshot of
the parent environment, truncating any unused memory to fit the active
variables. Consequently, changes made with the SET command
inside a child shell or batch process launched in a subshell only alter
the child's local environment block and do not persist in the parent
COMMAND.COM environment after the child process exits.