下面的示例程序使用动态内存分配创建并填充了一个 1000 字节的数组:
- ; 堆测试 #1 (Heaptest1.asm)
- INCLUDE Irvine32.inc
- ; 使用动态内存分配,本程序分配并填充一个字节数据
- .data
- ARRAY_SIZE = 1000
- FILL_VAL EQU 0FFh
- hHeap DWORD ? ; 程序堆句柄
- pArray DWORD ? ; 内存块指针
- newHeap DWORD ? ; 新堆句柄
- str1 BYTE "Heap size is: ",0
- .code
- main PROC
- INVOKE GetProcessHeap ; 获取程序堆句柄
- .IF eax == NULL ; 如果失败,显示消息
- call WriteWindowsMsg
- jmp quit
- .ELSE
- mov hHeap,eax ; 成功
- .ENDIF
- call allocate_array
- jnc arrayOk ; 失败 (CF = 1)?
- call WriteWindowsMsg
- call Crlf
- jmp quit
- arrayOk: ; 成功填充数组
- call fill_array
- call display_array
- call Crlf
- ; 释放数组
- INVOKE HeapFree, hHeap, 0, pArray
-
- quit:
- exit
- main ENDP
- ;--------------------------------------------------------
- allocate_array PROC USES eax
- ;
- ; 动态分配数组空间
- ; 接收: EAX = 程序堆句柄
- ; 返回: 如果内存分配成功,则 CF = 0
- ;--------------------------------------------------------
- INVOKE HeapAlloc, hHeap, HEAP_ZERO_MEMORY, ARRAY_SIZE
-
- .IF eax == NULL
- stc ; 返回 CF = 1
- .ELSE
- mov pArray,eax ; 保存指针
- clc ; 返回 CF = 0
- .ENDIF
- ret
- allocate_array ENDP
- ;--------------------------------------------------------
- fill_array PROC USES ecx edx esi
- ;
- ; 用一个字符填充整个数组
- ; 接收: 无
- ; 返回: 无
- ;--------------------------------------------------------
- mov ecx,ARRAY_SIZE ; 循环计数器
- mov esi,pArray ; 指向数组
- L1: mov BYTE PTR [esi],FILL_VAL ; 填充每个字节
- inc esi ; 下一个位置
- loop L1
- ret
- fill_array ENDP
- ;--------------------------------------------------------
- display_array PROC USES eax ebx ecx esi
- ;
- ; 显示数组
- ; 接收: 无
- ; 返回: 无
- ;--------------------------------------------------------
- mov ecx,ARRAY_SIZE ; 循环计数器
- mov esi,pArray ; 指向数组
-
- L1: mov al,[esi] ; 取出一个字节
- mov ebx,TYPE BYTE
- call WriteHexB ; 显示该字节
- inc esi ; 下一个位置
- loop L1
- ret
- display_array ENDP
- END main
下面的示例采用动态内存分配重复分配大块内存,直到超过堆大小。
- ; 堆测试 #2 (Heaptest2.asm)
- INCLUDE Irvine32.inc
- .data
- HEAP_START = 2000000 ; 2 MB
- HEAP_MAX = 400000000 ; 400 MB
- BLOCK_SIZE = 500000 ; 0.5 MB
- hHeap DWORD ? ; 堆句柄
- pData DWORD ? ; 块指针
- str1 BYTE 0dh,0ah,"Memory allocation failed",0dh,0ah,0
- .code
- main PROC
- INVOKE HeapCreate, 0,HEAP_START, HEAP_MAX
- .IF eax == NULL ; 失败?
- call WriteWindowsMsg
- call Crlf
- jmp quit
- .ELSE
- mov hHeap,eax ; 成功
- .ENDIF
- mov ecx,2000 ; 循环计数器
- L1: call allocate_block ; 分配一个块
- .IF Carry? ; 失败?
- mov edx,OFFSET str1 ; 显示消息
- call WriteString
- jmp quit
- .ELSE ; 否: 打印一个点来显示进度
- mov al,'.'
- call WriteChar
- .ENDIF
-
- ;call free_block ; 允许/禁止本行
- loop L1
-
- quit:
- INVOKE HeapDestroy, hHeap ; 销毁堆
- .IF eax == NULL ; 失败?
- call WriteWindowsMsg ; 是: 错误消息
- call Crlf
- .ENDIF
- exit
- main ENDP
- allocate_block PROC USES ecx
- INVOKE HeapAlloc, hHeap, HEAP_ZERO_MEMORY, BLOCK_SIZE
-
- .IF eax == NULL
- stc ; 返回 CF = 1
- .ELSE
- mov pData,eax ; 保存指针
- clc ; 返回 CF = 0
- .ENDIF
- ret
- allocate_block ENDP
- free_block PROC USES ecx
- INVOKE HeapFree, hHeap, 0, pData
- ret
- free_block ENDP
- END main