标准内存管理函数
GlobalAlloc,GlobalFree,GlobalReAlloc,GlobalLock,GlobalUnlock,GlobalDiscard,GlobalFlags,GlobalHandle,GlobalSize
1.固定的内存块
invoke GlobalAlloc,GMEM_FIXED or GMEM_ZEROINIT,dwBytes
.if eax
mov lpMemory,eax
.endif
申请失败eax返回NULL,成功返回指向申请内存起始地址的指针.GPTR
释放固定内存块
invoke GlobalFree,lpMemory
释放成功返回NULL,返否返回输入的lpMemory
改变内存块大小
invoke GlobalReAlloc,lpMemory,dwBytes,uFlags
.if eax
mov lpNewMemory,eax
.endif
lpMemory是先前申请的内存指针,dwBytes是新大小,uFlags可以是空
uFlags来规定是否允许移动内存块,当为GMEM_MOVEABLE选项时,如果需要移动内存块windows会在其它地方新开一个内存块,并把原来的内容自动复制到新内存中,这时函数会返回一个新的指针,原来的指针作废
如果不指定GMEM_MOVEABLE,当后面的空间不足时,函数失败并返回NULL,原来的指针继续有效.
改变内存大小时,建意使用以下代码
invoke GlobalReAlloc,lpMemory,dwBytes,GMEM_ZEROINIT or GMEM_MOVEABLE
.if eax
mov lpMemory,eax
.endif
2.可移动的内存块
申请可移动的内存块
invoke GlobalAlloc,GMEM_MOVEABLE or GMEM_ZEROINIT,dwBytes
.if eax
mov hMemory,eax
.endif
GMEM_MOVEABLE or GMEM_ZEROINIT = GHND
申请失败eax返回NULL,成功返回一个句柄.可移动内存块不能超过65536个,固定内存块数量无限制
销定可移动内存:
invoke GlobalLock,hMemory
.if eax
mov lpMemory,eax
.endif
销定失败返回NULL,成功返回一个指针
当不使用时要解销
invoke GlobalUnlock,hMemory
解销成功返回非0值
释放可移动内存块
invoke GlobalFree,hMemory
释放成功返回NULL
调整可移动内存块大小
invoke GlobalReAlloc,hMemory,dwBytes,GHND
如果成功返回hMemory,失败返回NULL
注意最好先解销再调整大小
3.可丢弃的内存块
可丢弃的内存块必须是可移动的内存块
invoke GlobalAlloc,GHND or GMEM_DISCARDABLE,dwBytes
.if eax
mov hMemory,eax
.endif
如果GlobalLock内存返回NULL,说明内存以被丢弃了,但句柄还是有效的,如果还要使用这个句柄,可以使用
GlobalReAlloc来重新分配内存,当销定计数为0时,可以使用GlobalDiscard主动将它丢弃.
4.获取内存块的信息
GlobalFlags主要用来取得可移动内存的计数,也可以检测可丢弃内存是否被丢弃.
invoke GlobalFlags,hMemory
and eax,GMEM_LOCKCOUNT
mov dwLockCount,eax
返回值不是GMEM_INVALID_HANDLE说明调用成功,这时返回值低8位是内存块的销定计数
GMEM_DISCARDABLE 表示内存块是可丢弃内存块
GMEM_DISCARDED 表示内存块以被失弃
GlobalHandle可以从GlobalLock得到的lpMemory值获取对应的hMemory
GlobalSize可以获取一个内存块的尺寸