Part1 - Part2 - Part3 - Single Page

Top Document: x86 Assembly Language FAQ - General Part 3/3
Previous Document: 26. WWW Assembly HomePages
Next Document: 28. Volume Serial Numbers


[ Usenet FAQs | Search | Web FAQs | Documents | RFC Index ]

27. Common Reason Why Memory Allocation Fails


27.1  BACKGROUND

A common error received when first learning to use Int 21h Function 48h,
allocate memory, is error code 8, insufficient memory available.
Usually, the programmer then writes a small program that only allocates
memory, and the program still fails.  This situation is quite puzzling
because there should be hundreds of kilobytes of memory available but
this function reports that there is insufficient memory for a few
hundred bytes.  The reason is that DOS generally allocates all available
memory above the loaded program to that program.  Therefore, there is no
more memory to allocate, so the request fails.

27.2  .COM FILES

Since a .COM file does not contain any header information, the DOS
loader has no way of determining how much memory is required for a
program beyond the physical size of the program.  Even this number is
deceptive because it does not include a stack.  Therefore, DOS always
allocates all available memory above the program to the program.

To use the allocate memory function, the programmer must release that
extra memory using Int 21h Function 4ah, Set Memory Block Size.  Given
that generally there is more that 64 Kbytes of memory, the DOS sets
Stack Top to just under that value, it is generally safe to release all
memory above 64 Kbytes.

27.3 .EXE FILES

The amount of memory the DOS allocates to the loaded program depends
upon a value in the .EXE header.  This value is called Maximum
Allocation and is a word starting at offset 12.  This value specifies
the number of 16-byte paragraphs beyond the image size wanted by the
program to execute.  This value must be equal or greater than the
Minimum Allocation, which is the number of 16-byte paragraphs beyond the
image size required by the program to execute.  This space generally
contains uninitialized variables and the stack.

The value of Maximum Allocation is set by the /CPARM Option for the
Microsoft Linker.  By default, the linker sets this value to 0ffffh that
will causes DOS to allocate the largest block of available memory.  This
memory can be used as a heap, print buffer, etc.

27.4  DETERMINING HOW MUCH MEMORY IS AVAILABLE TO A PROGRAM

In the PSP, at offset 02h, DOS loads a word that is the segment address
of the next Memory Control Block or Arena.  Subtracting the PSP from
that value at offset 02h will be the number of memory paragraphs
allocated to the program.  The number of bytes can be calculated by
shifting that number to the left by 4 bits, multiplying by 16, the size
of a memory paragraph.

27.5  HOW TO DEALLOCATE MEMORY AT THE START OF A PROGRAM

If you want to load and execute another program, you must release memory
to make room for the program.  Also, since the largest chunk of memory
is allocated already to the program, all requests to allocate memory
generally fail.

Again, to use the allocated memory function, the programmer must release
the extra memory above the program use as for a .COM file above.  The
problem here is where is the end of the program.  The answer is not as
simple as with the .COM file.  There are two basic solutions.

1.  If you use the .dosseg option, the Microsoft Linker will define a
label, _end, at the end of the DGROUP.  Since the .dosseg option also
places any FAR data segments between the code and DGROUP segments, you
can release all memory above that label.

2.  If you do not want or are unable to use the first option, use an
include file which declares all segments used by your program.  Define a
label in the last segment and use it as the _end label in the first
example.

27.6  TELLING DOS NOT TO ALLOCATE ALL AVAILABLE MEMORY AT STARTUP

If you are using a Microsoft Linker or a compatible linker, you can use
the /CPARMMAXALLOC or /CP switch.  Set this switch to /CP:1.  The Linker
places 1 at offset 0ch in the .exe header.  This tells DOS that you only
need a maximum of 1 paragraph of memory above your program.  DOS
compares this to the minimum memory required at offset 0ah in the .exe
header.  If the max is less than the minimum, DOS assigns the minimum.
Therefore, your program gets only the memory necessary for it to
execute, and all other memory above your program is available for
allocation.

Contributor:  Raymond Moon, raymoon@moonware.dgsys.com
Last changed: 21 Feb 99



Top Document: x86 Assembly Language FAQ - General Part 3/3
Previous Document: 26. WWW Assembly HomePages
Next Document: 28. Volume Serial Numbers

Part1 - Part2 - Part3 - Single Page


[ Usenet FAQs | Search | Web FAQs | Documents | RFC Index ]

Send corrections/additions to the FAQ Maintainer:
raymoon@moonware.dgsys.com

Last Update May 13 2007 @ 00:21 AM