[ Usenet FAQs | Search | Web FAQs | Documents | RFC Index ]
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
Send corrections/additions to the FAQ Maintainer:
Last Update May 13 2007 @ 00:21 AM