下面的示例程序使用动态内存分配创建并填充了一个 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