I am again fighting with retrieving the number of parameters from PROTOtyped procedure (http://www.old.masmforum.com/viewtopic.php?t=4839).
Today it comes to my mind that TYPE operator should return the needed information, but I have failed: :(
.686
.MODEL FLAT, STDCALL
.RADIX 16 ; ECHO hexa values
ExitProcess PROTO :DWORD
pr1 TYPEDEF PROTO :DWORD
x1 TEXTEQU %TYPE (ExitProcess)
x2 TEXTEQU %TYPE (pr1)
%ECHO TYPE (ExitProcess) : x1
%ECHO TYPE (TYPEDEF PROTO :DWORD): x2
ECHO
IF (TYPE (ExitProcess)) EQ (TYPE (pr1))
ECHO * It works!
ELSE
ECHO * It does not work...
ENDIF
.CODE
Start:
END Start
When I assemble it, I get:
TYPE (ExitProcess) : FF04
TYPE (TYPEDEF PROTO :DWORD): FF04
* It does not work...
Any ideas?
BTW, the TYPE operator is kind of magic. Look at the following example:
.686
.MODEL FLAT, STDCALL
.RADIX 16 ; ECHO hexa values
DoubleWord STRUCT
x DWORD ?
DoubleWord ENDS
x1t TEXTEQU %TYPE (DWORD)
x2t TEXTEQU %TYPE (DoubleWord)
x1s TEXTEQU %SIZEOF (DWORD)
x2s TEXTEQU %SIZEOF (DoubleWord)
%ECHO TYPE (DWORD) : x1t
%ECHO TYPE (DoubleWord): x2t
ECHO
%ECHO SIZEOF (DWORD) : x1s
%ECHO SIZEOF (DoubleWord): x2s
ECHO
IF (TYPE (DWORD)) EQ (TYPE (DoubleWord))
ECHO * Data type DWORD has the same type as DoubleWord structure
ELSE
ECHO * Data type DWORD has different type as DoubleWord structure
ENDIF
.CODE
Start:
END Start
it returns:
TYPE (DWORD) : 4
TYPE (DoubleWord): 4
SIZEOF (DWORD) : 4
SIZEOF (DoubleWord): 4
* Data type DWORD has different type as DoubleWord structure
It seems that TYPE returns also some hidden information, not only size of the type. I was hoping that information help me on the topic...
Is EQ an appropriate comparison to be using? For both examples it always returns FALSE, so perhaps it's returning a text value rather than a numeric value. I've never gotten deep into MASMs macro language, maybe it's about time I did ::)
Karel,
I have been playing with this one to recognise an operand type and within its tested rangle it seems to work OK. An API call seems to return zero which says its treated as a label.
LATER :
Played with the macro a little more.
op_type MACRO var
IF (OPATTR (var)) and 00000001y ;; 0 label
EXITM %0
ELSEIF (OPATTR (var)) and 00000010y ;; 1 memory operand
EXITM %1
ELSEIF (OPATTR (var)) and 00000100y ;; 2 immediate
EXITM %2
ELSEIF (OPATTR (var)) and 00010000y ;; 4 register
EXITM %4
ELSE
EXITM %64
ENDIF
ENDM
Tested it this way in the code section.
echo -------------------
% echo op_type(item)
% echo op_type(edx)
% echo op_type(varx)
% echo op_type(1234)
echo -------------------
Producing this result.
-------------------
0
4
1
2
-------------------
zooba,
we can always use only EQ, NE, GE, LE, GT, LT, nothing else.
Operators always return a numeric value. We can try to convert the value to the text one:
.686
.MODEL FLAT, STDCALL
ExitProcess PROTO :DWORD
pr0 TYPEDEF PROTO
pr1 TYPEDEF PROTO :DWORD
pr2 TYPEDEF PROTO :DWORD,:DWORD
xa TEXTEQU %TYPE (ExitProcess)
x0 TEXTEQU %TYPE (pr0)
x1 TEXTEQU %TYPE (pr1)
x2 TEXTEQU %TYPE (pr2)
%IF xa EQ x0
ECHO * ExitProcess PROTO
ENDIF
%IF xa EQ x1
ECHO * ExitProcess PROTO :DWORD
ENDIF
%IF xa EQ x2
ECHO * ExitProcess PROTO :DWORD,:DWORD
ENDIF
.CODE
Start:
END Start
output:
* ExitProcess PROTO
* ExitProcess PROTO :DWORD
* ExitProcess PROTO :DWORD,:DWORD
That's because we lose that "hidden" information after the conversion. 0FF04h EQ 0FF04h is always true.
hutch--,
OPATTR works very well, I have a bunch of macros like IsReg, IsMem, IsDirMemAdr, IsLabel etc. to make my macros more readable.
Unfortunatelly, OPATTR does not help us on the topic. I'm trying to compare the TYPE of ExitProcess with TYPE of PROTO :DWORD, but it always returns FALSE. :(
Karel,
Try string comparison with IFIDN or IFDIF, it may work for you if you can test the beginning of the string you are interested in.
I can't, I have just variable external function label.
To make it even more difficult, MASM replaces the API name like MessageBox with MessageBoxA BEFORE you work on it.