News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

for the macro-monsters

Started by HSE, June 16, 2016, 09:18:45 AM

Previous topic - Next topic

HSE

I'm using a simple macro (I simplified a little more here) to declare related variables:

   estado macro name:REQ
        a&name  REAL8 0.0
        b&name  REAL8 0.0
        c&name  REAL8 0.0
   endm


The appplication:

    estado  prot
    estado  fat

The result:

        aprot  REAL8 0.0
        bprot  REAL8 0.0
        cprot  REAL8 0.0
        afat  REAL8 0.0
        bfat  REAL8 0.0
        cfat  REAL8 0.0


The question: It's posible, for a large number of names (60 for example), to obtein:

        aprot  REAL8 0.0
        afat     REAL8 0.0
        bprot  REAL8 0.0
        bfat    REAL8 0.0
        cprot  REAL8 0.0
        cfat    REAL8 0.0


Thanks in advance. HSE
Equations in Assembly: SmplMath

jj2007

It is, it is...include \masm32\include\masm32rt.inc

makevars MACRO varcount
Local ct, tmp$
.data
  ct=0
  repeat varcount
tmp$ CATSTR <prot>, %ct, < REAL8 >, %ct, <.0>
% echo tmp$
  tmp$
tmp$ CATSTR <fat>, %ct, < REAL8 0.0>
% echo tmp$
  tmp$
  ct=ct+1
  ENDM
  .code
ENDM

.code
start:
makevars 60
fld prot40
fld fat59
exit

end start

HSE

Thanks JJ!

I don't explain enough, I think.

1. large number of "name" : prot, fat, water, Ac, Fa, Bu, ...
                     
                     (very large for  using VARARG in a nice code)

2. need to be: a+name, b+name, c+name. Not 1+name, name+1, name+a

   
Equations in Assembly: SmplMath

jj2007

The CATSTR part shows how to do it, the % echo shows the actual name while assembling. But in any case, this looks more like a candidate for a structure, or an array of structures:

include \masm32\MasmBasic\MasmBasic.inc      ; download
FOOD STRUCT
  prot    REAL8 ?
  fat     REAL8 ?
  water   REAL8 ?
  Ac      REAL8 ?
  Fa      REAL8 ?
  Bu      REAL8 ?
FOOD ENDS

  Init
  Dim MyFood() As FOOD
  fldpi                  ; get a real number
  fstp MyFood(0, water)
  Print Str$("Food 0/water=%f", MyFood(0, water))
EndOfCode

rrr314159

Structure seems like a good idea but actually it seems HSE wants this:

abc STRUCT
    a REAL8 ?
    b REAL8 ?
    b REAL8 ?
abc ENDS

Then instantiate prot, fat etc as that struct, and use prot.a, fat.b etc instead of aprot, afat etc.

An array of struct's might be a good idea, matter of style I guess.

As for the original problem: I think that's a bug. Macros can do stuff like that when you push them. In fact, HSE, you found another case like that last year. But note, all your variables are getting defined correctly, just in the wrong order. Instead of all prot's followed by all fat's, it's all a's followed by all b's, and so forth. Code still works.

Finally, the point of jj's first post is to use a CATSTR to make sure the order is the way you want it - if you go with that technique. But note, in that case it might screw up because there's a limit on size of the concatenated string.
I am NaN ;)

qWord

estado macro names:VARARG
FOR name,<names>
a&name REAL8 0.0
b&name REAL8 0.0
c&name REAL8 0.0
ENDM
endm
?

Quote from: rrr314159 on June 16, 2016, 06:55:37 PM
As for the original problem: I think that's a bug. Macros can do stuff like that when you push them. In fact, HSE, you found another case like that last year.
What exactly is a bug? What was the other case?

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

rrr314159

A bug, in this case, is unexpected behavior that arises sometimes when you use too many macros, or push them too far; you might say, "get too clever". HSE, last year, had too many nested macros; no doubt he can reference the thread if you're interested. One unexpected factor was that EXITM constituted a "nested macro".

If you want other examples, I'd have to go through my notes. I remember one happened using HLL statements with two terms "and"-ed together, in a complex series of .if statements. Fixed by putting them in two separate .if statements. Verified by debugging: the emitted code was wrong. I think it amounted to an obviously missing jump. But really don't remember the (maybe half dozen) cases well. One just works around it, and forgets about it.

You (or hutch) might say "it's not a bug, you just don't understand the beast well enough." Probably true in some cases, but not all.

Consider the present OP where HSE's declarations are, apparently, being emitted in the wrong order if called 60 times, as he says. That's an excellent example. Even if there's some reason - "it's not a bug, it's a feature" - it sure feels like a bug when you run into it.
I am NaN ;)

HSE

Thanks very much!

The entire example is in http://masm32.com/board/index.php?topic=5244.0 , but with the real code perhaps is dificult to see the subject.

Very clever JJ, that variables are inside an structure, an Object in this case.

In the way I define variables I obtein an array. The access to array demand calculation:

        firstinitial textequ iprot
        ForLp v1, 0 , topebucle
mov ebx , v1
mov eax , v1
mov ecx , 3
mul ecx
f2f  [esi].integrales[ebx*8], [esi].modelo.firstinitial[eax*8]
Next v1

If the variables are sorted is more simple to access this variables.

In a tipical run this type of code is called 1.2e3 times and optimization don't pay, but perhaps I need to run 1.2e9 or more for some problems. For more complicated problems writing by hand perhaps pay, even losing readability, that it's a must here (or should be).

What you mention qWord, for my purpose could be:

estado macro names:VARARG
FOR name,<names>
a&name REAL8 0.0
ENDM
FOR name,<names>
b&name REAL8 0.0
ENDM
FOR name,<names>
c&name REAL8 0.0
ENDM
endm


It's the option. I don't know if there is a limit for VARARG. And I don't have the posibilty of charge values:
estado macro name:REQ, value1
        a&name  REAL8 &value1
        b&name  REAL8 0.0
        c&name  REAL8 0.0
   endm


Perhaps you are rigth rrr, and the problem is a bug, that is the question! I think I saw a macro with specific location of variables, but could be a dream (or a very real bad interpretation). I don't know what case you remember, there is so many :biggrin:. Very nice of You remember only one!

I see there is new post at the same time.
Equations in Assembly: SmplMath

HSE

It's a good warning rrr!

Allowing most level macros in the compiler solved last year problem and works perfect, of course you lost more time in the case of errors, recurrency, etc. Perhaps need the leyend "Don't use for aeronautic controls, live support systems and... " (is something like that)

I don't remember the ".if" thing, perhaps never work.

In this case the variables are emited in the expected order, just I want a diferent order (with the same code!).

Thanks for your opinion!

Equations in Assembly: SmplMath

qWord

Quote from: rrr314159 on June 17, 2016, 01:15:45 AM
A bug, in this case, is unexpected behavior that arises sometimes when you use too many macros, or push them too far; you might say, "get too clever". HSE, last year, had too many nested macros; no doubt he can reference the thread if you're interested. One unexpected factor was that EXITM constituted a "nested macro".
It's not a bug, you just don't understand the beast well enough ;-D
Anyway, you are right: too much macros can overcomplicate the problem.

Quote from: rrr314159 on June 17, 2016, 01:15:45 AMI remember one happened using HLL statements with two terms "and"-ed together, in a complex series of .if statements. Fixed by putting them in two separate .if statements. Verified by debugging: the emitted code was wrong.
Could be possible, however, these are MASM statements and not macros (should be strictly separated IMO).

Quote from: rrr314159 on June 17, 2016, 01:15:45 AM
Consider the present OP where HSE's declarations are, apparently, being emitted in the wrong order if called 60 times, as he says. That's an excellent example. Even if there's some reason - "it's not a bug, it's a feature" - it sure feels like a bug when you run into it.
hard to say, because (at least for me) it not so clear what he want to do.
MREAL macros - when you need floating point arithmetic while assembling!

qWord

Quote from: HSE on June 17, 2016, 02:01:22 AM
Allowing most level macros in the compiler solved that problem
You problem can't express iterative? I've doubts on that.
MREAL macros - when you need floating point arithmetic while assembling!

HSE

qWord;

Was not clear, my fault. Last year problem, that rrr remember pretty well, was that compilers don't allow the number of macro levels when using SmplMath with ObjAsm32. For that thing, I use HJWasm modified with more macro levels. Very simple, not errors.  (and not related with the question)

Equations in Assembly: SmplMath

jj2007

Quote from: HSE on June 17, 2016, 01:20:28 AM
In the way I define variables I obtein an array. The access to array demand calculation:

Here a plain Masm32 example. Note the imul instruction. With opattr, you could determine if index is a register or memory variable, to produce even more efficient code (this example stolen from the MasmBasic Dim macro ;))
include \masm32\include\masm32rt.inc

FOOD STRUCT
  prot    REAL8 ?
  fat     REAL8 ?
  water   REAL8 ?
  Ac      REAL8 ?
  Fa      REAL8 ?
  Bu      REAL8 ?
FOOD ENDS

MyFood MACRO index, element
  mov eax, index
  imul eax, eax, FOOD
  exitm <myfood.&element[eax]>
ENDM

.data?
myfood FOOD 20 dup(<>)

.code
start:
  fld1 ; get a real number, 1 in this case
  fstp MyFood(4, fat) ; store it as element 4, fat
  fldpi ; get a real number
  fstp MyFood(2, water) ; store it
  printf("Food(2, water)=\t%f\n", MyFood(2, water))
  printf("Food(4, fat)=\t%f\n", MyFood(4, fat))
  exit
end start

HSE

Thanks JJ!

That will be usefull in a future step.

Meanwhile your program give me the idea to improve the access:

mov ecx,topebucle
iniloop1:
imul eax , ecx, 3
f2f [esi].integrales[ecx*8],[esi].modelo.firstinitial[eax*8]
dec ecx
jnl iniloop1
Equations in Assembly: SmplMath