The MASM Forum Archive 2004 to 2012

General Forums => The Workshop => Topic started by: Nordwind64 on June 26, 2009, 05:31:03 PM

Title: IsConstant?
Post by: Nordwind64 on June 26, 2009, 05:31:03 PM
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
Title: Re: IsConstant?
Post by: ToutEnMasm on June 26, 2009, 06:02:30 PM
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
Title: Re: IsConstant?
Post by: ramguru on June 26, 2009, 06:21:09 PM
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 :}
Title: Re: IsConstant?
Post by: dedndave on June 26, 2009, 06:26:14 PM
most (if not all) of the windows constants or "pins" are located in the windows.inc file
Title: Re: IsConstant?
Post by: Nordwind64 on June 26, 2009, 07:25:45 PM
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...  :(
Title: Re: IsConstant?
Post by: qWord on June 26, 2009, 07:27:23 PM
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

Title: Re: IsConstant?
Post by: Nordwind64 on June 26, 2009, 07:34:25 PM
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?
Title: Re: IsConstant?
Post by: qWord on June 26, 2009, 07:40:55 PM

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
Title: Re: IsConstant?
Post by: Nordwind64 on June 26, 2009, 07:59:13 PM
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?
Title: Re: IsConstant?
Post by: Nordwind64 on June 26, 2009, 08:11:16 PM
Seems, it don't work.

iscon MACRO arg
  % echo arg
ENDM

iscon WM_PAINT


Gives back:

WM_PAINT

Not 15...

:'(
Title: Re: IsConstant?
Post by: qWord on June 26, 2009, 08:17:06 PM
OK, did i understand you right:

IsCon(12345)   ; this should return FALSE
IsCon(WM_PAINT); this should return TRUE


Title: Re: IsConstant?
Post by: 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
Title: Re: IsConstant?
Post by: Nordwind64 on June 26, 2009, 08:21:48 PM
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...
Title: Re: IsConstant?
Post by: qWord on June 26, 2009, 08:27:16 PM
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"
Title: Re: IsConstant?
Post by: Nordwind64 on June 26, 2009, 08:36:59 PM
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...
Title: Re: IsConstant?
Post by: dedndave on June 26, 2009, 08:52:33 PM
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
Title: Re: IsConstant?
Post by: qWord on June 26, 2009, 08:55:46 PM
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)
Title: Re: IsConstant?
Post by: Nordwind64 on June 26, 2009, 08:57:53 PM
Hey cool, that seems to work...

IFDEF WM_PAINT
 PrintDec 1
ELSE
 PrintDec 0
ENDIF


I will test this extensively!
Title: Re: IsConstant?
Post by: Nordwind64 on June 26, 2009, 09:16:43 PM
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
Title: Re: IsConstant?
Post by: qWord on June 26, 2009, 09:19:03 PM

MacroName macro txt:=<>
IFDEF txt
PrintDec 1
ELSE
PrintDec 0
ENDIF
endm
Title: Re: IsConstant?
Post by: Nordwind64 on June 26, 2009, 09:31:21 PM
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
Title: Re: IsConstant?
Post by: Nordwind64 on June 27, 2009, 10:39:16 PM
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
Title: Re: IsConstant?
Post by: dedndave on June 28, 2009, 12:42:28 AM
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
Title: Re: IsConstant?
Post by: jj2007 on June 28, 2009, 09:26:52 AM
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
Title: Re: IsConstant?
Post by: Nordwind64 on June 28, 2009, 09:51:33 AM
 :'(

Ok, seems that cannot work. So I will go parsing the include-files.  ::)
Thank you to everybody which wanted to help me!  :U