Hello, coders!
I have run into a situation where I need to implement the functionality of "invoke" and "addr" using macros in MASM32v8.
With ADDR - I need to know how to find out if given var is global or local, i.e. if we can do "push var" or we will have to go "lea eax,var push var"
With INVOKE - How do I check amount of given arguments to a function and their sizes: DWORD, WORD, BYTE?
Thank you in advance. I hope someone can answer it.
SolidCode,
If you get the latest macro file posted you have a number of macros that will perform the argument count and can test the actual size of a register.
The distinction between a GLOBAL and LOCAL is not one I think can be done as the OPATTR operator returns the same value for either.
Hi to all!
This macro looked to work for me. Concerning distinction of global and local vars.
pushaddr macro arg:REQ
;now we have to find out what type of var or argument we have
attr = OPATTR(arg)
if attr AND 20h ;;if it's a valid argument
if (attr EQ 25h) OR (attr EQ 3A5h) OR (attr EQ 1A5h) OR (attr EQ 3AAh) ;;if it's a constant and a code reference
;if global label or STDCALL or C CALL label
push offset arg
elseif attr EQ 2Ah ;if it's a global var
push offset arg
elseif (attr EQ 22h) OR (attr EQ 62h)
;if local var (either stacked or another type (eg. [ebx+4]))
lea eax,arg
push eax
else ;else show error
.ERR Invalid argument
endif
else
.ERR Invalid argument
endif
endm
To Hutch.
Can you please look it up and see if I did it correctly?
SolidCode,
You have some return values for OPATTR that I don't have and have not seen before, where did they come from ?
Well, These are combinations of flags according to MASM32 Help on OPATTR.
E.g. start (as the entry point) gives 25h. So it's bit 0 set for code reference, bit 2 set for Immediate value and bit 5 for defined defined symbol w/o errors.
When you get bits beyond the lowest byte (bits 8-10), then you can find out the calling convention for a function (C or STDCALL or Pascal). It is all described in my help file for MASM32.
I made the following macro to get the values:
xcv macro arg:REQ
mov eax,OPATTR(arg)
endm
Then I used code like this:
xcv hHeap ;global
xcv nVar ;local
xcv [edx+4]
xcv start ;entry point
xcv MainDlgProc
xcv wsprintf
xcv UpdateWindow
xcv dword ptr [MessageBox+2]
And then looked the resulting code up in debugger. Of course the better way would have been %echo, I guess, but that required me to recall the way to show numbers with echo, but I needed that faster. And with bit fields it's better to see the resulting value in hex.
I still don't know how to find out the number of arguments that the particular function has in its prototype elsewhere. And the sizes of the arguments. Do you have an idea how this could be performed from inside a macro?
SolidCode,
Compliments, you have done some good research here. When I get in front I will have a play with the info you have posted as it makes for more powerful macros.
LATER : This is very useful info. This is the results from a quick play.
37 entry lbl
98 LOCAL variable
42 GLOBAL variable
48 register
37 any label
805 Procedure
933 API
36 WM_PAINT
98 [edx+4]
I have ml 6.14 and 7.00 set up handy and the values are consistent across both versions.