;QQ:112426112
;Email:leguanyuan at 126 dot com
;Homepage:http://correy.webs.com
;Programming Applications for Microsoft Windows 第十四章程序例子代码的汇编实现。
;VirtualQueryEx函数的使用,我就不多说了。
;很早就想玩windows的内存管理,今天算是实现了,开始了第一步。
.386
.model flat,stdcall
option casemap:none

include windows.inc
include kernel32.inc
includelib kernel32.lib
include user32.inc
includelib user32.lib
include comctl32.inc 
includelib comctl32.lib 

.data
;db '只用于Windows 2000,用于指明处理的结构 %04x 字节',0dh,0ah;
szsi db "CPU的页面大小:%08x字节",0dh,0ah
     db '每个进程的可用地址空间的最小内存地址 %08x 字节',0dh,0ah
     db '每个进程的可用地址空间的最大内存地址 %08x 字节',0dh,0ah
     db '哪个C P U是活动的(允许运行线程) %lu 字节',0dh,0ah
     db 'CPU数目 %08x 字节',0dh,0ah
     db '只用于Windows 98,用于指明处理器的类型 %08x 字节',0dh,0ah
     db ' 保留的地址空间区域的分配粒度 %08x 字节',0dh,0ah       
     db '只用于Windows 2000,用于进一步细分处理器的结构 %04x 字节',0dh,0ah
     db '只用于Windows 2000,用于进一步细分处理器的级别 %04x 字节',0dh,0ah,0

szInfo db '物理内存总数 %08x 字节',0dh,0ah
       db '空闲物理内存 %08x 字节',0dh,0ah
       db '虚拟内存总数 %08x 字节',0dh,0ah
       db '空闲虚拟内存 %08x 字节',0dh,0ah
       db '已用内存比例 %d%%',0dh,0ah
       db '用户地址空间总数 %08x 字节',0dh,0ah
       db '用户可用地址空间 %08x 字节',0dh,0ah,0

szClassName db "correy",0
szCaptionMain db "made by correy",0
ListViewClass db 'SysListView32',0;ListBox
szstatic db "Static",0
pwndclassex dd 48,3,offset liuchunli,0,0,0,0,0,6,0,offset szClassName,0

BaseAddress db "BaseAddress",0
AllocationBase db "AllocationBase",0
AllocationProtect  db "AllocationProtect",0
RegionSize db "RegionSize",0
State db "State",0
Protect db "Protect",0
szType db "Type",0

szPAGE_EXECUTE db "PAGE_EXECUTE",0
szPAGE_EXECUTE_READ db "PAGE_EXECUTE_READ",0
szPAGE_EXECUTE_READWRITE db "PAGE_EXECUTE_READWRITE",0
szPAGE_EXECUTE_WRITECOPY db "PAGE_EXECUTE_WRITECOPY",0
szPAGE_NOACCESS db "PAGE_NOACCESS",0
szPAGE_READONLY db "PAGE_READONLY",0
szPAGE_READWRITE db "PAGE_READWRITE",0
szPAGE_WRITECOPY db "PAGE_WRITECOPY",0

szMEM_COMMIT db "MEM_COMMIT",0
szMEM_FREE db "MEM_FREE",0
szMEM_RESERVE db "MEM_RESERVE",0

szMEM_IMAGE db "MEM_IMAGE",0
szMEM_MAPPED db "MEM_MAPPED",0
szMEM_PRIVATE db "MEM_PRIVATE",0

notice db "说明:",13,10,\
       "1.以上全部是十六进制。",13,10,\
       "2.AllocationProtect列与Protect列和Type列可能有获取失败的,我把它的值给列出来了,",13,10,\
       "3.Protect列出现一个两个类型的和,应该用按位与操作,AllocationProtect列应该也是!",13,10,\
       "4.错误与不足之处,敬请不啬指教!",13,10,0       

.data?
mbi MEMORY_BASIC_INFORMATION <>
hInstance dd ?
hWinMain dd ?
stMsg MSG <>
hlist dd ?
hstatic dd ?
hdc dd ?
lvc LV_COLUMN <>
lvi LV_ITEM <>
bufferl db 8 dup (?),0 

szBuffer db 4096 dup (?)
lpsi SYSTEM_INFO <>
stMemInfo MEMORYSTATUS <>
x dd ?

.code

showeax proc;坚决拒绝使用wsprintf等类似函数。
pushad
mov ecx,8
xor esi,esi
againp:
dec ecx
rol eax,4
push eax
and eax,0Fh
cmp eax,9
jg big
add eax,30h
mov [bufferl+esi],al
pop eax
inc esi
cmp ecx,0
jne againp
je showp
big:
add eax,37h
mov [bufferl+esi],al
pop eax
inc esi
cmp ecx,0
jne againp
showp:
popad
ret
showeax endp

liuchunli proc uses ebx edi esi,hWnd,uMsg,wParam,lParam
.if uMsg == WM_CLOSE;放置后面会反应更快点。
  invoke DestroyWindow,hWinMain
  invoke PostQuitMessage,0
.elseif uMsg == WM_CREATE
  INVOKE CreateWindowEx,WS_EX_CLIENTEDGE,addr ListViewClass,0,WS_CHILD or WS_VISIBLE or LVS_REPORT or LVS_SHAREIMAGELISTS,\
         0,0,700,350,hWnd,0,hInstance,0
  mov hlist,eax

  mov lvc.imask,LVCF_TEXT+LVCF_WIDTH
  mov lvc.pszText,offset BaseAddress
  mov lvc.lx,75
  invoke SendMessage,hlist, LVM_INSERTCOLUMN, 0, addr lvc
    
  mov lvc.pszText,offset AllocationBase
  mov lvc.lx,85
  invoke SendMessage,hlist, LVM_INSERTCOLUMN,1,addr lvc

  mov lvc.pszText,offset AllocationProtect
  mov lvc.lx,155
  invoke SendMessage,hlist, LVM_INSERTCOLUMN, 2 ,addr lvc

  mov lvc.pszText,offset RegionSize
  mov lvc.lx,65
  invoke SendMessage,hlist,LVM_INSERTCOLUMN,3,addr lvc
  
  mov lvc.pszText,offset State
  mov lvc.lx,85
  invoke SendMessage,hlist,LVM_INSERTCOLUMN,4,addr lvc
  
  mov lvc.pszText,offset Protect
  mov lvc.lx,130
  invoke SendMessage,hlist,LVM_INSERTCOLUMN,5,addr lvc
  
  mov lvc.pszText,offset szType
  mov lvc.lx,85
  invoke SendMessage,hlist,LVM_INSERTCOLUMN,6,addr lvc
  
  invoke SendMessage,hlist,LVM_SETEXTENDEDLISTVIEWSTYLE,LVS_EX_FULLROWSELECT,LVS_EX_FULLROWSELECT
  mov lvi.iItem,0

  mov x,0;不能用ecx,esi等寄存器,因为,它每次都在变化。
  .while x<=07fffffffh;可以设置09fffffffh,但大于这个数,不能显示窗口。
    invoke VirtualQuery,x,addr mbi,sizeof mbi
    cmp eax,0
    je next
    
    mov eax,dword ptr mbi    
    call showeax
    lea eax,bufferl
    mov lvi.imask,LVIF_TEXT
    mov lvi.pszText,eax
    mov lvi.iSubItem,0
    invoke SendMessage,hlist,LVM_INSERTITEM,0,addr lvi
    
    mov eax,dword ptr mbi+4    
    call showeax
    lea eax,bufferl
    mov lvi.imask,LVIF_TEXT
    mov lvi.pszText,eax
    mov lvi.iSubItem,1
    invoke SendMessage,hlist,LVM_SETITEM,0,addr lvi
    
    mov eax,dword ptr mbi+8
    .if eax==10h
      lea eax,szPAGE_EXECUTE
      mov lvi.imask,LVIF_TEXT
      mov lvi.pszText,eax
      mov lvi.iSubItem,2
      invoke SendMessage,hlist,LVM_SETITEM,0,addr lvi
    .elseif eax== 20h
      lea eax,szPAGE_EXECUTE_READ
      mov lvi.imask,LVIF_TEXT
      mov lvi.pszText,eax
      mov lvi.iSubItem,2
      invoke SendMessage,hlist,LVM_SETITEM,0,addr lvi
    .elseif eax== 40h
      lea eax,szPAGE_EXECUTE_READWRITE
      mov lvi.imask,LVIF_TEXT
      mov lvi.pszText,eax
      mov lvi.iSubItem,2
      invoke SendMessage,hlist,LVM_SETITEM,0,addr lvi
    .elseif eax== 80h
      lea eax,szPAGE_EXECUTE_WRITECOPY
      mov lvi.imask,LVIF_TEXT
      mov lvi.pszText,eax
      mov lvi.iSubItem,2
      invoke SendMessage,hlist,LVM_SETITEM,0,addr lvi
    .elseif eax== 1
      lea eax,szPAGE_NOACCESS
      mov lvi.imask,LVIF_TEXT
      mov lvi.pszText,eax
      mov lvi.iSubItem,2
      invoke SendMessage,hlist,LVM_SETITEM,0,addr lvi
    .elseif eax== 2
      lea eax,szPAGE_READONLY
      mov lvi.imask,LVIF_TEXT
      mov lvi.pszText,eax
      mov lvi.iSubItem,2
      invoke SendMessage,hlist,LVM_SETITEM,0,addr lvi
    .elseif eax== 4
      lea eax,szPAGE_READWRITE
      mov lvi.imask,LVIF_TEXT
      mov lvi.pszText,eax
      mov lvi.iSubItem,2
      invoke SendMessage,hlist,LVM_SETITEM,0,addr lvi
    .elseif eax== 8
      lea eax,szPAGE_WRITECOPY
      mov lvi.imask,LVIF_TEXT
      mov lvi.pszText,eax
      mov lvi.iSubItem,2
      invoke SendMessage,hlist,LVM_SETITEM,0,addr lvi
    .else
      mov eax,dword ptr mbi+8   
      call showeax
      lea eax,bufferl
      mov lvi.imask,LVIF_TEXT
      mov lvi.pszText,eax
      mov lvi.iSubItem,2
      invoke SendMessage,hlist,LVM_SETITEM,0,addr lvi
    .endif    
    
    mov eax,dword ptr mbi+12   
    call showeax
    lea eax,bufferl
    mov lvi.imask,LVIF_TEXT
    mov lvi.pszText,eax
    mov lvi.iSubItem,3
    invoke SendMessage,hlist,LVM_SETITEM,0,addr lvi
    
    mov eax,dword ptr mbi+16 
    .if eax==1000h
      lea eax,szMEM_COMMIT
      mov lvi.imask,LVIF_TEXT
      mov lvi.pszText,eax
      mov lvi.iSubItem,4
      invoke SendMessage,hlist,LVM_SETITEM,0,addr lvi
    .elseif eax==10000h
      lea eax,szMEM_FREE
      mov lvi.imask,LVIF_TEXT
      mov lvi.pszText,eax
      mov lvi.iSubItem,4
      invoke SendMessage,hlist,LVM_SETITEM,0,addr lvi
    .elseif eax==2000h
      lea eax,szMEM_RESERVE
      mov lvi.imask,LVIF_TEXT
      mov lvi.pszText,eax
      mov lvi.iSubItem,4
      invoke SendMessage,hlist,LVM_SETITEM,0,addr lvi
    .endif 
    
    mov eax,dword ptr mbi+20 
    .if eax==10h
      lea eax,szPAGE_EXECUTE
      mov lvi.imask,LVIF_TEXT
      mov lvi.pszText,eax
      mov lvi.iSubItem,5
      invoke SendMessage,hlist,LVM_SETITEM,0,addr lvi
    .elseif eax== 20h
      lea eax,szPAGE_EXECUTE_READ
      mov lvi.imask,LVIF_TEXT
      mov lvi.pszText,eax
      mov lvi.iSubItem,5
      invoke SendMessage,hlist,LVM_SETITEM,0,addr lvi
    .elseif eax== 40h
      lea eax,szPAGE_EXECUTE_READWRITE
      mov lvi.imask,LVIF_TEXT
      mov lvi.pszText,eax
      mov lvi.iSubItem,5
      invoke SendMessage,hlist,LVM_SETITEM,0,addr lvi
    .elseif eax== 80h
      lea eax,szPAGE_EXECUTE_WRITECOPY
      mov lvi.imask,LVIF_TEXT
      mov lvi.pszText,eax
      mov lvi.iSubItem,5
      invoke SendMessage,hlist,LVM_SETITEM,0,addr lvi
    .elseif eax== 1
      lea eax,szPAGE_NOACCESS
      mov lvi.imask,LVIF_TEXT
      mov lvi.pszText,eax
      mov lvi.iSubItem,5
      invoke SendMessage,hlist,LVM_SETITEM,0,addr lvi
    .elseif eax== 2
      lea eax,szPAGE_READONLY
      mov lvi.imask,LVIF_TEXT
      mov lvi.pszText,eax
      mov lvi.iSubItem,5
      invoke SendMessage,hlist,LVM_SETITEM,0,addr lvi
    .elseif eax== 4
      lea eax,szPAGE_READWRITE
      mov lvi.imask,LVIF_TEXT
      mov lvi.pszText,eax
      mov lvi.iSubItem,5
      invoke SendMessage,hlist,LVM_SETITEM,0,addr lvi
    .elseif eax== 8
      lea eax,szPAGE_WRITECOPY
      mov lvi.imask,LVIF_TEXT
      mov lvi.pszText,eax
      mov lvi.iSubItem,5
      invoke SendMessage,hlist,LVM_SETITEM,0,addr lvi
    .else
      mov eax,dword ptr mbi+20   
      call showeax
      lea eax,bufferl
      mov lvi.imask,LVIF_TEXT
      mov lvi.pszText,eax
      mov lvi.iSubItem,5
      invoke SendMessage,hlist,LVM_SETITEM,0,addr lvi
    .endif    
   
    mov eax,dword ptr mbi+24
    .if eax==1000000h
      lea eax,szMEM_IMAGE
      mov lvi.imask,LVIF_TEXT
      mov lvi.pszText,eax
      mov lvi.iSubItem,6
      invoke SendMessage,hlist,LVM_SETITEM,0,addr lvi 
    .elseif eax==40000h
      lea eax,szMEM_MAPPED
      mov lvi.imask,LVIF_TEXT
      mov lvi.pszText,eax
      mov lvi.iSubItem,6
      invoke SendMessage,hlist,LVM_SETITEM,0,addr lvi
    .elseif eax==20000h
      lea eax,szMEM_PRIVATE
      mov lvi.imask,LVIF_TEXT
      mov lvi.pszText,eax
      mov lvi.iSubItem,6
      invoke SendMessage,hlist,LVM_SETITEM,0,addr lvi
    .else
      ;mov eax,dword ptr [mbi.lType];Type 
      mov eax,dword ptr mbi+24  
      ;mov eax,[eax+24]
      call showeax
      lea eax,bufferl
      mov lvi.imask,LVIF_TEXT
      mov lvi.pszText,eax
      mov lvi.iSubItem,6
      invoke SendMessage,hlist,LVM_SETITEM,0,addr lvi 
    .endif
    
    mov eax,mbi.RegionSize 
    add eax,x
    mov x,eax
  .endw  
  
  next:
  INVOKE CreateWindowEx,WS_EX_CLIENTEDGE,addr szstatic,0,WS_CHILD or WS_VISIBLE or SS_LEFT or WS_GROUP,0,350,700,150,hWnd,0,hInstance,0
  MOV hstatic,EAX
  invoke SendMessage,eax,WM_SETTEXT,0,addr notice
  
.else
  invoke DefWindowProc,hWnd,uMsg,wParam,lParam
  ret;不能去掉。
.endif
xor eax,eax;这两行可以去掉?
ret
liuchunli endp

start:
      
invoke GetSystemInfo,addr lpsi
invoke wsprintf,addr szBuffer,addr szsi,\
       ;lpsi.wProcessorArchitecture,\;
       lpsi.dwPageSize,\
       lpsi.lpMinimumApplicationAddress,\
       lpsi.lpMaximumApplicationAddress,\
       lpsi.dwActiveProcessorMask,\
       lpsi.dwNumberOfProcessors ,\
       lpsi.dwProcessorType,\
       lpsi.dwAllocationGranularity,\
       lpsi.wProcessorLevel,\
       lpsi.wProcessorRevision
invoke MessageBox,0,addr szBuffer,addr szCaptionMain,0

mov    stMemInfo.dwLength,sizeof stMemInfo
invoke GlobalMemoryStatus,addr stMemInfo
invoke wsprintf,addr szBuffer,addr szInfo,\
       stMemInfo.dwTotalPhys,\
       stMemInfo.dwAvailPhys,\
       stMemInfo.dwTotalPageFile,\
       stMemInfo.dwAvailPageFile,\
       stMemInfo.dwMemoryLoad,\
       stMemInfo.dwTotalVirtual,\
       stMemInfo.dwAvailVirtual
invoke MessageBox,0,addr szBuffer,addr szCaptionMain,0

invoke InitCommonControls;少加这个按钮,SysListView32控件是建立不起来的。
invoke GetModuleHandle,0
mov hInstance,eax
mov pwndclassex+20,eax

invoke LoadIcon,hInstance,1;加载图标,在资源文件中定义。
mov pwndclassex+24,eax

invoke LoadCursor,0,32512;加载箭头鼠标。
mov pwndclassex+28,eax

invoke RegisterClassEx,addr pwndclassex
invoke CreateWindowEx,200h,offset szClassName,offset szCaptionMain,0Ca0000h,80000000h,80000000h,710,530,0,0,hInstance,0
;0Cf0000h,80000000h,80000000h,99h,99h,0,0,hInstance,0
mov hWinMain,eax

invoke ShowWindow,hWinMain,1;若不想显示,此行也可以去掉。
invoke UpdateWindow,hWinMain

again:invoke GetMessage,addr stMsg,0,0,0
  cmp eax,0
  je exit
  invoke TranslateMessage,addr stMsg;若不想处理字符信息,此行也可以去掉。此行主要是方便处理字符信息的,个人认为。
  invoke DispatchMessage,addr stMsg
jmp again

exit:invoke ExitProcess,0
end start
;made at 2011.03.02

上传的附件 3.rar