News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

Build and run issues of some masm32 examples under wine

Started by juozas, July 06, 2017, 09:37:01 PM

Previous topic - Next topic

juozas


  • 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
Intel Pentium Dual-Core E6300 @ 2.80 GHz / Asus P5G41-M LE (2 GB Ram) / NVIDIA GeForce 210
Ubuntu Linux 22.04 LTS with Wine 7.22
Windows XP on Virtual machine

Сделано в СССР

jj2007

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 ;)

juozas

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
Intel Pentium Dual-Core E6300 @ 2.80 GHz / Asus P5G41-M LE (2 GB Ram) / NVIDIA GeForce 210
Ubuntu Linux 22.04 LTS with Wine 7.22
Windows XP on Virtual machine

Сделано в СССР

jj2007

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.

juozas

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.
Intel Pentium Dual-Core E6300 @ 2.80 GHz / Asus P5G41-M LE (2 GB Ram) / NVIDIA GeForce 210
Ubuntu Linux 22.04 LTS with Wine 7.22
Windows XP on Virtual machine

Сделано в СССР

jj2007

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)

mineiro

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.
I'd rather be this ambulant metamorphosis than to have that old opinion about everything

juozas

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)
Intel Pentium Dual-Core E6300 @ 2.80 GHz / Asus P5G41-M LE (2 GB Ram) / NVIDIA GeForce 210
Ubuntu Linux 22.04 LTS with Wine 7.22
Windows XP on Virtual machine

Сделано в СССР