### Author Topic: Macro goto problem  (Read 1366 times)

#### jimg

• Member
• Posts: 409
##### Macro goto problem
« on: January 20, 2019, 10:08:06 AM »
When I try the following code-

Code: [Select]
`.686.model Flat, Stdcalloption Casemap :None    .codetestxa macro ThingsToTest:VARARG    for arg,<ThingsToTest>        forc nnx,<&arg>  ;; get first character         ifidni <&nnx>,</>   ;; check for line feeds             crcnt=0             dxflg = 6             forc slashx,<&arg>                 ifidn <&slashx>,</>                     crcnt = crcnt + 1                 endif             endm             mov dl,crcnt             goto Doit         endif         ifidni <&nnx>,<.>   ;; check for spaces             crcnt=0             forc slashx,<&arg>                 ifidn <&slashx>,<.>                     crcnt = crcnt + 1                 endif             endm             mov eax,crcnt             goto Doit         endif         exitm  ; only want to test first character    endm    ; do a whole bunch of other stuff here          :Doit        ; do more stuff here    endmendmprogram:    testxa .,d ecx,":",d eax,...,"test 3 < 4 ",///             retend program`
I get the error- Error A2267: Macro label not defined: Doit

if I comment out the outer loop, it assembles without error.

I couldn't find anything saying it was illegal to nest for loops, it that a restriction?

#### johnsa

• Member
• Posts: 799
##### Re: Macro goto problem
« Reply #1 on: January 21, 2019, 04:14:36 AM »
Hi,

Have you tried the same macro in ML and ASMC to see how it responds ?
(Useful to know if it's a common issue or UASM specific).

Thanks!
John

#### jj2007

• Member
• Posts: 10020
• Assembler is fun ;-)
##### Re: Macro goto problem
« Reply #2 on: January 21, 2019, 05:24:00 AM »
It throws additional errors in various MASM versions (6.15 .. 10.0). Can you explain what you want to achieve?
testxa .,d ecx,":",d eax,...,"test 3 < 4 ",///

• Regular Member
• Posts: 46
##### Re: Macro goto problem
« Reply #3 on: January 21, 2019, 07:17:21 AM »
Common macro problem, it can't know the Label because it's declared after statement.

Not tested but I think it will work.

Code: [Select]
`.686.model Flat, Stdcalloption Casemap :None    .codetestxa macro ThingsToTest:VARARG    local Doit    for arg,<ThingsToTest>        forc nnx,<&arg>  ;; get first character         ifidni <&nnx>,</>   ;; check for line feeds             crcnt=0             dxflg = 6             forc slashx,<&arg>                 ifidn <&slashx>,</>                     crcnt = crcnt + 1                 endif             endm             mov dl,crcnt             goto Doit         endif         ifidni <&nnx>,<.>   ;; check for spaces             crcnt=0             forc slashx,<&arg>                 ifidn <&slashx>,<.>                     crcnt = crcnt + 1                 endif             endm             mov eax,crcnt             goto Doit         endif         exitm  ; only want to test first character    endm    ; do a whole bunch of other stuff here          :Doit        ; do more stuff here    endmendmprogram:    testxa .,d ecx,":",d eax,...,"test 3 < 4 ",///             retend program`

#### HSE

• Member
• Posts: 1217
• <AMD>< 7-32>
##### Re: Macro goto problem
« Reply #4 on: January 21, 2019, 08:41:47 AM »
There is a label inside a loop, and that means redefinition.
Code: [Select]
`.686.model Flat, Stdcalloption Casemap :None    .codetstxa macro ThingsToTst:VARARG    cnt = 0    FOR arg,<ThingsToTst>        forc nnx,<&arg>  ;; get first character         ifidni <&nnx>,</>   ;; check for line feeds             crcnt=0             dxflg = 6             forc slashx,<&arg>                 ifidn <&slashx>,</>                     crcnt = crcnt + 1                 endif             endm             mov dl,crcnt %           goto @CatStr(Doit, %cnt)         endif         ifidni <&nnx>,<.>   ;; check for spaces             crcnt=0             forc slashx,<&arg>                 ifidn <&slashx>,<.>                     crcnt = crcnt + 1                 endif             endm             mov eax,crcnt %            goto @CatStr(Doit, %cnt)         endif         exitm <> ; only want to test first character    endm    ;; do a whole bunch of other stuff here        %  @CatStr(Doit,%cnt,<:>)        ;; do more stuff here        cnt = cnt+1    ENDMendmprogram:    tstxa  a,b ; .,d ecx,":",d eax,...,"test 3 < 4 ",///             retend program`
NOTE: I have not a clue what you are trying to do.

#### jimg

• Member
• Posts: 409
##### Re: Macro goto problem
« Reply #5 on: January 21, 2019, 10:06:18 AM »
I will try to respond to each one of you, bear with me, for some reason I've been having a hard time making myself understood lately-

Johnsa-
There are so many things broken in Masm that are done right in UAsm that I've stopped trying to make them compatible.  Yes, it throws an error in Masm also, but I couldn't see any reason for it, so I thought I'd ask here if it seemed like a reasonable thing to do.

JJ-
This is part of my printing macros.  Primitive compared to MasmBasic, but I've been using and improving them for about 15 years.  The cryptic string is just directives to Printx.

I've never had this problem before.  So far I've only seen it occur when in a nested loop.

HSE-
I didn't know that a loop would have local labels, variables, etc.   It seems like a rather restrictive requirement.

To everyone-
I have come to expect UAsm to be a better Masm.   I always hope for the best.
« Last Edit: January 21, 2019, 11:07:03 AM by jimg »

#### johnsa

• Member
• Posts: 799
##### Re: Macro goto problem
« Reply #6 on: January 21, 2019, 10:14:53 PM »
My immediate guess (without looking) is that the macro label isn't stored during the evaluation of a for loop, only upon completion which is why it's not available.
My suggestion would be to perhaps rather than using a label expand out the cases into calls to different macros, the sort of usual HLL response you'd get from anyone who saw you using a GOTO :)

#### jimg

• Member
• Posts: 409
##### Re: Macro goto problem
« Reply #7 on: January 22, 2019, 01:03:50 AM »
Thanks John, I've already found a simple work around.   The goto only fails in a nested loop, it works fine in an un-nested loop.   I thought this might be indicative of a deeper problem that should be addressed.
I really like UAsm, keep up the good work!

#### BugCatcher

• Member
• Posts: 56
##### Re: Macro goto problem
« Reply #8 on: January 22, 2019, 01:21:35 AM »
I haven't used goto since my basic days 30yrs ago. So does "goto" go to a label with the colon on the left side? :Doit instead of right side Doit:?

#### johnsa

• Member
• Posts: 799
##### Re: Macro goto problem
« Reply #9 on: January 22, 2019, 03:32:58 AM »
For macro labels yes, regular asm labels have the colon at the end, or if you're using scoped local labels then a :: at the end to put the label into global scope.

#### hutch--

• Member
• Posts: 6948
• Mnemonic Driven API Grinder
##### Re: Macro goto problem
« Reply #10 on: January 22, 2019, 11:53:44 AM »
I would not lose too much sleep over macro behaviour, the ancient pre-processor in MASM has all sorts of undocumented quirks. The various loop techniques do not always allow external macro instructions. Macros in MASM and compatible are closer to "Black Magic" than science.
hutch at movsd dot com
http://www.masm32.com

#### jimg

• Member
• Posts: 409
##### Re: Macro goto problem
« Reply #11 on: January 22, 2019, 01:31:03 PM »
Wouldn't it be wonderful to fix all that :)

#### johnsa

• Member
• Posts: 799
##### Re: Macro goto problem
« Reply #12 on: January 22, 2019, 08:16:22 PM »
The only real way to achieve it would be to create a totally new asl / macro language to use, perhaps as a command line switchable option..
-masmMacro vs -newMacro

with a more rigorous and structured syntax that can be properly parsed.
The way macros work is all a bit sketchy, it's always been a 98% type of solution.

#### jj2007

• Member
• Posts: 10020
• Assembler is fun ;-)
##### Re: Macro goto problem
« Reply #13 on: January 22, 2019, 08:36:39 PM »
Found the solution, it wasn't actually that difficult...

Code: [Select]
`include \masm32\include\masm32rt.inc.codetestxa macro ThingsToTest:VARARG    for arg,<ThingsToTest>        forc nnx,<&arg>  ;; get first character         ifidni <&nnx>,</>   ;; check for line feeds             crcnt=0             dxflg = 6             forc slashx,<&arg>                 ifidn <&slashx>,</>                     crcnt = crcnt + 1                 endif             endm             mov dl,crcnt             goto Doit         endif         ifidni <&nnx>,<.>   ;; check for spaces             crcnt=0             forc slashx,<&arg>                 ifidn <&slashx>,<.>                     crcnt = crcnt + 1                 endif             endm             mov eax,crcnt             goto Doit         endif :Doit tmp\$ CATSTR <found [>, <nnx>, <]> % echo tmp\$ exitm  ; only want to test first character    endm    ; do a whole bunch of other stuff here            ; do more stuff here    endmendmprogram:  if 1    testxa .,d ecx,":",d eax,...,"test 3 < 4 ",///       ; works only with UAsm    else    testxa .,d ecx,":",d eax,...,"test 3 lt 4 ",///       ; works with UAsm and ML 6.14+           endif    retend program`