首页 > 汇编语言 > 汇编语言MS-Windows编程
汇编语言实例:动态内存分配
下面的示例程序使用动态内存分配创建并填充了一个 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
所有教程
- C语言入门
- C语言编译器
- C语言项目案例
- 数据结构
- C++
- STL
- C++11
- socket
- GCC
- GDB
- Makefile
- OpenCV
- Qt教程
- Unity 3D
- UE4
- 游戏引擎
- Python
- Python并发编程
- TensorFlow
- Django
- NumPy
- Linux
- Shell
- Java教程
- 设计模式
- Java Swing
- Servlet
- JSP教程
- Struts2
- Maven
- Spring
- Spring MVC
- Spring Boot
- Spring Cloud
- Hibernate
- Mybatis
- MySQL教程
- MySQL函数
- NoSQL
- Redis
- MongoDB
- HBase
- Go语言
- C#
- MATLAB
- JavaScript
- Bootstrap
- HTML
- CSS教程
- PHP
- 汇编语言
- TCP/IP
- vi命令
- Android教程
- 区块链
- Docker
- 大数据
- 云计算