To Hutch,

There is a "USES" instruction defined in your MASM32 package.
This was used by Microsoft in their MASM 16 bit compiler.

WHY doesn't this work in the Windows 32 bit environment?

Read a similar answer by you in the MAIN section but am still confused.
It stated that all registers must be preserved by the programmer before
each API and restored after each API. It was my impression that was what the
"USES" paramter did.

Thanks for any help,
jps
Posted on 2002-09-19 09:07:28 by shankle
I'm not Hutch, but I know the answer too :grin:

Uses works in the 32bit env.

Are you using it like this?

MyProc proc uses edi ebx esi hwnd:DWORD, szParam:DWORD

ret
MyProc endp

Uses saves the registers on entry of your proc and restores them on exit, but not before each API (that would be overkill right?) Afaik, no register has to be saved before any API, except the ones you want to keep.
For example if you're using ecx as a counter and at some point your calling an API it would be better to push ecx before the call and pop it after the call to make sure Windows didn't change it.

You have to preserve registers before you give control back to windows, which will happen sooner or later upon exit of your proc. Probably at the WndProc when you give it a ret.


<hr>

Just avoid all this nonsense and code just using eax, ecx and edx. :grin:
Posted on 2002-09-19 09:43:56 by JimmyClif
Thanks JimmyClif for a very informative answer.

Yes, I am using the "WndProc Proc" in the manner you stated.
Posted on 2002-09-19 11:07:38 by shankle
To cover all bases and any other finicky OSes the following should work;

WNDPROC PROC uses eax ecx edx ebx ebp esi edi. hWnd:HWND, iMsg:UINT\
wParam:WPARAM, lParam:LPARAM

Example:
Pushad
INVOKE CreateSolidBrush, 0000ffffh
Popad

The same setup after every API call Ad Infinitum

The only thing I question is will Pushad/Popad cause a problem with esp?
Posted on 2002-09-19 11:45:55 by shankle
WNDPROC PROC uses eax ecx edx ebx ebp esi edi. hWnd:HWND, iMsg:UINT\

wParam:WPARAM, lParam:LPARAM


There is no need to preserve eax, ecx, or edx. These are your trash registers. Use them at your will. Windows doesn't care if you modify them either before or after an API, or whenever.



Pushad
INVOKE CreateSolidBrush, 0000ffffh
Popad


You throw away the return value right after the call with your popad. And why do you want to save all the registers at every call anyway?

Take this as a rule:

If you mess with ESI, EDI or EBX push them before you use them and pop them when you're done. (That's what 'uses' does for you)

If you have a value inside EAX, EDX or ECX you really want to keep - push them before an API call and pop them afterwards.

Don't touch and worry about EBP or ESP.
Posted on 2002-09-19 13:06:03 by JimmyClif
Jack,

You do not need to use PUSHAD/POPAD, just observe the normal convention with EBX ESI and ESI. Jimmy has explained the USES syntax which works fine but if you want to have a more intuitive style of code, you normally do the register preservation manually.

If you are going to use EBX ESI EDI in the proc, manually preserve them in the normal manner at the beginning and end of the proc,


push ebx
push esi
push edi

; write your code

pop edi
pop esi
pop ebx

ret

Of course you only preserve the ones you need to preserve so that you don't do more than you need and slow the proc call down.

Just remember that any API function you call does the same thing but can modify EAX ECX EDX so if you use any of these as counters or similar, preserve them before the API call.

Regards,

hutch@movsd.com
Posted on 2002-09-20 03:34:49 by hutch--