Chapter Thirteen (Part 4)
|Table of Content||
Chapter Thirteen (Part 6)
MS-DOS PC-BIOS AND FILE I/O (Part 5)
MS-DOS Memory Management Functions
220.127.116.11 - Allocate Memory
18.104.22.168 - Deallocate Memory
22.214.171.124 - Modify Memory Allocation
126.96.36.199 - Advanced Memory Management Functions
MS-DOS Process Control Functions
188.8.131.52 - Terminate Program Execution
184.108.40.206 - Terminate but Stay Resident
220.127.116.11 - Execute a Program
MS-DOS provides three memory management functions- allocate deallocate and resize (modify). For most programs these three memory allocation calls are not used. When DOS executes a program it gives all of the available memory from the start of that program to the end of RAM to the executing process. Any attempt to allocate memory without first giving unused memory back to the system will produce an "insufficient memory" error.
Sophisticated programs which terminate and remain resident run other programs or perform complex memory management tasks may require the use of these memory management functions. Generally these types of programs immediately deallocate all of the memory that they don't use and then begin allocating and deallocating storage as they see fit.
Since these are complex functions
they shouldn't be used
unless you have a very specific purpose for them. Misusing these commands may result in
loss of system memory that can be reclaimed only by rebooting the system. Each of the
following calls returns the error status in the carry flag. If the carry is clear on
then the operation was completed successfully. If the carry flag is set when DOS
ax register contains one of the following error codes:
7- Memory control blocks destroyed 8- Insufficient memory 9- Invalid memory block address
Additional notes about these errors will be discussed as appropriate.
18.104.22.168 Allocate Memory
Function (ah): 48h Entry parameters: bx- Requested block size (in paragraphs) Exit parameters: If no error (carry clear): ax:0 points at allocated memory block If an error (carry set): bx- maximum possible allocation size ax- error code (7 or 8)
This call is used to allocate a block of memory. On entry
bx contains the size of the requested block in paragraphs (groups
of 16 bytes). On exit
assuming no error
ax register contains the
segment address of the start of the allocated block. If an error occurs
the block is not
allocated and the
ax register is returned containing the error code. If the
allocation request failed due to insufficient memory
bx register is
returned containing the maximum number of paragraphs actually available.
22.214.171.124 Deallocate Memory
Function (ah): 49h Entry parameters: es:0- Segment address of block to be deallocated Exit parameters: If the carry is set ax contains the error code (7 9)
This call is used to deallocate memory allocated via
function 48h above. The
es register cannot contain an arbitrary memory
address. It must contain a value returned by the allocate memory function. You cannot use
this call to deallocate a portion of an allocated block. The modify allocation function is
used for that operation.
126.96.36.199 Modify Memory Allocation
Function (ah): 4Ah Entry parameters: es:0- address of block to modify allocation size bx- size of new block Exit parameters: If the carry is set then ax contains the error code 7 8 or 9 bx contains the maximum size possible (if error 8)
This call is used to change the size of an allocated block.
es must contain the segment address of the allocated block returned
by the memory allocation function.
Bx must contain the new size of this block
in paragraphs. While you can almost always reduce the size of a block
you cannot normally
increase the size of a block if other blocks have been allocated after the block being
modified. Keep this in mind when using this function.
188.8.131.52 Advanced Memory Management Functions
The MS-DOS 58h opcode lets programmers adjust MS-DOS' memory allocation strategy and control the use of upper memory blocks (UMBs). There are four subfunctions to this call with the subfunction value appearing in the al register. The following table describes these calls:
|Function # (AH)||Input Parameters||Output Parameters||Description|
||Get Allocation Strategy: Returns the current allocation strategy in ax (see table below for details).|
|Set Allocation Strategy: Sets the MS-DOS allocation strategy to the value specified in bx (see the table below for details).|
||Get Upper Memory Link: Returns true/false (1/0) in al to determine whether a program can allocate memory in the upper memory blocks.|
|Set Upper Memory Link: Links or unlinks the upper memory area. When linked an application can allocate memory from the UMB (using the normal DOS allocate call).|
|0||First Fit Low||Search conventional memory for the first free block of memory large enough to satisfy the allocation request. This is the default case.|
|1||Best Fit Low||Search conventional memory for the smallest block large enough to satisfy the request.|
|2||Last Fit Low||Search conventional memory from the highest address downward for the first block large enough to satisfy the request.|
|80h||First Fit High||Search high memory then conventional memory for the first available block that can satisfy the allocation request.|
|81h||Best Fit High||Search high memory then conventional memory for the smallest block large enough to satisfy the allocation request.|
|82h||Last Fit High||Search high memory from high addresses to low then conventional memory from high addresses to low for the first block large enough to satisfy the request.|
|40h||First Fit Highonly||Search high memory only for the first block large enough to satisfy the request.|
|41h||Best Fit Highonly||Search high memory only for the smallest block large enough to satisfy the request.|
|42h||Last Fit Highonly||Search high memory only from the end of memory downward for the first block large enough to satisfy the request.|
These different allocation strategies can have an impact on system performance. For an analysis of different memory management strategies please consult a good operating systems theory text.
13.3.7 MS-DOS Process Control Functions
DOS provides several services dealing with loading executing and terminating programs. Many of these functions have been rendered obsolete by later versions of DOS. There are three functions of general interest- program termination terminate and stay resident and execute a program. These three functions will be discussed in the following sections.
184.108.40.206 Terminate Program Execution
Function (ah): 4Ch
Entry parameters: al- return code
Exit parameters: Does not return to your program
This is the function call normally used to terminate your
program. It returns control to the calling process (normally
but not necessarily
return code can be passed to the calling process in the
al register. Exactly
what meaning this return code has is entirely up to you. This return code can be tested
with the DOS "IF ERRORLEVEL return code" command in a DOS batch file. All files
opened by the current process will be automatically closed upon program termination.
Note that the UCR Standard Library function "
is simply a macro which makes this particular DOS call. This is the normal way of
returning control back to MS-DOS or some other program which ran the currently active
220.127.116.11 Terminate but Stay Resident
Function (ah): 31h Entry parameters: al- return code dx- memory size in paragraphs Exit parameters: does not return to your program
This function also terminates program execution but upon returning to DOS the memory in use by the process is not returned to the DOS free memory pool. Essentially the program remains in memory. Programs which remain resident in memory after returning to DOS are often called TSRs (terminate and stay resident programs).
When this command is executed
contains the number of memory paragraphs to leave around in memory. This value is measured
from the beginning of the "program segment prefix"
a segment marking the start
of your file in memory. The address of the PSP (program segment prefix) is passed to your
program in the
ds register when your program is first executed. You'll have
to save this value if your program is a TSR.
Programs that terminate and stay resident need to provide some mechanism for restarting. Once they return to DOS they cannot normally be restarted. Most TSRs patch into one of the interrupt vectors (such as a keyboard printer or serial interrupt vector) in order to restart whenever some hardware related event occurs (such as when a key is pressed). This is how "pop-up" programs like SmartKey work.
Generally TSR programs are pop-ups or special device drivers. The TSR mechanism provides a convenient way for you to load your own routines to replace or augment BIOS' routines. Your program loads into memory patches the appropriate interrupt vector so that it points at an interrupt handler internal to your code and then terminates and stays resident. Now when the appropriate interrupt instruction is executed your code will be called rather than BIOS'.
There are far too many details concerning TSRs including compatibility issues DOS re-entrancy issues and how interrupts are processed to be considered here. Additional details will appear in a later chapter.
18.104.22.168 Execute a Program
Entry parameters: ds:dx- pointer to pathname of program to execute
es:bx- Pointer to parameter block
al- 0=load and execute 1=load only 3=load overlay.
Exit parameters: If carry is set ax contains one of the following error codes:
1- invalid function
2- file not found
5- access denied
8- not enough memory
10- bad environment
11- bad format
The execute (
exec) function is an extremely
but at the same time
very useful operation. This command allows you to load or
load and execute a program off of the disk drive. On entry into the
ds:dx registers contain a pointer to a zero terminated string containing
the name of the file to be loaded or executed
es:bx points at a parameter
al contains zero or one depending upon whether you want to load
and execute a program or simply load it into memory. On return
if the carry is clear
then DOS properly executed the command. If the carry flag is set
then DOS encountered an
error while executing the command.
The filename parameter can be a full pathname including
drive and subdirectory information. "B:\DIR1\DIR2\MYPGM.EXE" is a perfectly
valid filename (remember
it must be zero terminated). The segmented address of
this pathname is passed in the
es:bx registers point at a parameter block
exec call. This parameter block takes on three different forms
depending upon whether a program is being loaded and executed (
loaded into memory (
or loaded as an overlay (
exec call loads and
executes a program. In this case the
es:bx registers point at a parameter
block containing the following values:
Offset Description 0 A word value containing the segment address of the default environment (usually this is set to zero which implies the use of the standard DOS environment). 2 Double word pointer containing the segment address of a command line string. 6 Double word pointer to default FCB at address 5Ch 0Ah Double word pointer to default FCB at address 6Ch
The environment area is a set of strings containing default
pathnames and other information (this information is provided by DOS using the PATH
and other DOS commands). If this parameter entry contains zero
pass the standard DOS environment on to the new procedure. If non-zero
parameter contains the segment address of the environment block that your process is
passing on to the program about to be executed. Generally
you should store a zero at this
The pointer to the command string should contain the segmented address of a length prefixed string which is also terminated by a carriage return character (the carriage return character is not figured into the length of the string). This string corresponds to the data that is normally typed after the program name on the DOS command line. For example if you're executing the linker automatically you might pass a command string of the following form:
CmdStr byte 16 "MyPgm+Routines /m" 0dh
The second item in the parameter block must contain the segmented address of this string.
The third and fourth items in the parameter block point at the default FCBs. FCBs are used by the obsolete DOS filing commands so they are rarely used in modern application programs. Since the data structures these two pointers point at are rarely used you can point them at a group of 20 zeros.
Example: Format a floppy disk in drive A: using the FORMAT.EXE command
mov ah 4Bh mov al 0 mov dx seg PathName mov ds dx lea dx PathName mov bx seg ParmBlock mov es bx lea bx ParmBlock int 21h . . . PathName byte 'C:\DOS\FORMAT.EXE' 0 ParmBlock word 0 ;Default environment dword CmdLine ;Command line string dword Dummy Dummy ;Dummy FCBs CmdLine byte 3 ' A:' 0dh Dummy byte 20 dup (?)
MS-DOS versions earlier than 3.0 do not preserve any registers except cs:ip when you execute the exec call. In particular ss:sp is not preserved. If you're using DOS v2.x or earlier you'll need to use the following code:
;Example: Format a floppy disk in drive A: using the FORMAT.EXE command <push any registers you need preserved> mov cs:SS_Save ss ;Save SS:SP to a location mov cs:SP_Save sp ; we have access to later. mov ah 4Bh ;EXEC DOS opcode. mov al 0 ;Load and execute. mov dx seg PathName ;Get filename into DS:DX. mov ds dx lea dx PathName mov bx seg ParmBlock ;Point ES:BX at parameter mov es bx ; block. lea bx ParmBlock int 21h mov ss cs:SS_Save ;Restore SS:SP from saved mov sp cs:SP_Save ; locations. <Restore registers pushed onto the stack> . . . SS_Save word ? SP_Save word ? . . . PathName byte 'C:\DOS\FORMAT.EXE' 0 ParmBlock word 0 ;Default environment dword CmdLine ;Command line string dword Dummy Dummy ;Dummy ;FCBs CmdLine byte 3 ' A:' 0dh Dummy byte 20 dup (?)
SP_Save must be
declared inside your code segment. The other variables can be declared anywhere.
exec command automatically allocates
memory for the program being executed. If you haven't freed up unused memory before
executing this command
you may get an insufficient memory error. Therefore
use the DOS deallocate memory command to free up unused memory before attempting to use
al=1 when the
DOS will load the specified file but will not execute it. This function is
generally used to load a program to execute into memory but give the caller control and
let the caller start that code. When this function call is made
at the following parameter block:
Offset Description 0 Word value containing the segment address of the environment block for the new process. If you want to use the parent process' environment block set this word to zero. 2 Dword pointer to the command tail for this operation. The command tail is the command line string which will appear at location PSP:80. 6 Address of default FCB #1. For most programs this should point at a block of 20 zeros (unless of course you're running a program which uses FCBs.). 0Ah Address of default FCB #2. Should also point at a block of 20 zeros. 0Eh SS:SP value. You must load these four bytes into SS and SP before starting the application. 12h CS:IP value. These four bytes contain the starting address of the program.
CSIP fields are
output values. DOS fills in the fields and returns them in the load structure. The other
fields are all inputs which you must fill in before calling the
When you execute the
exec command with
DOS simply loads an overlay into memory. Overlays generally consist of a single code
segment which contains some functions you want to execute. Since you are not creating a
the parameter block for this type of load is much simpler than for the other
two types of load operations. On entry
es:bx must point at the following
parameter block in memory:
Offset Description 0 Word value containing the segment address of where this file is going to be loaded into memory. The file will be loaded at offset zero within this segment. 2 Word value containing a relocation factor for this file.
Unlike the load and execute functions
the overlay function
does not automatically allocate storage for the file being loaded. Your program has to
allocate sufficient storage and then pass the address of this storage block to the
command (though the parameter block above). Only the segment address of this block
is passed to the
the offset is always assumed to be zero. The
relocation factor should also contain the segment address for ".EXE" files. For
the relocation factor parameter should be zero.
The overlay command is quite useful for loading overlays
from disk into memory. An overlay is a segment of code which resides on the disk drive
until the program actually needs to execute its code. Then the code is loaded into memory
and executed. Overlays can reduce the amount of memory your program takes up by allowing
you to reuse the same portion of memory for different overlay procedures (clearly
one such procedure can be active at any one time). By placing seldom-used code and
initialization code into overlay files
you can help reduce the amount of memory used by
your program file. One word of caution
managing overlays is a very complex task.
This is not something a beginning assembly language programmer would want to tackle right
away. When loading a file into memory (as opposed to loading and executing a file)
does not scramble all of the registers
so you needn't take the extra care necessary to
ss:sp and other registers.
The MS-DOS Encyclopedia contains an excellent description
of the use of the
 Actually there are others. See the DOS technical reference manual for more details. We will only consider these three here.
 DOS also provides a call which will return the PSP for your program.
Chapter Thirteen: MS-DOS
File I/O (Part 5)
28 SEP 1996