The MASM Forum

General => The Workshop => Topic started by: jj2007 on July 23, 2012, 07:40:27 AM

Title: Short global variables
Post by: jj2007 on July 23, 2012, 07:40:27 AM
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.
Title: Re: Short global variables
Post by: dedndave on July 23, 2012, 09:15:53 AM
good thinking   :t

i try to use a register to address larger structures, like WNDCLASSEX
also - i often put many of my globals into structures
it helps keep them organized and you can address them with a register
true that you don't need a structure to do this - but it makes the code cleaner

here are a few examples from my map viewer...
ControlHandles STRUCT
  hStatusBar     HWND ?
  hRightBox      HWND ?
  hVScrollBar    HWND ?
  hHScrollBar    HWND ?
  hLeftBox       HWND ?
  hTrackBar      HWND ?
  hImageWin      HWND ?
ControlHandles ENDS

CoordInfo   STRUCT
  s           SCROLLINFO <>
;   cbSize      dd ? ;sizeof SCROLLINFO
;   fMask       dd ? ;SIF_RANGE or SIF_PAGE or SIF_POS
;   nMin        dd ? ;0
;   nMax        dd ? ;(zoomed image dimension - 1) + ((image window dimension - 1) and -2)
;   nPage       dd ? ;image window dimension
;   nPos        dd ? ;top or left image window coordinate
;   nTrackPos   dd ? ;thumb track position
  uImgWinCent dd ?   ;image window center (unzoomed image coord) for "Center" display
  uCursorLoc  dd ?   ;cursor location for "Current" display
  uUnzoomSize dd ?   ;unzoomed image dimension
  uZoomedSize dd ?   ;zoomed image dimension
  nGrabOffset dd ?   ;(cursor position - scroll position) when grabbed
  nOriginDest dd ?   ;destination coordinate for StretchBlt
  nSizeDest   dd ?   ;destination dimension for StretchBlt
  nOriginSrc  dd ?   ;source coordinate for StretchBlt
  nSizeSrc    dd ?   ;source dimension for StretchBlt
  uScBarSize  dd ?   ;scrollbar dimension
  lpStatusBar dd ?   ;status bar info pointer
  uScreenSize dd ?   ;screen dimension
  uFrameSize  dd ?   ;frame dimension
CoordInfo   ENDS

CoordinateGroup STRUCT
  h               CoordInfo <>
  v               CoordInfo <>
CoordinateGroup ENDS
Title: Re: Short global variables
Post by: hutch-- on July 23, 2012, 09:31:18 AM
 :biggrin:

In applications where a single bitmap can be over 100k, you worried about 3 bytes in a MOV instruction ? Come on.  :P
Title: Re: Short global variables
Post by: jj2007 on July 23, 2012, 03:41:16 PM
Quote from: hutch-- on July 23, 2012, 09:31:18 AM
In applications where a single bitmap can be over 100k, you worried about 3 bytes in a MOV instruction ? Come on.  :P

Well, recently I was accused of wasting precious speed with some push/pop pairs ;-)
It's the fun of testing the limits, Hutch. Why else are we here in this forum??

Besides, I wanted to create a GUI example that looks a bit more concise and more modern than \masm32\examples\exampl01\generic\generic.asm.
Title: Re: Short global variables
Post by: mywan on July 23, 2012, 08:00:23 PM
Even when I say to hell with it, I'm going the easy route, I still want to know how much efficiency I'm am trading for that ease.
Title: Re: Short global variables
Post by: Ryan on July 23, 2012, 09:24:31 PM
How many cycles does each version take?
Title: Re: Short global variables
Post by: hutch-- on July 23, 2012, 09:31:17 PM
JJ,

> Besides, I wanted to create a GUI example that looks a bit more concise and more modern than \masm32\examples\exampl01\generic\generic.asm.

Do you mean like masm1k.asm ?
Title: Re: Short global variables
Post by: jj2007 on July 23, 2012, 09:36:29 PM
It's more a proof of concept than anything else, and an extension of Dave's structures method (which I also frequently use) to all global variables.

Re trading,

- you need typically two mov ebx, offset globalvars (the SetGlobals without args does that), one in the startup code plus one in the WndProc (assuming no other callbacks).
- in case you need ebx in an innermost loop, you cannot use global variables there
+ shorter code anywhere else,
+ with a chance of getting faster code through fitting more into the CPU cache
+ same syntax for local and global variables
+ variables in WndProc remain valid for the next message (e.g. a RECT)
+ cleaner code for multi-threaded apps (i.e. you can use the same variable names for different memory areas)

It looks a bit different, though :biggrin:

> Do you mean like masm1k.asm ?
masm1k is a "naked" window; the example posted above has a few controls and handles messages etc

> How many cycles does each version take?
There is no difference, except if you have an innermost loop that fits into the CPU cache for the "short globals" version but doesn't for the "long" one. There is certainly no measurable difference for the handling of WM_xxx messages in the WndProc.
Title: Re: Short global variables
Post by: Ryan on July 23, 2012, 10:25:33 PM
Just out of curiosity, what file system/cluster size do you use?
Title: Re: Short global variables
Post by: qWord on July 23, 2012, 10:42:22 PM
Quote from: Ryan on July 23, 2012, 10:25:33 PM
Just out of curiosity, what file system/cluster size do you use?
He has create his own FS that allows a cluster size of 1 Byte - the days of oversized and byte wasting clusters are over  :biggrin:
Title: Re: Short global variables
Post by: Ryan on July 23, 2012, 10:45:51 PM
Nice!  His file system uses a cluster size of 1/512 of a sector!
Title: Re: Short global variables
Post by: qWord on July 23, 2012, 10:53:09 PM
Quote from: Ryan on July 23, 2012, 10:45:51 PM
His file system uses a cluster size of 1/512 of a sector!
When interpreting all sectors as a byte stream, you can choose whatever cluster size without losing any byte in the sectors.  :P
Title: Re: Short global variables
Post by: Ryan on July 23, 2012, 11:05:04 PM
How do you get the assembler to truncate the unused bytes at the end of the executable?
Title: Re: Short global variables
Post by: hutch-- on July 24, 2012, 01:00:35 AM
You don't, its the linker that produces the final EXE file but its still not good practice, at least some OS version don't like misaligned ends of EXE files and some AV scanners have nightmares with such mods.
Title: Re: Short global variables
Post by: mywan on July 24, 2012, 01:36:51 AM
I think a lot of AV scanners like to scare their customers into thinking their doing them a favor. Some scanners, if you set them to go after ad cookies, will label them viruses, tracking.exploit, or something similar to. More marketing than substance. What they will not say is how easy it is to stash a 10 gig file on a machine that the scanner can't even find, much less scan.
Title: Re: Short global variables
Post by: jj2007 on July 24, 2012, 09:00:31 AM
Quote from: qWord on July 23, 2012, 10:42:22 PM
Quote from: Ryan on July 23, 2012, 10:25:33 PM
Just out of curiosity, what file system/cluster size do you use?
He has create his own FS that allows a cluster size of 1 Byte - the days of oversized and byte wasting clusters are over  :biggrin:
Quote from: Ryan on July 23, 2012, 10:45:51 PM
Nice!  His file system uses a cluster size of 1/512 of a sector!

Hutch,

Could you please move these posts to their proper place (http://masm32.com/board/index.php#c7)? Afterwards, please delete this one (by the way: the old forum used to have a delete button - where is it gone?)

Thanks.
Title: Re: Short global variables
Post by: hutch-- on July 24, 2012, 10:17:36 AM
No need, the Workshop is a place for general discussion and many topics wander from their original subject.
Title: Re: Short global variables
Post by: Ryan on July 24, 2012, 11:45:15 AM
My apologies.  I was trying to get a feeling for pros and cons.  I got a bit carried away.  I'm sorry.
Title: Re: Short global variables
Post by: Antariy on July 24, 2012, 12:29:28 PM
Jochen, it's cute technique simplifying the code readability, besides it could have its use, for instance, in an inner loops of some heavy multithreaded apps (for accessing global vars controlling the threads each from another) :t
Title: Re: Short global variables
Post by: jj2007 on July 24, 2012, 12:36:50 PM
Quote from: Antariy on July 24, 2012, 12:29:28 PM
Jochen, it's cute technique simplifying the code readability, besides it could have its use, for instance, in an inner loops of some heavy multithreaded apps (for accessing global vars controlling the threads each from another) :t

Thanks, Alex, that could indeed be the most interesting application for this technique.

@Ryan: Thanks for the clarification :icon14:
Title: Re: Short global variables
Post by: dedndave on July 25, 2012, 08:04:39 AM
it can do a lot for you

if you look at the structures i posted earlier, you will see that i have horz and vert scroll info structs
i use the same code for both axis
at the beginning, i just grab a pointer into the structure
if it is horz scroll, the scroll info struct is right there
if it is vert scroll, i add the struct size and - bang - i am pointing at vert scroll info
then - both use the same code

again - with the handles...
when the child windows and controls are created in a loop, the handles fill the structure
in WM_SIZE, i use an index into the handle struct to adjust window/control sizes and positions

so - it saves more than a few bytes   :t
Title: Re: Short global variables
Post by: Gunther on July 25, 2012, 08:09:59 AM
Quote from: dedndave on July 25, 2012, 08:04:39 AM
so - it saves more than a few bytes   :t

Dave,

good point and a really cool technique. :t

Gunther