Win32汇编——内存管理

来源:互联网 发布:身份证借别人开淘宝 编辑:程序博客网 时间:2024/05/21 00:56

一、内存管理基础

1.Windows的内存分层管理图:


2.不同内存管理函数的操作对象图:


3.GlobalMemoryStatus函数通过MEMORYSTATUS结构获取系统内存信息,示例代码如下:

.constszInfodb'物理内存总数     %lu 字节',0dh,0ahdb'空闲物理内存     %lu 字节',0dh,0ahdb'虚拟内存总数     %lu 字节',0dh,0ahdb'空闲虚拟内存     %lu 字节',0dh,0ahdb'已用内存比例     %d%%',0dh,0ahdb'————————————————',0dh,0ahdb'用户地址空间总数 %lu 字节',0dh,0ahdb'用户可用地址空间 %lu 字节',0dh,0ah,0.code_GetMemInfoprocLOCAL@stMemInfo:MEMORYSTATUSLOCAL@szBuffer[1024]:bytemov@stMemInfo.dwLength,sizeof @stMemInfoinvokeGlobalMemoryStatus,addr @stMemInfoinvokewsprintf,addr @szBuffer,addr szInfo,\@stMemInfo.dwTotalPhys,@stMemInfo.dwAvailPhys,\@stMemInfo.dwTotalPageFile,@stMemInfo.dwAvailPageFile,\@stMemInfo.dwMemoryLoad,\@stMemInfo.dwTotalVirtual,@stMemInfo.dwAvailVirtualinvokeSetDlgItemText,hWinMain,IDC_INFO,addr @szBufferret_GetMemInfo endp

二、标准内存管理函数

1.功能:在进程的默认堆中申请和释放内存块

2.主要的函数有:

申请:GlobalAlloc

释放:GlobalFree

修改:GlobalReAlloc

锁定:GlobalLock

解锁:GlobalUnlock

丢弃:GlobalDiscard

其它:GlobalFlags、GlobalHandle、GlobalSize

建议:GlobalAlloc跟LocalAlloc等函数是为兼容而保留的,Win32下两组函数完全相同,都是在底层直接调用HeapAlloc函数从默认堆分配内存,建议使用HeapAlloc函数。

3.可分配的内存有两种:固定的内存块和可移动的内存块(可进一步定义为可丢弃的内存块)

可通过在申请时指定标志来创建不同的内存块

GMEM_FIXED:固定

GMEM_ZEROINIT:0初始化

GPTR:GMEM_FIXED or GMEM_ZEROINIT 组合

GMEM_MOVEABLE:可移动的

GMEM_DISCARDABLE:可丢弃的

4.调整可移动内存块的大小最好还是先将内存解锁,等调整完毕后再锁定使用

注意:Win32下以上函数仅仅是为了兼容而存在,系统不保证这些函数在使用上不会出错,而在底层已经不再去做碎片拼合的工作。HeapAlloc等函数不支持可移动内存机制,所以在Win32下要防止内存碎片化,最好的办法还是使用内存池


三、堆管理函数

Windows的堆分为两种:

默认堆:由OS自动创建,只有一个,可直接使用

私有堆:使用前需先创建,可以有多个

使用私有堆的好处:

1.空间预留,避免同步冲突,增加运行速度

2.某些情况,防止系统频繁在物理内存和交换文件之间进行数据交换,提高系统性能

3.封装和保护模块化程序

4.便于扫尾工作,无需像默认堆一般将内存一块块单独释放

主要函数有:

创建私有堆: HeapCreate

释放私有堆: HeapDestroy

在堆中分配内存:HeapAlloc

释放内存: HeapFree

修改内存块大小:HeapReAlloc

获取默认堆:GetProcessHeap

列出进程中所有堆:GetProcessHeaps

列出堆中所有内存块:HeapWalk

验证堆的完整性或堆中某内存块的完整性:HeapValidate

锁定堆:HeapLock

解锁:HeapUnlock

(这两个函数可用于线程同步,不过一般不采用,而是采用HEAP_NO_SERIALIZE标志)

合并堆中空闲内存并释放不在使用中的内存页:HeapCompact

获取堆中某块内存大小:HeapSize


注意:

1.出错代码的定义值都大于0c0000000h,因为0c0000000h开始的地址空间为系统使用,分配的内存地址不可能高于这个地址,所以检测函数的形式可以如下:

invoke HeapCreate,flOptions,dwInitialSize,dwMaximumSize.if  eax && (eax < 0c0000000h)     mov hHeap,eax.endif

2.在堆中分配的内存块只能是固定地址的内存块


四、虚拟内存管理函数(书P339)

主要函数:

VirtualAlloc 和 VirtualFree :进行地址空间的分配和释放工作

VirtualLock 和 VirtualUnlock :对内存页进行锁定和解锁

VirtualQuery(Ex):查询内存页状态

VirtualProtext(Ex):改变内存页的保护模式


五、其他内存管理函数

填充和移动内存:

RtlMoveMemory、RtlFillMemory、RtlZeroMemory


内存状态测试:

IsBadCodePtr、IsBadReadPtr、IsBadWritePtr、IsBadStringPtr


原创粉丝点击