| January 2003 Laboratory Notes: Computer Engineering II | ||
|---|---|---|
| Prev | Chapter 18 Introduction to PModeLib | Next |
Allocating memory is something that was never needed in the MP's up to this point. So why is it necessary to learn about it now? Primarily because we're going to start working with some really big (multi-megabyte) data such as images. Once a program's memory usage goes beyond a few kilobytes, it's smart to dynamically allocate memory at run time, and PModeLib provides a function to make this task much easier.
AllocMem() takes just a single parameter: Size, which specifies the number of bytes to allocate. It returns the starting offset of the newly allocated block, which you can use just like any other offset (such as to a variable). Generally it's a smart idea to store this offset in a variable, which adds a layer of indirection, but makes it easier to allocate and keep track of several memory blocks at once. There is no way to free memory once it's allocated; the memory is freed when the program exits.
Example 18-3. Allocating Memory
%include "lib291.inc"
GLOBAL _main
test1size equ 4*1024*1024 ; 4 MB
test2size equ 1*1024*1024 ; 1 MB
SECTION .bss ; Uninitialized data
test1off resd 1 ; stores offset of test1 data
test2off resd 1 ; stores offset of test2 data
SECTION .text
_main
push esi ; Save registers
push edi
call _LibInit ; You could use invoke here, too
test eax, eax ; Check for error (nonzero return value)
jnz near .initerror
; Allocate test1 memory block
invoke _AllocMem, dword test1size
cmp eax, -1 ; Check for error (-1 return value)
je near .error
mov [test1off], eax ; Save offset in variable
; Allocate test2 memory block
invoke _AllocMem, dword test2size
cmp eax, -1 ; Check for error (-1 return value)
je near .error
mov [test2off], eax ; Save offset in variable
; Fill the test1 block with 0's.
; We don't need to set es=ds, because it's that way at start.
xor eax, eax ; Fill with 0
mov edi, [test1off] ; Starting address (remember indirection)
mov ecx, test1size/4 ; Filling doublewords (4 bytes at a time)
rep stosd ; Fill!
; Copy from last meg of test1 to test2
mov esi, [test1off] ; Starting address of source
add esi, test1size-1024*1024 ; Move offset to last meg
mov edi, [test2off] ; Destination
mov ecx, test2size/4 ; Copying dwords
rep movsd
.error:
call _LibExit
.initerror:
pop edi ; Restore registers
pop esi
ret ; Return to DOS