首页
社区
课程
招聘
对罗云彬WIN32汇编中程序的疑问,为什么内存碎片对系统XPSP3没有影响?
发表于: 2010-1-26 22:43 4851

对罗云彬WIN32汇编中程序的疑问,为什么内存碎片对系统XPSP3没有影响?

2010-1-26 22:43
4851
我在看罗云彬WIN32汇编中的内存管理章节中有一个疑问:
Chapter10\Fragment中的程序执行后操作系统还能正常运行,用进程查询工具看该程序的内存占用率还是很低,请问这是为什么?

程序说明:
在这个例子中,让我们来设计一个“阴谋”,用一个极端的方法“谋杀”掉所有的地址空间:程序首先申请一个1 MB大小的固定内存块,然后继续申请内存并把前面申请的内存块大小改为100 B,由此循环,因为缩小内存块释放出来的空间大小为999 900 B,新申请的内存块无法使用这些地址空间,只能继续使用后面大块的地址空间,如果没有算错的话,经过2 000次左右的循环就会把全部的地址空间分割成2 000个999 900 B大小的空间(2GB等于2 000个1 MB),到时候虽然只保留了近200 KB大小的内存(2 000个100 B),但是这2 000个100 B均匀分布在2 GB的地址空间内,以至于接下来任何大于999 900 B的内存申请操作都无法成功。

源码:
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Sample code for < Win32ASM Programming >
; by 罗云彬, http://asm.yeah.net
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Fragment.asm
; 重复分配和释放固定内存块使内存碎片化
; Windows NT 下使用。
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 使用 nmake 或下列命令进行编译和链接:
; ml /c /coff Fragment.asm
; rc Fragment.rc
; Link /subsystem:windows Fragment.obj Fragment.res
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
                .386
                .model flat, stdcall
                option casemap :none
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Include 文件定义
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include                windows.inc
include                user32.inc
includelib        user32.lib
include                kernel32.inc
includelib        kernel32.lib
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Equ 等值定义
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
ICO_MAIN        equ        1000
DLG_MAIN        equ        100
IDC_MEMORY        equ         101
IDC_COUNT        equ         102
IDC_INFO        equ        103
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 数据段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
                .data?

hInstance        dd        ?
hWinMain        dd        ?
dwTotalMemory        dd        ?
dwCount                dd        ?
ifCanQuit        dd        ?

                .const
szInfo                db        '无法继续申请 1MB 大小的内存!',0
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 代码段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
                .code
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_ProcThread        proc        uses ebx ecx edx esi edi,lParam
                local        @lpLastMem

                invoke        GlobalAlloc,GPTR,1000000
                mov        @lpLastMem,eax
                inc        dwCount
                add        dwTotalMemory,1000000
                .repeat
                        push        @lpLastMem
                        invoke        GlobalAlloc,GPTR,1000000
                        mov        @lpLastMem,eax
                        .if        eax
                                add        dwTotalMemory,1000000
                                inc        dwCount
                        .endif
                        pop        eax
                        invoke        GlobalReAlloc,eax,100,GMEM_ZEROINIT
                        sub        dwTotalMemory,1000000 - 100
                        invoke        SetDlgItemInt,hWinMain,IDC_MEMORY,dwTotalMemory,FALSE
                        invoke        SetDlgItemInt,hWinMain,IDC_COUNT,dwCount,FALSE
                .until        ! @lpLastMem
                invoke        SetDlgItemText,hWinMain,IDC_INFO,addr szInfo
                mov        ifCanQuit,1
                ret

_ProcThread        endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_ProcDlgMain        proc        uses ebx edi esi hWnd,wMsg,wParam,lParam
                local        @dwTemp

                mov        eax,wMsg
                .if        eax ==        WM_CLOSE
                        .if        ifCanQuit
                                invoke        EndDialog,hWnd,NULL
                        .endif
;********************************************************************
                .elseif        eax ==        WM_INITDIALOG
                        push        hWnd
                        pop        hWinMain
                        invoke        LoadIcon,hInstance,ICO_MAIN
                        invoke        SendMessage,hWnd,WM_SETICON,ICON_BIG,eax
                        invoke        CreateThread,NULL,0,offset _ProcThread,NULL,\
                                NULL,addr @dwTemp
                        invoke        CloseHandle,eax
;********************************************************************
                .else
                        mov        eax,FALSE
                        ret
                .endif
                mov        eax,TRUE
                ret

_ProcDlgMain        endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
start:
                invoke        GetModuleHandle,NULL
                mov        hInstance,eax
                invoke        DialogBoxParam,hInstance,DLG_MAIN,NULL,offset _ProcDlgMain,NULL
                invoke        ExitProcess,NULL
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
                end        start

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 0
支持
分享
最新回复 (8)
雪    币: 354
活跃值: (26)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
2
因为:
每个应用程序都有相互独立的 4GB 寻址空间,不同应用程序的地址空间是隔离的;

你这个程序只是把它自己的内存空间搞得支离破碎,但其它程序(当然也包括系统程序)是不会受影响的。
2010-1-26 22:51
0
雪    币: 86
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
那么实际上 invoke  GlobalAlloc,GPTR,1000000 函数没有给应用程序分配内存吗?

GMEM_ZEROINIT
将所申请内存初始化为0.
GMEM_FIXED
分配固定的内存,返回值是一个指针.

函数说明含糊不清与实际情况不符,在这种情况下操作系统做了哪些处理能说一下吗?谢谢
2010-1-26 22:59
0
雪    币: 86
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
我将该程序修改为无限循环,程序依然可以正常运行,但观察发现每次申请的内存总数都在减少,每次减少4KB估计和分页管理有关,希望有高手能给解释下,系统是怎样管理的
2010-1-27 00:25
0
雪    币: 131
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
建议你去看一下操作系统,并且参考一下linux的一些资料。
2010-1-27 08:40
0
雪    币: 23
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
invoke  GlobalReAlloc,eax,100,GMEM_ZEROINIT

这样写的结果会不会改变GPTR为GMEM_ZEROINIT丢失GMEM_FIXED,问一下
2010-1-27 16:31
0
雪    币: 285
活跃值: (16)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
7
2楼已经说得很清楚了
2010-1-27 20:50
0
雪    币: 2
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
win 32 会为每个进程分配独立的4空间。当进程的内存空间快耗尽,系统会结束此进程。
2010-1-28 07:27
0
雪    币: 56
活跃值: (276)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
靠点普
2010-1-31 21:27
0
游客
登录 | 注册 方可回帖
返回
//