News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

MACRO Arrays?

Started by jj2007, May 16, 2008, 04:02:55 PM

Previous topic - Next topic

jj2007

I am trying to create an array within a macro. Getting values out works, but I have trouble finding an elegant way to get values into the array, see below. Any advice?
Thanks, jj

; array of numbers
AriM0 = 00
AriM1 = 10
AriM2 = 20
AriM3 = 30
AriM4 = 40

REPEAT 4
   gLev = gLev + 1
   CurM = @CatStr(AriM, %gLev)   ; get current arithmetic mode, WORKS
   CurM = CurM + 1 + 10*gLev
--->   AriM&gLev=CurM            ; set current ari mode, HOW??
   add esi, CurM
   invoke MessageBox, 0, str$(esi), chr$("Current mode is"), MB_OK
ENDM

Jimg

AriM0 = 00
AriM1 = 10
AriM2 = 20
AriM3 = 30
AriM4 = 40
gLev=0
mov esi,0
REPEAT 4
   CurM = @CatStr(AriM, %gLev)   ; get current arithmetic mode, WORKS
   CurM = CurM + 1 + 10*gLev
   @CatStr(AriM,%gLev) = CurM    ; set current ari mode, HOW??  **** like this *****
   add esi, CurM
   invoke MessageBox, 0, str$(esi), chr$("Current mode is"), MB_OK
   gLev = gLev + 1
ENDM
; test out changes
gLev=0
repeat 4
   CurM = @CatStr(AriM, %gLev)   ; get current arithmetic mode, WORKS
   mov esi,CurM
   invoke MessageBox, 0, str$(esi), chr$("Changed mode is"), MB_OK
   gLev = gLev + 1
ENDM


If I understood what you are trying to do, it would go like this---
mov esi,0
AriM0 = 00
AriM1 = 10
AriM2 = 20
AriM3 = 30
AriM4 = 40

glev = 0
CurM = AriM0
CurM = CurM + 1 + 10*gLev   ; = 1
AriM0 = 1

add esi,1   ; esi = 1
gLev = gLev + 1    ; = 1
CurM = AriM1  ; = 10
CurM = CurM + 1 + 10*gLev   ; = 21
AriM1 = 21
add esi,21   ; = 22

gLev = gLev + 1    ; = 2
CurM = AriM2  ; = 20
CurM = CurM + 1 + 10*gLev   ; = 41
AriM2 = 41
add esi,41   ; = 22 + 41 = 63

gLev = gLev + 1    ; = 3
CurM = AriM3  ; = 30
CurM = CurM + 1 + 10*gLev   ; = 30+1+30 = 61
AriM3 = 61
add esi,41   ; = 63+61=124



jj2007

Thanks, Jim, but what I intend to do is more ambitious: I want to pass a string to the macro, and return values depending on the values of each character. So I need a pseudo "array" during assembly - can't do that by hand, as it is not predictable...
As I showed above, I master one direction through string concatenation, i.e. instead of AriM(n) I produce AriMn

qWord

Hi,

is this what are you search for:


GetVarNameByValue macro Name:req,Value:req
EXITM <Name&Value>
endm

%Echo GetVarNameByValue(AriM,1)



edit:

or something like this:

SetAriMX MACRO index:req,value:req

sa_str TEXTEQU <AriM>,%(index)

sa_str = value

endm

GetAriMX MACRO index:req

ga_txt TEXTEQU %(@CatStr(<AriM>,%(index)))

exitm <ga_txt>
endm

MovAriMX MACRO iDest:req,iSrc:req

ma_txt TEXTEQU %(@CatStr(<AriM>,%(iSrc)))
@CatStr(<AriM>,%(iDest)) = ma_txt

endm


SetAriMX 0,500
MovAriMX 1,0
%echo == GetAriMX(1)
FPU in a trice: SmplMath
It's that simple!

jj2007

Thanks, qWord and Jim. We are definitely getting closer. Here is a full example:

.nolist
include \masm32\include\masm32rt.inc

; the array is global:
MyArray0 = 00
MyArray1 = 10
MyArray2 = 20
MyArray3 = 30
MyArray4 = 40
MyArray5 = 50
MyArray6 = 60
MyArray7 = 70

ArrayMac MACRO arg:REQ
LOCAL ct, CurVal, NewVal
ct = 0
WHILE ct lt @SizeStr(arg)
ct = ct + 1
cc = @SubStr(arg, ct, 1) ; get a number from the passed argument, e.g. 3
CurVal = @CatStr(MyArray, %cc) ; get the corresponding number from the array, e.g. 30
tmp CATSTR <MyArray>, %ct-1 ; define the name of the array element, e.g. MyArray3
tmp=CurVal+99 ; add 99 to the 30 and put the result into MyArray3
ENDM

ct=0

REPEAT 8
NewVal = @CatStr(MyArray, %ct) ; define the name of the array element, e.g. MyArray3
invoke MessageBox, 0, str$(NewVal), cat$(chr$("Test "), str$(ct)), MB_OK ; and show its value
ct = ct + 1
ENDM
ENDM

.code
start:

ArrayMac 31504323415 ; first round
ArrayMac 31504323415 ; second round

exit
end start

qWord

what about this:


.nolist
include \masm32\include\masm32rt.inc

; the array is global:
MyArray0 = 00
MyArray1 = 10
MyArray2 = 20
MyArray3 = 30
MyArray4 = 40
MyArray5 = 50
MyArray6 = 60
MyArray7 = 70


.code
start:

ArrayMac macro arg:req
LOCAL ct, NewVal
ct = 0

FORC num,<arg>
MyArray&num& = MyArray&num& + 99
ENDM
ct=0
REPEAT 8
NewVal = @CatStr(MyArray, %ct) ; define the name of the array element, e.g. MyArray3
invoke MessageBox, 0, str$(NewVal), cat$(chr$("Test "), str$(ct)), MB_OK ; and show its value
ct = ct + 1
ENDM

endm

ArrayMac 31504323415

exit
end start


qWord
FPU in a trice: SmplMath
It's that simple!

jj2007

Yes, your code works like a charm. But what am I doing wrong in my adaptation?? I tried all kinds of combinations of <>, % , & etc but no success... it escapes my logic...


ArrayMac MACRO arg:REQ
LOCAL ct, CurVal, NewVal
   ct = 0
    WHILE ct lt @SizeStr(arg)
      ct = ct + 1
      if 0   ; THIS BRANCH WORKS
         cc = @SubStr(arg, ct, 1)         ; get a number from the passed argument, e.g. 3
         CurVal = @CatStr(MyArray, %cc)   ; get the corresponding number from the array, e.g. 30
         tmp CATSTR <MyArray>, %ct-1   ; define the name of the array element, e.g. MyArray3
         tmp=CurVal+99               ; add 99 to the 30 and put the result into MyArray3
      else
         cc SUBSTR arg, ct, 1            ; no chance with either version
         ; cc = @SubStr(arg, ct, 1)
         MyArray&cc& = MyArray&cc& + 99      ; why the heck does this give an error??
      endif
   ENDM

   ct=0
   REPEAT 1
      NewVal = @CatStr(MyArray, %ct)      ; define the name of the array element, e.g. MyArray3
      invoke MessageBox, 0, str$(NewVal), cat$(chr$("Test "), str$(ct)), MB_OK   ; and show its value
      ct = ct + 1
   ENDM
ENDM

qWord

Here are some information out of the "MASM Programmer's Guide":

Quote
&    Substitution Operator:

Tells the assembler to replace a macro parameter or text macro name with its
actual value.


....

You can also use the substitution operator in lines beginning with the expansion operator (%) symbol, even outside macros (see page 236). It may be necessary to use the substitution operator to paste text macro names to adjacent characters or symbol names, as shown here:

text    TEXTEQU <var>
value   TEXTEQU %5
%       ECHO    textvalue is text&&value


this works:
  %   MyArray&cc& = MyArray&cc& + 99
FPU in a trice: SmplMath
It's that simple!