How to Allocate Memory From the MS-DOS Upper Memory AreaID: Q102325
|
In MS-DOS version 5.0, an application can dynamically allocate blocks of memory from the MS-DOS upper-memory area. To do so, the application calls Function 5803h, Set Upper-Memory Link, before it calls the malloc() function in the C run-time library.
The first 640KB of MS-DOS memory is commonly called "conventional
memory." The address space immediately above that, in the address
range from 640K to 1024K is the Upper Memory Area (UMA).
When an application developed in the compact or large memory model
uses malloc() to dynamically allocate memory, malloc() acquires memory
in the MS-DOS far heap to satisfy the request. By default, MS-DOS
makes only conventional memory available to an application because, by
default, MS-DOS does not link conventional memory with the 384K of UMA
memory immediately above conventional memory.
MS-DOS version 5.0 introduces the ability to satisfy allocation
requests with the UMA on machines that have an 80386 or greater
processor and that have physical memory installed in the address space
from 640K to 1024K. Both HIMEM.SYS and EMM386 must be installed, and
the CONFIG.SYS file must contain the line DOS=UMB.
The code example below demonstrates establishing the link to the
MS-DOS UMA and allocating memory from the UMA.
NOTE: This example does not work when an application other than
MS-DOS, such as 386MAX, manages the UMA.
By default, the MS-DOS memory allocation strategy involves searching
memory from the available memory block with the lowest address. If the
upper-memory link is established, MS-DOS searches the UMA only after
all conventional memory has been exhausted. You can change this
allocation strategy using the MS-DOS Function 5801h, Set Allocation
Strategy. For example, your application can choose to search only the
UMA.
If you change the upper-memory link state or the original MS-DOS
memory allocation strategy, you must restore them before terminating
your application.
/*
* Compiler options needed: /AL or /AC
*/
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <malloc.h>
#include <dos.h>
void main(void)
{
int i;
char in;
union REGS inregs, outregs;
printf("Link upper-memory area? Y/N: ");
in = getche();
while (in != 'Y' && in != 'y' && in != 'N' && in != 'n')
{
printf("\nLink upper-memory area? Y/N: ");
in = getche();
}
if (in == 'Y' || in == 'y')
{
// Link upper-memory area
inregs.x.ax = 0x5803;
inregs.x.bx = 0x0001;
int86(0x21, &inregs, &outregs);
if (outregs.x.cflag)
printf("\n** Set Upper-Memory Link error **\n");
}
// malloc() as many 1KB blocks as possible
for (i = 0; ; i++)
{
if (!malloc(1024))
break;
}
printf("\n%d KB successfully allocated\n", i);
// Unlink UMA
inregs.x.ax = 0x5803;
inregs.x.bx = 0x0000;
int86(0x21, &inregs, &outregs);
if (outregs.x.cflag)
printf("** Set Upper-Memory Link error **\n");
}
Running the application produced the following output. The MEM /C
command showed that the test machine had 582K available conventional
memory and 76K free in the UMA.
Link upper-memory area? Y/N: n
503 KB successfully allocated
Link upper-memory area? Y/N: y
578 KB successfully allocated
Additional query words: kbinf 1.00 1.50 6.00 6.00a 6.00ax 7.00
Keywords : kb16bitonly
Version :
Platform :
Issue type :
Last Reviewed: August 3, 1999