首页 > 汇编语言 > 汇编语言MS-Windows编程
阅读:1,553
汇编语言实例:动态内存分配
下面的示例程序使用动态内存分配创建并填充了一个 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