Global variables bloat the code:
mov hMain, 123 ; 10 bytes
mov [ebx+4], 123 ; 7 bytes
So I wrote a macro that defines them relative to ebx. Usage is very simple, just declare them in the .data? section as if they were LOCALs:
SetGlobals hMain:HWND, hButton1:HWND, hButton2:HWND, hStatic:HWND, hEdit:HWND
SetGlobals hButFnt:HWND, hAccels:HWND, msgCount, opSubClass
SetGlobals rc:RECT, msg:MSG, wc:WNDCLASSEX, gBuffer[1024]:BYTE
....
.code
start: SetGlobals ; no args makes ebx point to the variables defined above
...
WndProc proc uses ebx esi hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
SetGlobals ; do not use ebx below, unless pushed & popped
SWITCH uMsg
...
mov hMain, eax ; use like a normal global variable, but 3 bytes shorter
This technique is useful when you often use global variables. It also opens the option to use the same set of variables in multi-thread applications (i.e. just copy the first global set to a second location for thead #2 and let ebx point to it).
The "short" range is [ebx-128] to [ebx+127], i.e. 64 DWORD variables; if you need a fat general purpose buffer, put it at the end, so that its start address will be inside the range.
I attach a full example similar to \masm32\examples\exampl01\generic\generic.asm
The next release of MasmBasic will contain the SetGlobals and Enum macros, too. The attached source does not use MasmBasic, though, just plain Masm32.