News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

TEXTEQU problem

Started by mabdelouahab, February 04, 2015, 08:25:49 AM

Previous topic - Next topic

mabdelouahab

Hello everyone
First, my problem is in English, I hope that concentrated with me a little bit, Please
So ,
When I used TEXTEQU, to get the text value , the process is to succeed me
LastP___ textequ <Anything>
And when I want to cancel the value use LastP___ textequ <>
And I can simply re-use variable again.  LastP___ textequ <Anything Else>
But the problem is when I use the variable in MACRO, I like


__DEF MACRO __arg:VARARG
IFNDEF Last___
Last___ = 0
ENDIF
Last___ = Last___+1
??nArg = 0
% for Str_ , <&__arg>
??nArg = ??nArg + 1
% @CatStr(<_>,%Last___,<_>,%??nArg,<_>) textequ <__&Str_&>
@CatStr(&Str_&) textequ <dword ptr [ebp- @CatStr(%??nArg*4)]>
  endm
LastnArg__ = ??nArg
endm

I canceled using the following Macro

__UnDEF MACRO 
  ?????nArg = LastnArg__
  ??nArg =0
  repeat ?????nArg
??nArg=??nArg+1
??o textequ <@CatStr(<_>,%Last___,<_>,%??nArg,<_>)>
@SubStr(@CatStr(%??o), 3,) textequ <>
  endm
endm


I can not use the variable that I entered again


__DEF A,B   ;Succeed
    ;..................  Succeed
__UnDEF          ;Succeed but From here A is nothing (= <>)
   ;................
__DEF abc,Z,A,B  ;<--- = (__DEF abc,Z, , )


Because it is the second time means nothing. " "

My question is , How can I re- A = A and not A = nothing

To bring the idea , the way in which I would like to access similar to the use of variables in the part of the program I want to be the words have meaning , then fired its use again , and come back in another part use them again
For example :
When using the macro "LOCAL Abc:DWORD  " in the procedure , the "Abc " means -(for example)-  "<dword ptr [ebp-4]> " ,And after "ENDP  " the " Abc" mean Abc  not "<> or nothing"

dedndave

don't use TEXTEQU in the macro, use a LOCAL....

      ustr$ MACRO number
        LOCAL buffer
        .data?
          buffer TCHAR 40 dup (?)
          align 4
        .code
        IFNDEF __UNICODE__
          invoke crt__ultoa,number,ADDR buffer,10
        ELSE
          invoke crt__ultow,number,ADDR buffer,10
        ENDIF
        EXITM <eax>
      ENDM


now, the symbol "buffer" may be used elsewhere

mabdelouahab

Good morning dedndave,Good morning everyone
I think that you did not understand my problem
I want to make a MACRO simulates LOCAL, I want to declare variables in a particular part only ,
look
When using "LOCAL"

FirstProc PROC
LOCAL Abc:dword ; ---> Abc textequ <DWORD PTR [ebp-4]>
mov eax,Abc ; ---> mov eax ,DWORD PTR [ebp-4]
ret
FirstProc endp
; ---> Abc =Abc
SecProc PROC
LOCAL Z,Abc:dword ; ---> Abc textequ <DWORD PTR [ebp-8]>
mov eax,Abc ; ---> mov eax ,DWORD PTR [ebp-8]
ret
FirstProc endp

and When using my macro "__DEF"

FirstProc PROC
__DEF Abc ; ---> Abc textequ <DWORD PTR [ebp-4]>
mov eax,Abc ; ---> mov eax ,DWORD PTR [ebp-4]
ret
FirstProc endp
__UnDEF
; ---> Abc = nothing
SecProc PROC
__DEF Z,Abc ; Error because ---> __DEF Z,
mov eax,Abc ; ---> mov eax ,
ret
FirstProc endp

I am looking for a replacement for "TEXTEQU <> " in  __UnDEF macro, They make Abc  means nothing (Abc is just  example)

rrr314159

Hello mabdelouahab,

The first puzzle is to understand what you want, the second is how to do it.

FirstProc PROC
; __DEF Abc ; __DEF MACRO doesn't do anything, u might mean "IFDEF"
Abc textequ <DWORD PTR [ebp-4]> ; Simply define Abc like this
mov eax,Abc ; ---> mov eax,DWORD PTR [ebp-4] ; yes, you'd get this
ret
FirstProc endp

; __UnDEF ; the puzzle is, what you want __UNDEF to do
; ---> Abc = nothing ; I think you want to UNDEFINE the Symbol
Abc textequ <> ; this makes sense but I think not what you want

SecProc PROC
LOCAL Z: dword ; I think your Z is just a dword
; __DEF Z,Abc ; Error because ---> __DEF ; I think u want to use IFDEF to skip it
; ; because Abc has become UNDEFINED
mov eax,Abc ; ---> mov eax , ; yes you'd get a blank with "Abc textequ <>"
ret
SecProc endp


That's how it would work with textequ <> but I think you want to UNDEFINE the symbol Abc?

Abc textequ <DWORD PTR [ebp-4]>
IFDEF Abc
mov eax,Abc ; ---> mov eax,DWORD PTR [ebp-4]
ENDIF

;__UnDEF Abc ; u want to UNDEFINE Abc

IFDEF Abc
mov eax,Abc ; ---> nothing happens because Abc is undefined, so the line is skipped
ENDIF


Is that what you want?
I am NaN ;)

mabdelouahab

hi rrr314159 ;
Quote from: rrr314159 on February 04, 2015, 07:04:01 PM
The first puzzle is to understand what you want, the second is how to do it.
Thank you for your attention
I understand very well what I want, I created a macro group , to work on the CLR,
and kept me only this problem, and I'm asking now . How can I make _DEF macro works like LOCAL macro

*  _DEF Macro works well, but only once, Because the problem in __UnDef ,exactly in "TEXTEQU <>"

1. When I use : __DEF Var01,Var02
I get :      (mov eax,Var01) ==>(mov eax,DWORD PTR [ebp-4])
2. Then I used __UnDef , at the end of the sector
3. When the re- use :  __DEF R,Index,Var01,A
I get the problem :  __DEF R,Index, ,A
Because __UnDef Mark Var01 = nothing or "" or <>

What is the alternative "Var01 TEXTEQU <>" To use them in  __UnDef , and gives me Var01 not "nothing"  (To the nearest idea Var01 = "Var01" not  Var01 = "")

** I know that the problems in English , please excuse us on Google Translate

qWord

Tricky problem ... quickly worked out solution, so no guaranty for generality:
defhelper macro txtmac_name
IFNDEF redef_hlp_&txtmac_name
redef_hlp_&txtmac_name macro newTxt
txtmac_name TEXTEQU <&newTxt>
endm
ENDIF
endm

__DEF MACRO __arg:VARARG
IFNDEF Last___
Last___ = 0
ENDIF
LastnArg__ = 0
for Str_ , <&__arg>
defhelper Str_
@CatStr(<_>,%Last___,<_>,%LastnArg__,<_>) textequ <redef_hlp_&Str_>
Str_ textequ <dword ptr [ebp->, %(LastnArg__ + 1)*4, <]>
LastnArg__ = LastnArg__ + 1
endm
Last___ = Last___ + 1
endm


__UnDEF MACRO
??nArg = 0
repeat LastnArg__
@CatStr(<_>,%Last___-1,<_>,%??nArg,<_>) <>
??nArg = ??nArg + 1
endm
endm

MREAL macros - when you need floating point arithmetic while assembling!

dedndave

i understand, now
and, i was about to say that a symbol cannot be undefined
then, qWord comes along and shows us how   :lol:

mabdelouahab

Thank you qWord  for the smart solution
Quote from: qWord on February 04, 2015, 10:28:45 PM
.., so no guaranty for generality:
You are right Because the solution only succeeded with me between _DEF and _UnDEF, and I can re- use with _DEF
But outside the sector remains the same problem
For example
_DEF MyVal      ;succeeded
....
_UnDEF         ;succeeded
..
_DEF A, MyVal       ;succeeded
..
_UnDEF         ;succeeded
...
but if I wanted to use them in other ? ?
MyProc PROC MyVal  :dword       ;Not succeeded  Because it means (MyProc PROC  :dword     )

I do not know , I could be looking for a solution that does not exist

qWord

Quote from: mabdelouahab on February 05, 2015, 02:44:51 AMbut if I wanted to use them in other ? ?
MyProc PROC MyVal  :dword       ;Not succeeded  Because it means (MyProc PROC  :dword     )
It is in a text macro -> when ever "undef" it, just fill it with some unique ID:
get_unique_sym_cntr = 0
get_unique_sym macro
get_unique_sym_cntr = get_unique_sym_cntr + 1
EXITM @CatStr(<unique>,%get_unique_sym_cntr-1)
endm

__UnDEF MACRO
??nArg = 0
repeat LastnArg__
@CatStr(<_>,%Last___-1,<_>,%??nArg,<_>) get_unique_sym()
??nArg = ??nArg + 1
endm
endm


Just as side note (I guess it is clear for you), it as dave said before, symbols can not be deleted/removed (unfortunately).
You might give us some more information about the usage of these macros, to see if there is some other solution...
MREAL macros - when you need floating point arithmetic while assembling!

dedndave


rrr314159

@mabdelouahab
Quote"I understand very well what I want,... "
Sorry! Please, no offense! I meant I (we) had to understand what you want. Of course, YOU understand what you want, but your English is difficult.

qword, I think your solution is not it.__DEF abc, def  ; defines abc as "dword ptr [ebp-4]"
%echo abc       ; and def as "dword ptr [ebp-8]"
%echo def

__DEF abc, def  ; same definitions again
%echo abc
%echo def

%echo _1_0_     ; each time new symbols are defined
%echo _0_0_     ; all of which equal redef_hlp_abc

%echo _1_1_     ; or redef_hlp_def
%echo _0_1_

redef_hlp_abc hello ; the redef_hlp_xyz functions assign
%echo abc           ; a value to xyz

__UnDEF             ; this simply assigns <> (blank)
                    ; to abc and def
%echo abc
IFDEF abc
    echo abc blank but still defined
ENDIF

%echo def
IFDEF def
    echo def blank but still defined
ENDIF

%echo _1_0_     ; all these symbols are still there
redef_hlp_abc hello again   ; redef_hlp_abc still works
%echo abc
In effect, it's equivalent to this snippet:
abc textequ <dword ptr [ebp-4]>  ; define abc as "dword ptr [ebp-4]"
def textequ <dword ptr [ebp-8]>  ; define def as "dword ptr [ebp-8]"
%echo abc
%echo def

abc equ hello       ; can do this of course, w/o use of redef_hlp_abc
%echo abc

abc textequ <>      ; can assign <> (blank)
def textequ <>      ; to abc and def

%echo abc
IFDEF abc
    echo abc blank but still defined
ENDIF

%echo def
IFDEF def
    echo def blank but still defined
ENDIF

abc equ hello again   ; can still do this
%echo abc
As I said mabdelouahab wants to UNDEFINE his "MyVar". It's the only way that his statement
QuoteMyProc PROC MyVal: dword
can work: MyVal has to be a fresh undefined symbol. As dedndave said, that can't be done ... except, it can! The method is a bit clumsy, but does exactly what mabdelouahab wants ...

As I'm typing this, qword has posted a suggestion about using an unique ID. ... And now, dedndave also has made a suggestion! So, I'll wait and see if either of those fill the bill b4 telling u how to effectively undefine a symbol.

Anyway, this post is 2 long already.
I am NaN ;)

jj2007

I was hoping that PURGE could deal with it, but nope, empty yes, undefined no.
include \masm32\include\masm32rt.inc

ifdef abc
% echo + abc
else
% echo - abc
endif

abc equ hello
ifdef abc
% echo + abc
else
% echo - abc
endif

abc equ
ifdef abc
% echo + abc
else
% echo - abc
endif

bla MACRO args
  EXITM <this is bla>
ENDM

ifdef bla
% echo b+ bla()
else
% echo b- bla()
endif

PURGE bla

ifdef bla
% echo b+ bla()
else
% echo b- bla()
endif

.code
start:
exit
echo
.err
end start

mabdelouahab

Quote from: rrr314159 on February 05, 2015, 04:14:30 AM
... how to effectively undefine a symbol.
Thank you rrr314159 Is exactly what I wanted to say, (and I'm sorry for the Englis,not I am,  is Google translation)

rrr314159

Hello mabdelouahab,

I hope my idea works for you. From what I know of your situation, it may.

Simply, use a second module.

Since I don't know much about your level of MASM knowledge I'll spell it out a bit; if you already know all this please excuse.

Use two separate .asm files. Compile them separately into .obj files and link them into one .exe with the linker.

In the first one, use MyVar as you want. When you need to "UNDEFINE" it, call into the second module. Over there it will be a fresh instance, undefined at first, knowing nothing of how MyVar was used in the first module.

Make sure MyVar is not public: it can't be a procedure name, or EXTERNDEF'ed, or in a common include file. It can be a macro name, symbol, variable, code label or data label, as long as it's not public (or "global").

Of course you can do this with as many symbols as you like. If you have hundreds of symbols that work together, want to "UNDEFINE" them all together, put them all in the 2nd module.

If you need to "UNDEFINE" MyVar again you'll need a third module. The linker can handle dozens. It might be clumsy - well it IS clumsy - but I hope it solves your problem.

If not, sorry; in that case qword's suggestion is good, you would need to tell more about why you want to do this, for someone to think of a better solution.

Good Luck!
I am NaN ;)

mabdelouahab

By using a trick , and the exploitation of the compilation , I suggest the following solution:

___DEF MACRO __arg:VARARG
.code
IFNDEF Last___
Last___ = 0
ENDIF
Last___ = Last___ + 1
LastnArg__ = 0
for Str_ , <&__arg>
LastnArg__ = LastnArg__ + 1
endm

OPTION PROLOGUE:NONE
OPTION EPILOGUE:NONE
PUSH EBP
PUSH EAX
invoke GetProcessHeap
% invoke HeapAlloc, EAX, NULL, @CatStr(%LastnArg__*4)
MOV EBP,EAX
ADD EBP,@CatStr(%LastnArg__*4)
POP EAX
@CatStr(<__>,%Last___,<_TMP_ PROC>)
for Str_ , <&__arg>
% LOCAL Str_ :DWORD
endm
OPTION PROLOGUE:PrologueDef
OPTION EPILOGUE:EpilogueDef
ENDM

___UnDEF MACRO
OPTION PROLOGUE:NONE
OPTION EPILOGUE:NONE
@CatStr(<__>,%Last___,<_TMP_ ENDP>)
PUSH EAX
SUB EBP ,@CatStr(%LastnArg__*4)
invoke GetProcessHeap
invoke HeapFree, EAX, NULL,ebp
POP EAX
POP EBP
OPTION PROLOGUE:PrologueDef
OPTION EPILOGUE:EpilogueDef
ENDM

Usage

start:
xor eax,eax
___DEF My01_Var,A,B
xor eax,eax
mov My01_Var, eax
mov B,eax
mov eax,14
mov A,eax
invoke crt_wprintf,cfm$("\n   %d,%d,%d \n") ,My01_Var,A,B
___UnDEF

; mov eax,B ;: error A2006: undefined symbol : B

___DEF A,My01_Var,B
xor eax,eax
mov A, eax
mov B,eax
mov eax,77
mov My01_Var,eax
invoke crt_wprintf,cfm$("\n   %d,%d,%d \n") ,My01_Var,A,B
___UnDEF

; mov eax,My01_Var ;: error A2006: undefined symbol : My01_Var

___DEF A,B
; mov eax,My01_Var ;: error A2006: undefined symbol : My01_Var
___UnDEF

inkey
exit

Output:

   0,14,0

   77,0,0
Press any key to continue ...

Olly:

004010C0 >/$ 33C0           XOR EAX,EAX                              ;  kernel32.BaseThreadInitThunk
004010C2  |. 55             PUSH EBP
004010C3  |. 50             PUSH EAX
004010C4  |. E8 EB010000    CALL <JMP.&kernel32.GetProcessHeap>      ; [GetProcessHeap
004010C9  |. 6A 0C          PUSH 0C                                  ; /HeapSize = C (12.)
004010CB  |. 6A 00          PUSH 0                                   ; |Flags = 0
004010CD  |. 50             PUSH EAX                                 ; |hHeap
004010CE  |. E8 E7010000    CALL <JMP.&kernel32.HeapAlloc>           ; \HeapAlloc
004010D3  |. 8BE8           MOV EBP,EAX
004010D5  |. 83C5 0C        ADD EBP,0C
004010D8  |. 58             POP EAX
004010D9  |. 55             PUSH EBP
004010DA  |. 8BEC           MOV EBP,ESP
004010DC  |. 83C4 F4        ADD ESP,-0C
004010DF  |. 33C0           XOR EAX,EAX
004010E1  |. 8945 FC        MOV DWORD PTR SS:[EBP-4],EAX
004010E4  |. 8945 F4        MOV DWORD PTR SS:[EBP-C],EAX
004010E7  |. B8 0E000000    MOV EAX,0E
004010EC  |. 8945 F8        MOV DWORD PTR SS:[EBP-8],EAX
004010EF  |. FF75 F4        PUSH DWORD PTR SS:[EBP-C]                ; /<%d>
004010F2  |. FF75 F8        PUSH DWORD PTR SS:[EBP-8]                ; |<%d>
004010F5  |. FF75 FC        PUSH DWORD PTR SS:[EBP-4]                ; |<%d>
004010F8  |. 68 00304000    PUSH JastForM.00403000                   ; |format = "..   %d,%d,%d .."
004010FD  |. FF15 2C204000  CALL DWORD PTR DS:[<&msvcrt.wprintf>]    ; \wprintf
00401103  |. 83C4 10        ADD ESP,10
00401106  |. 50             PUSH EAX
00401107  |. 83ED 0C        SUB EBP,0C
0040110A  |. E8 A5010000    CALL <JMP.&kernel32.GetProcessHeap>      ; [GetProcessHeap
0040110F  |. 55             PUSH EBP                                 ; /pMemory
00401110  |. 6A 00          PUSH 0                                   ; |Flags = 0
00401112  |. 50             PUSH EAX                                 ; |hHeap
00401113  |. E8 A8010000    CALL <JMP.&kernel32.HeapFree>            ; \HeapFree
00401118  |. 58             POP EAX
00401119  |. 5D             POP EBP
0040111A  |. 55             PUSH EBP
0040111B  |. 50             PUSH EAX
0040111C  |. E8 93010000    CALL <JMP.&kernel32.GetProcessHeap>      ; [GetProcessHeap
00401121  |. 6A 0C          PUSH 0C                                  ; /HeapSize = C (12.)
00401123  |. 6A 00          PUSH 0                                   ; |Flags = 0
00401125  |. 50             PUSH EAX                                 ; |hHeap
00401126  |. E8 8F010000    CALL <JMP.&kernel32.HeapAlloc>           ; \HeapAlloc
0040112B  |. 8BE8           MOV EBP,EAX
0040112D  |. 83C5 0C        ADD EBP,0C
00401130  |. 58             POP EAX
00401131  |. 55             PUSH EBP
00401132  |. 8BEC           MOV EBP,ESP
00401134  |. 83C4 F4        ADD ESP,-0C
00401137  |. 33C0           XOR EAX,EAX
00401139  |. 8945 FC        MOV DWORD PTR SS:[EBP-4],EAX
0040113C  |. 8945 F4        MOV DWORD PTR SS:[EBP-C],EAX
0040113F  |. B8 4D000000    MOV EAX,4D
00401144  |. 8945 F8        MOV DWORD PTR SS:[EBP-8],EAX
00401147  |. FF75 F4        PUSH DWORD PTR SS:[EBP-C]                ; /<%d>
0040114A  |. FF75 FC        PUSH DWORD PTR SS:[EBP-4]                ; |<%d>
0040114D  |. FF75 F8        PUSH DWORD PTR SS:[EBP-8]                ; |<%d>
00401150  |. 68 24304000    PUSH JastForM.00403024                   ; |format = "..   %d,%d,%d .."
00401155  |. FF15 2C204000  CALL DWORD PTR DS:[<&msvcrt.wprintf>]    ; \wprintf
0040115B  |. 83C4 10        ADD ESP,10
0040115E  |. 50             PUSH EAX
0040115F  |. 83ED 0C        SUB EBP,0C
00401162  |. E8 4D010000    CALL <JMP.&kernel32.GetProcessHeap>      ; [GetProcessHeap
00401167  |. 55             PUSH EBP                                 ; /pMemory
00401168  |. 6A 00          PUSH 0                                   ; |Flags = 0
0040116A  |. 50             PUSH EAX                                 ; |hHeap
0040116B  |. E8 50010000    CALL <JMP.&kernel32.HeapFree>            ; \HeapFree
00401170  |. 58             POP EAX
00401171  |. 5D             POP EBP
00401172  |. 55             PUSH EBP
00401173  |. 50             PUSH EAX
00401174  |. E8 3B010000    CALL <JMP.&kernel32.GetProcessHeap>      ; [GetProcessHeap
00401179  |. 6A 0C          PUSH 0C                                  ; /HeapSize = C (12.)
0040117B  |. 6A 00          PUSH 0                                   ; |Flags = 0
0040117D  |. 50             PUSH EAX                                 ; |hHeap
0040117E  |. E8 37010000    CALL <JMP.&kernel32.HeapAlloc>           ; \HeapAlloc
00401183  |. 8BE8           MOV EBP,EAX
00401185  |. 83C5 0C        ADD EBP,0C
00401188  |. 58             POP EAX
00401189  |. 55             PUSH EBP
0040118A  |. 8BEC           MOV EBP,ESP
0040118C  |. 83C4 F4        ADD ESP,-0C
0040118F  |. 8B45 FC        MOV EAX,DWORD PTR SS:[EBP-4]
00401192  |. 50             PUSH EAX
00401193  |. 83ED 0C        SUB EBP,0C
00401196  |. E8 19010000    CALL <JMP.&kernel32.GetProcessHeap>      ; [GetProcessHeap
0040119B  |. 55             PUSH EBP                                 ; /pMemory
0040119C  |. 6A 00          PUSH 0                                   ; |Flags = 0
0040119E  |. 50             PUSH EAX                                 ; |hHeap
0040119F  |. E8 1C010000    CALL <JMP.&kernel32.HeapFree>            ; \HeapFree
004011A4  |. 58             POP EAX
004011A5  |. 5D             POP EBP