Hi,
Is it possible to detect, if a system constant is known in a running code?
Just like the function GetProcAdresse for API.
text db "WM_PAINT",0
;...
invoke IsConstant,addr text
.if eax
;...
Any ideas?
:eek
constant can be only loaded in a register or pushed on stack.
at runtime,there is no constant.
Only soluce i see,is to put them in data and to test for equality.
.const
ThisConstant equ 458
.data
Myconst dd ThisConstant
.code
mov eax,Myconst
.if eax == Text
;do something
.endif
All those winapi (named) constants are just for developer only, to make things clearer.
None of them are saved into an executable as text labels.
This is really simple to understand, because
WM_PAINT equ 15
it doesn't mean that there can't another constant with the same value.
There could be:
MY_NUMBER equ 15
DIVIDER equ 15
..
So such function simply can't exist :}
edit > But if you mean to detect if constant is defined in include files
& tell that at run time :} wow .. there is no easy way | unless you wanna make a parser :}
most (if not all) of the windows constants or "pins" are located in the windows.inc file
QuoteAll those winapi (named) constants are just for developer only, to make things clearer.
Yes, I know. The assembler/linker detects the constant-words in code and change them to decimal. If a constant could not find in the include-files, the linker will give an error. Seems, there is no chance to make my idea true... :(
hi,
it is possible to write a macro, that record the name and value of used Constans. This could look something like (just an idea):
; e.g. inside WndProc
.if uMsg == con(<WM_PAINT>)
.elseif uMsg == con(<WM_CREATE>)
.elseif uMsg == con(<WM_GETTEXT>)
...
.endif
regards, qWord
Ah, and the macro looks, if the parameter is alpha or numeric? If it is text, the constant was not found in an include. If it is numeric, it was changed... possible?
con macro txt:=<>
IFNDEF const_cntr
const_cntr = 1
@CatStr(<const_name_>,%const_cntr) TEXTEQU <&txt>
@CatStr(<const_value_>,%const_cntr) = txt
EXITM <&txt>
ENDIF
cc_flag = 0
cc_cntr = 1
REPEAT const_cntr
% IFIDN <&txt>,<@CatStr(<const_name_>,%cc_cntr)>
cc_flag = 1
EXITM
ENDIF
cc_cntr = cc_cntr + 1
ENDM
IF cc_flag EQ 0
const_cntr = const_cntr + 1
@CatStr(<const_name_>,%const_cntr) TEXTEQU <&txt>
@CatStr(<const_value_>,%const_cntr) = txt
ENDIF
EXITM <&txt>
endm
; this macro can be changed, so that it creates
; a (string-)table in data-section -> you can read this table at runtime
show_con macro
IFNDEF const_cntr
%echo no const used
EXITM
ENDIF
%echo Used Const's:
pushcontext radix
.radix 16
cc_cntr = 1
REPEAT const_cntr
%echo @CatStr(<const_name_>,%cc_cntr) EQU @CatStr(<0>,%(@CatStr(<const_value_>,%cc_cntr)),<h>)
cc_cntr = cc_cntr + 1
ENDM
popcontext radix
endm
;-------------------------------
; e.g. inside WndProc
.if uMsg == con(<WM_PAINT>)
.elseif uMsg == con(<WM_CREATE>)
.elseif uMsg == con(<WM_GETTEXT>)
.endif
; show used EQU's in build-consol
show_con
Thank you! But I'm not interested in building a constant-database. :P
The macro only must detect, if the parameter is alpha or numeric. Unfortunately, I do not feel well to write macros. Can you please help again?
Seems, it don't work.
iscon MACRO arg
% echo arg
ENDM
iscon WM_PAINT
Gives back:
WM_PAINT
Not 15...
:'(
OK, did i understand you right:
IsCon(12345) ; this should return FALSE
IsCon(WM_PAINT); this should return TRUE
This.
IsCon(WM_DON_T_EXISTS) ; this should return FALSE
IsCon(WM_PAINT); this should return TRUE
Quote from: Nordwind64 on June 26, 2009, 08:20:24 PM
This.
IsCon(WM_DON_T_EXISTS) ; this should return FALSE
IsCon(WM_PAINT); this should return TRUE
But it will not work. MASM don't translate the WM_PAINT to decimal as I though...
You want to proof, if an Constant is defined? If so, use IFNDEF/IFDEF ...
IsCon macro txt:=<>
IFNDEF txt
EXITM <FALSE>
ELSE
EXITM <TRUE>
EXITM
endm
or you want the number as literal?:
@CatStr(%(WM_PAINT)) ; this returns "15"
I would like to know whether the constant is known in the programme or not. WM_PAINT should be confessed. WM_SOMETHING not.
Excuse my bad English...
it is an equate
when the assembler sees it, it simply replaces it with the constant numeric value (or string, in the case of text)
the linker (and, thus, the exe) know nothing of the equate, unless you somehow force it to
mhh..
you want to know this at runtime (? that is also what you ask in your first post). This can only be done, if you record the EQU's names (this is makeable with macros) and save them as strings.
PS: I'm also not an native English speaker :8)
Hey cool, that seems to work...
IFDEF WM_PAINT
PrintDec 1
ELSE
PrintDec 0
ENDIF
I will test this extensively!
Wow, that works fine! It is possible. :U
IFDEF WM_PAINT
PrintDec 1
ELSE
PrintDec 0
ENDIF
IFDEF TDX_JWCZIGRE
PrintDec 1
ELSE
PrintDec 0
ENDIF
IFDEF LVM_APPROXIMATEVIEWRECT
PrintDec 1
ELSE
PrintDec 0
ENDIF
Gives me:
1
0
1
But I could not geht it working as macro. How must I change it to work as macro? Macros are not my strength. :P
MacroName macro txt:=<>
IFDEF txt
PrintDec 1
ELSE
PrintDec 0
ENDIF
endm
Thank you to everybody which have helped me. Particularly to qWord! :U
I would not have thought that an easy solution is possible. :thumbu
Quoteedit > But if you mean to detect if constant is defined in include files
& tell that at run time :} wow .. there is no easy way | unless you wanna make a parser :}
I need this for writing a parser. :lol
Ok, the macro works perfekt with plaint texts like:
IsConst macro txt:=<>
IFDEF txt
mov eax,1
ELSE
xor eax,eax
ENDIF
endm
...
IsConst WM_PAINT
Is it possible to get it working with an address of a string?
lea ecx,text
IsConst ecx
i don't know about that one
in the old days, equates had to be resolved on the first pass of the assembler
the addresses are not resolved until the second pass
the newer assemblers may be different
Quote from: Nordwind64 on June 27, 2009, 10:39:16 PM
Is it possible to get it working with an address of a string?
lea ecx,text
IsConst ecx
No. You test for ecx, a register. Its content is known only at runtime, and
may correspond to an immediate like
offset MyString, but that immediate will always "exist", since it's part of your address space.
If, however, you want to check whether MyString has been defined, it can be done:
ChkIsValidAddress MACRO arg
ifndef <arg>
EXITM <1>
else
EXITM <0>
endif
ENDM
EDIT: However, this still does not allow you to
use an undefined MyString in your code. To achieve that, some more effort is needed:
include \masm32\include\masm32rt.inc
ChkIsValidAddress MACRO arg
xor ecx, ecx
ifdef arg
dec ecx
else
.data
tmp$ CATSTR <arg>, < db "Hello everybody!", 13, 10, 0>
% echo tmp$
tmp$
.code
endif
mov eax, offset &arg&
EXITM <ecx>
ENDM
.data
MyString db "Good morning, I am a defined string", 0
.code
start:
.if ChkIsValidAddress(MyString)
print eax, 13, 10
.else
print "No MyString", 13, 10
.endif
.if ChkIsValidAddress(MyUndefinedString)
print eax, 13, 10
.else
push eax
print "There was no MyUndefinedString", 13, 10, "but now there is one: "
pop eax
print eax
.endif
getkey
exit
end start
:'(
Ok, seems that cannot work. So I will go parsing the include-files. ::)
Thank you to everybody which wanted to help me! :U