- C:\masm32\examples\Bill_Cravener\memfree\MemFree.asm fails to build with multiple errors like
error A2163: non-benign structure redefinition: incorrect initializers : MEMORYSTATUSEX
- C:\masm32\examples\enumerate\enumdd\enumdd.exe crash after rebuild:
Unhandled exception: page fault on read access to 0x00222000 in 32-bit code (0x0040139d).
Register dump:
CS:0023 SS:002b DS:002b ES:002b FS:0063 GS:006b
EIP:0040139d ESP:0033f358 EBP:0033f5b8 EFLAGS:00010282( R- -- I S - - - )
EAX:000380d5 EBX:7ea0d000 ECX:0033f350 EDX:00000000
ESI:00222000 EDI:fffc7f2a
Stack dump:
0x0033f358: 0033f3a8 00000200 00030aac 0033f8e4
0x0033f368: 00330000 7e9cccae 00030a9a 00000030
0x0033f378: 00010030 00000001 00000000 7bc3e1d6
0x0033f388: 0033f3b0 0000053e 00050a9c 0033f3b0
0x0033f398: 0033f3d8 7e9ccaea 00030a9a 7ea0d000
0x0033f3a8: 00330000 7e9ccaea 00030a9a 00000030
Backtrace:
=>0 0x0040139d in enumdd (+0x139d) (0x0033f5b8)
1 0x00401263 in enumdd (+0x1262) (0x0033f7e8)
2 0x7e9ccaea WINPROC_wrapper+0x19() in user32 (0x0033f818)
3 0x7e9cd15a in user32 (+0x9d159) (0x0033f868)
4 0x7e9cf5f5 in user32 (+0x9f5f4) (0x0033f8b8)
5 0x7e991eae in user32 (+0x61ead) (0x0033f928)
6 0x7e998c84 in user32 (+0x68c83) (0x0033f988)
7 0x7e99b032 SendMessageA+0x61() in user32 (0x0033f9d8)
8 0x7e9c4730 in user32 (+0x9472f) (0x0033fb78)
9 0x7e9bd6a1 CreateWindowExA+0x120() in user32 (0x0033fde8)
10 0x0040114c in enumdd (+0x114b) (0x0033fe3c)
11 0x004010b3 in enumdd (+0x10b2) (0x0033fe58)
12 0x7b4615a4 ExitProcess+0xfe3() in kernel32 (0x0033fe98)
13 0x7bc80e7c call_thread_func_wrapper+0xb() in ntdll (0x0033feb8)
14 0x7bc83e2f call_thread_func+0xce() in ntdll (0x0033ffa8)
15 0x7bc80e5a RtlRaiseException+0x21() in ntdll (0x0033ffc8)
16 0x7bc53153 call_dll_entry_point+0x3d2() in ntdll (0x0033ffe8)
17 0xf74fdb5d wine_call_on_stack+0x1c() in libwine.so.1 (0x00000000)
18 0xf74fdcc0 wine_switch_to_stack+0x1f() in libwine.so.1 (0xfffbdea8)
19 0x7bc59052 LdrInitializeThunk+0x251() in ntdll (0xfffbdef8)
20 0x7b467780 __wine_kernel_init+0xa5f() in kernel32 (0xfffbf068)
21 0x7bc59f33 __wine_process_init+0x152() in ntdll (0xfffbf0d8)
22 0xf74fbd97 wine_init+0x2c6() in libwine.so.1 (0xfffbf138)
23 0x7c000a42 main+0x81() in <wine-loader> (0xfffbf588)
24 0xf7336276 __libc_start_main+0xf5() in libc.so.6 (0x00000000)
0x0040139d: pushl 0x0(%esi)
Modules:
Module Address Debug info Name (54 modules)
PE 400000- 404000 Export enumdd
ELF 7b400000-7b7e0000 Dwarf kernel32<elf>
\-PE 7b410000-7b7e0000 \ kernel32
ELF 7bc00000-7bcf6000 Dwarf ntdll<elf>
\-PE 7bc10000-7bcf6000 \ ntdll
ELF 7c000000-7c004000 Dwarf <wine-loader>
ELF 7e30a000-7e341000 Deferred uxtheme<elf>
\-PE 7e310000-7e341000 \ uxtheme
ELF 7e341000-7e348000 Deferred libxfixes.so.3
ELF 7e348000-7e353000 Deferred libxcursor.so.1
ELF 7e353000-7e366000 Deferred libxi.so.6
ELF 7e366000-7e36a000 Deferred libxcomposite.so.1
ELF 7e36a000-7e377000 Deferred libxrandr.so.2
ELF 7e377000-7e383000 Deferred libxrender.so.1
ELF 7e383000-7e38a000 Deferred libxxf86vm.so.1
ELF 7e38a000-7e38e000 Deferred libxinerama.so.1
ELF 7e38e000-7e395000 Deferred libxdmcp.so.6
ELF 7e395000-7e399000 Deferred libxau.so.6
ELF 7e399000-7e3bf000 Deferred libxcb.so.1
ELF 7e3bf000-7e50a000 Deferred libx11.so.6
ELF 7e50a000-7e51f000 Deferred libxext.so.6
ELF 7e53f000-7e5cc000 Deferred winex11<elf>
\-PE 7e550000-7e5cc000 \ winex11
ELF 7e5cc000-7e5f0000 Deferred imm32<elf>
\-PE 7e5d0000-7e5f0000 \ imm32
ELF 7e676000-7e6a0000 Deferred libexpat.so.1
ELF 7e6a0000-7e6e9000 Deferred libfontconfig.so.1
ELF 7e6e9000-7e723000 Deferred libpng16.so.16
ELF 7e723000-7e740000 Deferred libz.so.1
ELF 7e740000-7e7f3000 Deferred libfreetype.so.6
ELF 7e813000-7e827000 Deferred psapi<elf>
\-PE 7e820000-7e827000 \ psapi
ELF 7e827000-7e922000 Deferred comctl32<elf>
\-PE 7e830000-7e922000 \ comctl32
ELF 7e922000-7ea77000 Dwarf user32<elf>
\-PE 7e930000-7ea77000 \ user32
ELF 7ea77000-7eaee000 Deferred advapi32<elf>
\-PE 7ea80000-7eaee000 \ advapi32
ELF 7eaee000-7ec1d000 Deferred gdi32<elf>
\-PE 7eb00000-7ec1d000 \ gdi32
ELF 7ec1d000-7ec30000 Deferred libnss_files.so.2
ELF 7ec30000-7ec3d000 Deferred libnss_nis.so.2
ELF 7ec3d000-7ec58000 Deferred libnsl.so.1
ELF 7ef8a000-7efe0000 Deferred libm.so.6
ELF 7efe6000-7f000000 Deferred version<elf>
\-PE 7eff0000-7f000000 \ version
ELF f7319000-f731e000 Deferred libdl.so.2
ELF f731e000-f74d8000 Dwarf libc.so.6
ELF f74d8000-f74f5000 Deferred libpthread.so.0
ELF f74f5000-f76ac000 Dwarf libwine.so.1
ELF f76ac000-f76b5000 Deferred libgtk3-nocsd.so.0
ELF f76b6000-f76c0000 Deferred libnss_compat.so.2
ELF f76d8000-f76fd000 Deferred ld-linux.so.2
ELF f76ff000-f7700000 Deferred [vdso].so
Threads:
process tid prio (all id:s are in hex)
00000008 explorer.exe
0000002a 0
00000029 0
00000009 0
0000000e services.exe
00000020 0
0000001f 0
00000014 0
00000010 0
0000000f 0
00000012 winedevice.exe
0000001e 0
00000019 0
00000018 0
00000013 0
0000001c plugplay.exe
00000022 0
00000021 0
0000001d 0
00000023 explorer.exe
00000028 0
00000027 0
00000026 0
00000025 0
00000024 0
000000d4 (D) C:\masm32\examples\enumerate\enumdd\enumdd.exe
000000d5 0 <==
System information:
Wine build: wine-2.0.1
Platform: i386
Version: Windows XP
Host system: Linux
Host version: 4.10.0-26-generic
- testing is in progress, more might be added
It will work if you either:
- replace the 4 occurrences with MEMSTATEX (or any other name).
- or comment out Bill's structure, and correct the access to some elements with dword ptr ...
Here is the original definition:MEMORYSTATUSEX STRUCT
dwLength DWORD ?
dwMemoryLoad DWORD ?
ullTotalPhys QWORD ?
ullAvailPhys QWORD ?
ullTotalPageFile QWORD ?
ullAvailPageFile QWORD ?
ullTotalVirtual QWORD ?
ullAvailVirtual QWORD ?
ullAvailExtendedVirtual QWORD ?
MEMORYSTATUSEX ENDS
Attached a version with a switch: useBill=0 ;)
Option 1 (renaming struct) works ok
Option 2 breaks with more errors: MemFree.asm(223) : error A2006: undefined symbol : lowDWORD
MemFree.asm(224) : error A2006: undefined symbol : highDWORD
Old and new comparison (generated by diff): 29,39c29,39
< MEMORYSTATUSEX STRUCT
< dwLength DWORD ?
< dwMemoryLoad DWORD ?
< ullTotalPhys QWORD ?
< ullAvailPhys QWORD ?
< ullTotalPageFile QWORD ?
< ullAvailPageFile QWORD ?
< ullTotalVirtual QWORD ?
< ullAvailVirtual QWORD ?
< ullAvailExtendedVirtual QWORD ?
< MEMORYSTATUSEX ENDS
---
> MEMORYSTATUSEX STRUCT
> dwLength DWORD ?
> dwMemoryLoad DWORD ?
> ullTotalPhys DWORDDWORD <>
> ullAvailPhys DWORDDWORD <>
> ullTotalPageFile DWORDDWORD <>
> ullAvailPageFile DWORDDWORD <>
> ullTotalVirtual DWORDDWORD <>
> ullAvailVirtual DWORDDWORD <>
> ullAvailExtendedVirtual DWORDDWORD <>
> MEMORYSTATUSEX ENDS
QWORD ? does not work, DWORDDWORD <> works
Quote from: juozas on July 06, 2017, 10:20:56 PM
Option 2 breaks with more errors:
This is what I meant with "correct the access to some elements with dword ptr". See attachment above.
The attached example works, also it has DWORDDWORD <> instead of QWORD ?, if I change to QWORD, an example wouldn't compile.
P.s. masm32 is installed on 32bit wine prefix.
You can use a QWORD with a few changes:
MEMSTATEXBILL STRUCT
dwLength DWORD ?
dwMemoryLoad DWORD ?
ullTotalPhys QWORD ? ; <<<<<<<<<<<<<<<<<<<<<<<<
ullAvailPhys DWORDDWORD <>
...
mov eax,dword ptr memStatusEx.ullTotalPhys
mov edx,dword ptr memStatusEx.ullTotalPhys[4]
Just check what happens for useBill=0 8)
hello juozas;
remember that wine is not 100% windows compatible, not all windows functions are implemented, I think that 'fixme' messages have something related to this.
I rewrite that code, command line used on end of source code:
.486 ; create 32 bit code
.model flat, stdcall ; 32 bit memory model
option casemap :none ; case sensitive
; €€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€
; include files
; ~~~~~~~~~~~~~
include \masm32\include\windows.inc
include \masm32\include\masm32.inc
include \masm32\include\gdi32.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\Comctl32.inc
include \masm32\include\comdlg32.inc
include \masm32\include\shell32.inc
include \masm32\include\oleaut32.inc
include \masm32\include\psapi.inc
include \masm32\include\msvcrt.inc
include \masm32\macros\macros.asm
; libraries
; ~~~~~~~~~
includelib \masm32\lib\masm32.lib
includelib \masm32\lib\gdi32.lib
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\Comctl32.lib
includelib \masm32\lib\comdlg32.lib
includelib \masm32\lib\shell32.lib
includelib \masm32\lib\oleaut32.lib
includelib \masm32\lib\psapi.lib
includelib \masm32\lib\msvcrt.lib
.code
start:
enumproc proc
LOCAL parr :DWORD
LOCAL breq :DWORD
LOCAL pbuf :DWORD
LOCAL ptxt :DWORD
LOCAL buffer[512]:BYTE
LOCAL txt[64]:BYTE
push esi
push edi
mov pbuf, ptr$(buffer)
mov ptxt, ptr$(txt)
invoke EnumDeviceDrivers,NULL,NULL,ADDR breq ; get array size in bytes
;EnumDeviceDrivers returns TRUE but don't fill breq
;dump edx
;fixme:file:K32EnumDeviceDrivers((nil), 0, 0x33fe58): stub.
.if [breq] != 0
mov parr, alloc(breq) ; allocate required memory
invoke EnumDeviceDrivers,parr,breq,ADDR breq ; enumerate device drivers
shr breq, 2 ; divide result by 4 for driver count
mov esi, parr ; array address in ESI
mov edi, breq ; driver count in EDI
@@:
invoke GetDeviceDriverFileName,[esi],pbuf,512
add esi, 4
sub edi, 1
jnz @B
free parr ; deallocate memory
.endif
pop edi
pop esi
ret
enumproc endp
end start
;:~/.wine/drive_c/Masm32/examples/enumdd$ wine cmd.exe
;C:\Masm32\examples\enumdd>PATH=%PATH%;C:\Masm32\bin;C:\Masm32\include;C:\Masm32\lib
;C:\Masm32\examples\enumdd>ml /c /coff teste.asm
;C:\Masm32\examples\enumdd>link /subsystem:console teste.obj
;fixme:heap:HeapSetInformation 0x240000 0 0x23fd30 4
;C:\Masm32\examples\enumdd>teste
;fixme:file:K32EnumDeviceDrivers ((nil), 0, 0x33fe58): stub
I have read that we are able to insert on wine real windows .dll files, but I do not have tried that. We can change windows version being used too, again, I do not tried that.
Regarding memfree example, I worked out so far to make sure that there's a code that compiles ok on wine. It doesn't much differ from the original.
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; GlobalMemoryStatusEx Example - Author: William F Cravener 01 . 17 . 09
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.486 ; create 32 bit code
.model flat,stdcall ; 32 bit memory model
option casemap :none ; case sensitive
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include \masm32\include\windows.inc
include \masm32\include\gdi32.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\masm32.inc
includelib \masm32\lib\gdi32.lib
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\masm32.lib
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
DWORDDWORD STRUCT
lowDWORD DWORD ?
highDWORD DWORD ?
DWORDDWORD ENDS
MEMORYSTATEX STRUCT ; struct renamed, to make it more compatible with wine
dwLength DWORD ?
dwMemoryLoad DWORD ?
ullTotalPhys QWORD ? ; changed DWORDDWORD <> to QWORD ?
ullAvailPhys QWORD ?
ullTotalPageFile QWORD ?
ullAvailPageFile QWORD ?
ullTotalVirtual QWORD ?
ullAvailVirtual QWORD ?
ullAvailExtendedVirtual QWORD ?
MEMORYSTATEX ENDS
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
WinMain PROTO :DWORD,:DWORD,:DWORD,:DWORD
WndProc PROTO :DWORD,:DWORD,:DWORD,:DWORD
TopXY PROTO :DWORD,:DWORD
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.data
hInstance dd 0
hWnd dd 0
szClassName db "MemFree",0
szDisplayName db "MemFree",0
MemString1 db "Total physical memory: ",0
PhysicalMem1 db 10 dup(0)
MemString2 db " Free physical memory: ",0
PhysicalMem2 db 10 dup(0)
MemString3 db " Total page file size: ",0
PagingMem3 db 10 dup(0)
MemString4 db " Free page file size: ",0
PagingMem4 db 10 dup(0)
MemString5 db " Total virtual memory: ",0
VirtualMem5 db 10 dup(0)
MemString6 db " Free virtual memory: ",0
VirtualMem6 db 10 dup(0)
MemString7 db "Free extended virtual: ",0
VirtualMem7 db 10 dup(0)
paintstruct PAINTSTRUCT <>
memStatusEx MEMORYSTATEX <> ; references updated to renamed function here
lgfnt LOGFONT <14,0,0,0,0,0,0,0,0,0,0,0,0,"Lucida Console">
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.code
start:
invoke FindWindow,ADDR szClassName,0
cmp eax,0
je @F
mov eax,0
ret
@@:
invoke GetModuleHandle,0
mov hInstance,eax
invoke WinMain,hInstance,0,0,0
invoke ExitProcess,eax
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
WinMain proc hInst:DWORD,hPrevInst:DWORD,CmdLine:DWORD,CmdShow:DWORD
LOCAL wc:WNDCLASSEX
LOCAL msg:MSG
LOCAL Wwd:DWORD
LOCAL Wht:DWORD
LOCAL Wtx:DWORD
LOCAL Wty:DWORD
mov wc.cbSize,sizeof WNDCLASSEX
mov wc.style,CS_HREDRAW or CS_VREDRAW or CS_BYTEALIGNWINDOW
mov wc.lpfnWndProc,OFFSET WndProc
mov wc.cbClsExtra,0
mov wc.cbWndExtra,0
mov eax,hInst
mov wc.hInstance,eax
mov wc.hbrBackground,COLOR_WINDOW+1
mov wc.lpszMenuName,0
mov wc.lpszClassName,OFFSET szClassName
invoke LoadIcon,hInstance,500
mov wc.hIcon,eax
invoke LoadCursor,0,IDC_ARROW
mov wc.hCursor,eax
invoke LoadIcon,hInstance,500
mov wc.hIconSm,eax
invoke RegisterClassEx,ADDR wc
mov Wwd,320
mov Wht,220
invoke GetSystemMetrics,SM_CXSCREEN ; get screen width in pixels
invoke TopXY,Wwd,eax
mov Wtx,eax
invoke GetSystemMetrics,SM_CYSCREEN ; get screen height in pixels
invoke TopXY,Wht,eax
mov Wty,eax
invoke CreateWindowEx,WS_EX_OVERLAPPEDWINDOW,
ADDR szClassName,
ADDR szDisplayName,
WS_OVERLAPPEDWINDOW,
Wtx,Wty,Wwd,Wht,
NULL,NULL,
hInstance,NULL
mov hWnd,eax
invoke ShowWindow,hWnd,SW_SHOWNORMAL
invoke UpdateWindow,hWnd
StartLoop:
invoke GetMessage,ADDR msg,0,0,0
cmp eax,0
je ExitLoop
invoke TranslateMessage,ADDR msg
invoke DispatchMessage,ADDR msg
jmp StartLoop
ExitLoop:
mov eax,msg.wParam
ret
WinMain endp
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
WndProc proc hWin:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD
LOCAL hDC:DWORD
LOCAL hFont:DWORD
.if uMsg == WM_CREATE
call ShowRAMFreeProc
.elseif uMsg == WM_PAINT
invoke BeginPaint,hWin,ADDR paintstruct
mov hDC,eax
invoke CreateFontIndirect,ADDR lgfnt
mov hFont,eax
invoke SelectObject,hDC,hFont
invoke TextOut,hDC,20,20,ADDR MemString1,24
invoke lstrlen,ADDR PhysicalMem1
invoke TextOut,hDC,200,20,ADDR PhysicalMem1,eax
invoke TextOut,hDC,20,40,ADDR MemString2,24
invoke lstrlen,ADDR PhysicalMem2
invoke TextOut,hDC,200,40,ADDR PhysicalMem2,eax
invoke TextOut,hDC,20,60,ADDR MemString3,24
invoke lstrlen,ADDR PagingMem3
invoke TextOut,hDC,200,60,ADDR PagingMem3,eax
invoke TextOut,hDC,20,80,ADDR MemString4,24
invoke lstrlen,ADDR PagingMem4
invoke TextOut,hDC,200,80,ADDR PagingMem4,eax
invoke TextOut,hDC,20,100,ADDR MemString5,24
invoke lstrlen,ADDR VirtualMem5
invoke TextOut,hDC,200,100,ADDR VirtualMem5,eax
invoke TextOut,hDC,20,120,ADDR MemString6,24
invoke lstrlen,ADDR VirtualMem6
invoke TextOut,hDC,200,120,ADDR VirtualMem6,eax
invoke TextOut,hDC,20,140,ADDR MemString7,24
invoke lstrlen,ADDR VirtualMem7
invoke TextOut,hDC,200,140,ADDR VirtualMem7,eax
invoke DeleteObject,hFont
invoke EndPaint,hWin,ADDR paintstruct
.elseif uMsg == WM_DESTROY
invoke PostQuitMessage,0
.else
invoke DefWindowProc,hWin,uMsg,wParam,lParam
ret
.endif
xor eax,eax
ret
WndProc endp
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ShowRAMFreeProc proc
push eax
push ecx
push edx
push edi
push esi
mov memStatusEx.dwLength,sizeof MEMORYSTATEX ; references fixed here
invoke GlobalMemoryStatusEx,ADDR memStatusEx
mov eax,dword ptr memStatusEx.ullTotalPhys ; using .lowDWORD or .highDWORD does not compile under wine
mov edx,dword ptr memStatusEx.ullTotalPhys[4] ; instead using different notation, like in posts above recommended (works on both "useBill" cases)
mov ecx,1024
div ecx
mov esi,eax
mov edi,OFFSET PhysicalMem1
invoke dwtoa,esi,edi
mov eax,dword ptr memStatusEx.ullAvailPhys
mov edx,dword ptr memStatusEx.ullAvailPhys[4] ; like above
mov ecx,1024
div ecx
mov esi,eax
mov edi,OFFSET PhysicalMem2
invoke dwtoa,esi,edi
mov eax,dword ptr memStatusEx.ullTotalPageFile
mov edx,dword ptr memStatusEx.ullTotalPageFile[4] ; like above
mov ecx,1024
div ecx
mov esi,eax
mov edi,OFFSET PagingMem3
invoke dwtoa,esi,edi
mov eax,dword ptr memStatusEx.ullAvailPageFile
mov edx,dword ptr memStatusEx.ullAvailPageFile[4] ; like above
mov ecx,1024
div ecx
mov esi,eax
mov edi,OFFSET PagingMem4
invoke dwtoa,esi,edi
mov eax,dword ptr memStatusEx.ullTotalVirtual
mov edx,dword ptr memStatusEx.ullTotalVirtual[4] ; like above
mov ecx,1024
div ecx
mov esi,eax
mov edi,OFFSET VirtualMem5
invoke dwtoa,esi,edi
mov eax,dword ptr memStatusEx.ullAvailVirtual
mov edx,dword ptr memStatusEx.ullAvailVirtual[4] ; like above
mov ecx,1024
div ecx
mov esi,eax
mov edi,OFFSET VirtualMem6
invoke dwtoa,esi,edi
mov eax,dword ptr memStatusEx.ullAvailExtendedVirtual
mov edx,dword ptr memStatusEx.ullAvailExtendedVirtual[4] ; like above
mov ecx,1024
div ecx
mov esi,eax
mov edi,OFFSET VirtualMem7
invoke dwtoa,esi,edi
pop esi
pop edi
pop edx
pop ecx
pop eax
ret
ShowRAMFreeProc endp
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
TopXY proc wDim:DWORD, sDim:DWORD
shr sDim,1
shr wDim,1
mov eax,wDim
sub sDim,eax
mov eax,sDim
ret
TopXY endp
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
end start
;compiled using bat file in attached archive or manually (executables not included)
Also one with a slight modification (useBill=0, etc) works too, as the
mov eax,dword ptr memStatusEx.ullTotalPhys
mov edx,dword ptr memStatusEx.ullTotalPhys[4]
;etc
form factor works fine whether useBill is 1 or 0.
Full source code, comparison text files (generated by diff util) and old original file (w/o precompiled exe's, bat files to build them not removed) attatched.
@mineiro, I'll check our your code later. can reproduce it too (I get exactly same)