Memory Management

In this section, several functions allowing you to dynamically allocate and delete memory blocks are covered.

Consider the GlobalAlloc function. Another function, LocalAlloc , is equivalent to GlobalAlloc and has been preserved exclusively for compatibility with older applications. The function has two arguments. The first argument is the flag, which will be covered later. The second argument is the number of the required memory bytes to allocate. If this function completes successfully, it returns the starting address of the block that can be used in further operations. If the system cannot allocate the requested memory block, it returns zero.

Usually, the flag value is set to the GMEM_FIXED constant, which is equal to zero. This means that the memory block is fixed, and the virtual block address will not change, although the physical memory address, to which this block is mapped, can be changed by the system. Combining this flag with the GMEM_ZEROINIT flag automatically fills the allocated block with zeros, which is often convenient . The size of the allocated block can be changed using the GlobalReAlloc function. The first argument of this function is the pointer to the block that needs to be changed, the second argument is the size of the new block, and the third argument is the flag. Note that this function can change the properties of the memory blockfor example, make it movable.

Consider the flags of the GlobalAlloc function. If your program works with memory intenselyfor example, it frequently allocates and releases the memorythe memory may become fragmented . After all, you do not allow it to move memory blocks. In this case, it is possible to use the GMEM_MOVEABLE flag. Having allocated a block, you can fix it at any time using the GlobalLock function, after which it is possible to work with that block without worrying. The Globalunlock function allows you to remove blocking at any time, enabling the system to organize blocks. It is only necessary to bear in mind that, when using the GMEM_MOVEABLE flag, the function returns the handle rather than the address. However, the handle is the argument of the GlobalLock function. As for the GlobalLock function, it returns the address.

An even more exotic approach is possible. This relates to the use of the GMEM_DISCARDABLE flag. This flag is used with the GMEM_MOVEABLE flag. In this case, the system can remove the block from the memory if you have not fixed it beforehand. If the block was removed by the system, then the GlobalLock function will return zero, and you'll have to allocate a block again and load data if necessary.

To delete the memory block, use the GlobalFree function. When a fixed memory block is allocated, the memory block address is the function argument. With a movable memory block, the argument is the descriptor. To release the memory block being deleted, use the GlobalDiscard function.

The GlobalMemoryStatus function deserves special mention. Using this function, it is possible to determine the amount of available memory. The only parameter of this function is the pointer to the structure containing information about the memory. Here is this structure:

 MEM STRUC         DwLength           DD ?         DwMemoryLoad       DD ?         DwTotalPhys        DD ?         DwAvailPhys        DD ?         DwTotalPageFile    DD ?         DwAvailPageFile    DD ?         DwTotalVirtual     DD ?         DwAvailVirtual     DD ? MEM ENDS 

The elements of this structure are as follows :

  • DwLength Structure size in bytes

  • DwMemoryLoad Percentage of the used memory

  • DwTotalPhys Total size of the physical memory in bytes

  • DwAvailPhys Size of the available physical memory in bytes

  • DwTotalPageFile Number of physical memory bytes flushed to the disk

  • DwAvailPageFile Number of available memory bytes stored on the disk

  • DwTotalvirtual Total size of the virtual memory

  • DwAvailvirtual Size of the available virtual memory

Listing 19.1 demonstrates the use of the GlobalAlloc function.

Listing 19.1: Dynamical memory allocation
image from book
 ; The MEM.ASM file .586P ; Flat memory model .MODEL FLAT, stdcall ; Constants ; For console output STD_OUTPUT_HANDLE  equ -11 GENERIC_READ       equ 80000000h OPEN_EXISTING       equ 3 IFDEF MASM ; MASM ; Prototypes of external procedures         EXTERN  GlobalFree@4:NEAR         EXTERN  GlobalAlloc@8:NEAR         EXTERN  GetFileSize@8:NEAR         EXTERN  CloseHandle@4:NEAR         EXTERN  CreateFileA@28:NEAR         EXTERN  ReadFile@20:NEAR         EXTERN  GetStdHandle@4:NEAR         EXTERN  WriteConsoleA@20:NEAR         EXTERN  ExitProcess@4:NEAR         EXTERN  GetCommandLineA@0:NEAR ; INCLUDELIB directives for the linker         includelib c:\masm32\lib\user32.lib         includelib c:\masm32\lib\kernel32.lib ELSE ; TASM LOCALS ; Prototypes of external procedures         EXTERN  GlobalFree:NEAR         EXTERN  GlobalAlloc:NEAR         EXTERN  GetFileSize:NEAR         EXTERN  CloseHandle:NEAR         EXTERN  CreateFileA:NEAR         EXTERN  ReadFile:NEAR         EXTERN  GetStdHandle:NEAR         EXTERN  WriteConsoleA:NEAR         EXTERN  ExitProcess:NEAR         EXTERN  GetCommandLineA:NEAR         GlobalFree@4 = GlobalFree         GlobalAlloc@8 = GlobalAlloc         GetFileSize@8 = GetFileSize         CloseHandle@4 = CloseHandle         CreateFileA@28 = CreateFileA         ReadFile@20 = ReadFile         GetStdHandle@4 = GetStdHandle         WriteConsoleA@20 = WriteConsoleA         ExitProcess@4 = ExitProcess         GetCommandLineA@0 = GetCommandLineA ; INCLUDELIB directives for the linker         includelib c:\tasm32\lib\import32.lib ENDIF ;----------------------------------------------- ; Data segment _DATA SEGMENT         LENS   DWORD ?         HANDL  DWORD ? ; Console descriptor         HF     DWORD ? ; File descriptor         SIZEH  DWORD ? ; Most significant part of the file length         SIZEL  DWORD ? ; Least significant part of the file length         GH     DWORD ? ; Pointer to the memory block         NUMB   DWORD ?         BUF    DB 10 DUP(0) _DATA ENDS ; Code segment _TEXT SEGMENT START: ; Get the output handle         PUSH  STD_OUTPUT_HANDLE         CALL  GetStdHandle@4         MOV   HANDL, EAX ; Get the number of parameters CALL NUMBAR         CMP   EAX, 2         JB    _EXIT ; ----------------------------------- ; Get the parameter with the EDI number         MOV   EDI, 2         LEA   EBX, BUF         CALL  GETPAR ; Now, work with the file ; Open as a read-only file         PUSH  0         PUSH  0         PUSH  OPEN_EXISTING         PUSH  0         PUSH  0         PUSH  GENERIC_READ         PUSH  OFFSET BUF         CALL  CreateFileA@28         CMP   EAX, -1         JE    _EXIT ; Save the file descriptor         MOV   HF, EAX ; Determine the file size         PUSH  OFFSET SIZEH         PUSH  EAX         CALL  GetFileSize@8 ; Save the size, assuming that it ; doesn't exceed 4 GB         MOV   SIZEL, EAX- ; Request the memory for reading the file         PUSH  EAX         PUSH  0         CALL  GlobalAlloc@8         CMP   EAX, 0         JE    _CLOSE ; Store the address of the allocated block         MOV   GH, EAX ; Read the file into the allocated memory         PUSH  0         PUSH  OFFSET NUMB         PUSH  SIZEL         PUSH  GH ; Buffer address         PUSH  HF         CALL  ReadFile@20         CMP   EAX, 0         JE    _FREE ; Output the read data         PUSH  0         PUSH  OFFSET LENS         PUSH  SIZEL         PUSH  GH         PUSH  HANDL         CALL  WriteConsoleA@20 _FREE: ; Release the memory         PUSH  GH         CALL  GlobalFree@4 ; Close the files _CLOSE:         PUSH  HF         CALL  CloseHandle@4 _EXIT: ; Exit the program         PUSH  0         CALL  ExitProcess@4 ;-------------------------------------------- ; Procedures area ; The procedure for determining the number of parameters in the string ; Determine the number of parameters (->EAX) NUMPAR PROC         CALL  GetCommandLineA@0         MOV   ESI, EAX ; Pointer to the string         XOR   ECX, ECX ; Counter         MOV   EDX, 1 ; Flag @@L1:         CMP   BYTE PTR [ESI], 0         JE    @@L4         CMP   BYTE PTR [ESI], 32         JE    @@L3         ADD   ECX, EDX ; Parameter number         MOV   EDX, 0         JMP   @@L2 @@L3:         OR    EDX, 1 @@L2:     INC   ESI     JMP   @@L1 @@L4:     MOV   EAX, ECX     RET NUMPAR ENDP ; Get the parameter from the command line ; EBX --- Points to the buffer, in which the parameter will be stored ; Zero-terminated string is placed into the buffer ; EDI --- Parameter number GETPAR PROC     CALL  GetCommandLineA@0     MOV   ESI, EAX ; Pointer to the string     XOR   ECX, ECX ; Counter     MOV   EDX, 1 ; Flag @@L1:     CMP   BYTE PTR [ESI], 0     JE    @@L4     CMP   BYTE PTR [ESI], 32     JE    @@L3     ADD   ECX, EDX ; Parameter number     MOV   EDX, 0     JMP   @@L2 @@L3:     OR,   EDX, 1 @@L2:     CMP   ECX, EDI     JNE   @@L5     MOV   AL, BYTE PTR [ESI]     MOV   BYTE PTR [EBX], AL     INC   EBX @@L5:     INC   ESI     JMP   @@L1 @@L4:     MOV   BYTE PTR [EBX], 0     RET GETPAR ENDP _TEXT ENDS END START 
image from book
 

To translate the program presented in Listing 19.1, issue the following commands for MASM32:

 ML /c /coff /DMASM MEM.ASM     LINK /SUBSYSTEM:CONSOLE MEM.OBJ 

Issue the following commands for TASM32:

 TASM32 /ml MEM.ASM     TLINK32 -ap MEM.OBJ 

Windows also provides a special group of functions for managing virtual memory. The main function of this group is the virtualAlloc function that accepts the following parameters:

  • First parameterThis parameter specifies the desired starting address to allocate or reserve. As a rule, it is assumed to be zero, which allows the system to determine, in which part of the address space to allocate the memory.

  • Second parameterThis is the region size.

  • Third parameterThis parameter can take the following values: MEM_RESERVE for reserving a block, MEM_COMMIT for reserving a block and passing physical memory to it, MEM_PHYSICAL for allocating physical memory, MEM_RESET for informing the system that the data in the block will not be needed, and MEM_TOP_DOWN for informing the system that the memory must be reserved at the highest possible addresses.

  • Fourth parameterThis defines the protection level of the memory region. It can take the following values: PAGE_READONLY, PAGE_READWRITE, PAGE_EXECUTE , or any other constant defined in Windows documentation.

The function returns the virtual address of the allocated region of memory pages.

The main idea of this function is that you can reserve a memory block that is not mapped to the physical memory and then ensure that the entire block or part of it is mapped to the physical memory. After that, the memory block can be used. Note that the function will allocate a memory block that is a multiple of 64 KB with an address that also is a multiple of 64 KB.

Another function, VirtualFree, can free blocks allocated using the VirtualAlloc function. The fist parameter of this function is the block address. The second parameter is the size of the block to be freed. The third parameter can take one of the following two values: MEM_DECOMMIT or MEM_RELEASE . In the first case, the block or part of it ceases to be mapped. In the second case, the entire block ceases to be reserved and the second parameter must be zero; if it is not, the function fails.



The Assembly Programming Master Book
The Assembly Programming Master Book
ISBN: 8170088178
EAN: 2147483647
Year: 2004
Pages: 140
Authors: Vlad Pirogov

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net