I have a simple question about the "&" operator, and a macro programming example to explain it:


I have a macro declared like this:



glob_var_1 TEXTEQU <>
glob_var_2 TEXTEQU <>

SET_GLOBAL_VARIABLE MACRO var_index, var_value
glob_var_&var_index& TEXTEQU <var_value>
ENDM

And I'm calling it like this:



SET_GLOBAL_VARIABLE 1, <value_1>

This all works fine, and it sets the global macro variable glob_var_1 to the value <value_1>.


But now I want to take the global variable index from a local variable in the macro instead, like this:



SET_GLOBAL_VARIABLE MACRO var_index, var_value
local_counter = 1
glob_var_&local_counter& TEXTEQU <var_value>
ENDM

And then I immediately get compiler errors?!?

Neither does it work to use a string value in the local variable, like this:



SET_GLOBAL_VARIABLE MACRO var_index, var_value
local_counter = <1>
glob_var_&local_counter& TEXTEQU <var_value>
ENDM


Why is this? I really need to use a local variable in a situation like this, but it seems to be completely impossible? Is there really no way to do it?

I never seem to understand when I can use the "&" operator or not. :( Are there any clearly defined rules for this somewhere to read? It never seems to work as I want anyway. :(


Any clue or explanation whatsoever would be greatly appreciated.

Thanks!
Posted on 2003-01-15 09:25:59 by dELTA
dELTA, it works but I cannot explain the rules.

In such cases its always good to use (or try :grin: ) the "%" op.



SET_GLOBAL_VARIABLE MACRO var_index, var_value
local_counter textequ <1>
%glob_var_&local_counter TEXTEQU <var_value>
ENDM
Posted on 2003-01-15 16:15:32 by japheth
japheth is correct - very hard to figure out exactly how it works sometimes. If you can work through the BNF grammar in the manual you can figure it out exactly, but that is a waste of time.
Posted on 2003-01-15 16:59:13 by bitRAKE
Thanks for the info!

Believe me japheth, I tried to stick that "%" operator at every possible place I could think of in that line. :) But that was not the only problem I just noticed. After trying your solution I still got the error message, so I then noticed that if I removed the global "declaration" of the macro variables it worked.

This is apparently because when the global variables are initialized to empty strings, and the % operator dereferences first the concatenated strings to the variable name, but then it also further dereferences the newly created variable name to its current contents, i.e. an empty string. This left the compiler with a line containing only "TEXTEQU <var_value>", which caused the syntax error.

I have ran into problems on many occasions with this "all or nothing" dereferencing of macro variables, and it has caused me quite a lot trouble. :(

Isn't there any possible way whatsoever to only dereference a macro variable "one level" (or at least not all the levels)? You can think of it as a C pointer, and I only want to get the expression *macro_variable, and not **macro_variable.

Would this be possible in any way, however complicated?
Posted on 2003-01-15 18:18:56 by dELTA
dELTA,

I understand the problem and it may be impossible to solve with text equates.

Possible it may work with macro functions as in the following example:



MakeName macro string1, string2
exitm @CatStr(string1, string2)
endm

SET_GLOBAL_VARIABLE MACRO var_value
xxx textequ MakeName(<glob_var_>,%?index)
%xxx macro
exitm <var_value>
endm
ENDM

SET_INDEX macro index
?index = index
endm

.CODE

main proc c

xor eax, eax

SET_INDEX 1
SET_GLOBAL_VARIABLE <123>
SET_INDEX 2
SET_GLOBAL_VARIABLE <234>
SET_INDEX 3
SET_GLOBAL_VARIABLE <345>

add eax, glob_var_1()
add eax, glob_var_2()
add eax, glob_var_3()


.if (eax == (123 + 234 + 345))
invoke printf, CStr(<"worked",13,10>)
.endif


SET_INDEX 2
SET_GLOBAL_VARIABLE <1>
SET_INDEX 1
SET_GLOBAL_VARIABLE <2>

xor eax, eax
add eax, glob_var_1()
add eax, glob_var_2()
.if (eax == (1 + 2))
invoke printf, CStr(<"worked",13,10>)
.endif

ret

main endp



Ok, you have to add a "()" to your variables, but besides that it may work better

japheth
Posted on 2003-01-16 06:58:20 by japheth
Cool idea japheth, thanks! :)

I might still be out of luck though, since in my real problem I need to change the values of these global variables at several points, and even worse, the new values are based on the old values (like: glob_var_x CATSTR glob_var_x, <new_value>).

Does anybody have any cool idea about how to solve this too?
In that case, my current problems would be completely solved!
Posted on 2003-01-16 10:38:36 by dELTA
Hm, is that such an aggravation?



MakeName macro string1, string2
exitm @CatStr(string1, string2)
endm

SET_GLOBAL_VARIABLE MACRO var_value
xxx textequ MakeName(<glob_var_>,%?index)
%xxx macro
exitm <var_value>
endm
ENDM

CAT_GLOBAL_VARIABLE MACRO var_value
xxx textequ MakeName(<glob_var_>,%?index)
tmpVal equ xxx()
tmpVal2 textequ @CatStr(%tmpVal,var_value)
%xxx macro
exitm <tmpVal2>
endm
ENDM

SET_INDEX macro index
?index = index
endm

.CODE

main proc c

xor eax, eax

SET_INDEX 1
SET_GLOBAL_VARIABLE <123>
add eax, glob_var_1()

CAT_GLOBAL_VARIABLE <456>
add eax, glob_var_1()

CAT_GLOBAL_VARIABLE <789>
add eax, glob_var_1()


.if (eax == (123 + 123456 + 123456789))
invoke printf, CStr(<"worked",13,10>)
.endif


works!

No awaiting your next problem :) Or just tell us your problem in more detail.

Japheth
Posted on 2003-01-16 14:02:27 by japheth
I really didn't think that it was possible to redefine macros like that (with the same name as before), and that's why I thought it would be hard. Thanks for giving me another revelation anyway. ;)

And don't you worry, I'll be back with even more screwed-up problems for you to solve japheth. ;)

Thanks!
Posted on 2003-01-16 16:08:06 by dELTA