The MASM Forum Archive 2004 to 2012

General Forums => The Laboratory => Topic started by: jj2007 on September 01, 2008, 09:35:48 AM

Title: Line continuation when calling macros
Post by: jj2007 on September 01, 2008, 09:35:48 AM
For sure some will think what I am doing is nonsense, but just out of curiosity: Why does line continuation not work properly when calling macros?

I am tinkering with the float$ macro (http://www.masm32.com/board/index.php?topic=9756.0), and with some effort one can arrive at the allowed 260 characters in a line:
   mov eax, 12345678
   print float$("\n------- New float$ macro: ---------------------\nDivide\tMyReal10\t(=1.2345678e9)\nby\t12345678\t(=1.2e7, in eax)\nadd\t 11.1111   \t(an immediate real)\nResult=\t%f\n-- This para printed by one line of code! -----\n\n", MyReal10/eax+011.1111)

------- New float$ macro: ----------------------
Divide  MyReal10        (=1.2345678e9)
by      12345678        (=1.2e7, in eax)
add      11.1111        (an immediate real)
Result= 111.1111
-- This para printed by one line of code! -----


Splitting the line with backslash as last character yields error A2041: string or text literal too long

   print float$("\n------- New float$ macro: ----------------------\
   \nDivide ...

Is there a logic behind this behaviour? Is there any workaround...?  ::)
Title: Re: Line continuation when calling macros
Post by: Jimg on September 01, 2008, 02:39:34 PM
try this-

   print float$("\n------- New float$ macro: ---------------------\
   \nDivide\tMyReal10\t(=1.2345678e9)\nby\t12345678\t(=1.2e7, in eax)\nadd\t 11.1111   \
   \t(an immediate real)\nResult=\t%f\n-- This para printed by one line of code! -----\n\n",\
    MyReal10/eax+011.1111)
Title: Re: Line continuation when calling macros
Post by: jj2007 on September 01, 2008, 03:34:46 PM
Interesting - it works! But why? Apparently, the comma separating the string from the second argument must have a backslash to work properly. This also works:

   print float$("\n------- New float$ macro: ---------------------\
   \nDivide\tMyReal10\t(=1.2345678e9)\nby\t12345678\
   \t(=1.2e7, in eax)\nadd\t 11.1111   \
   \t(an immediate real)\nResult=\t%f\
   \n-- This para printed by one line of code! -----\n\n",\
   MyReal10/eax+011.1111)

If you are aware of any written rule, please let me know.
Title: Re: Line continuation when calling macros
Post by: Jimg on September 01, 2008, 04:01:26 PM
No, no rule.  You have just exceeded the complexity capabilities of masm, and need to give it a little more direction some times.  This seems especially true when calling a macro as a function with the arguments enclosed with parens.
Title: Re: Line continuation when calling macros
Post by: jj2007 on September 01, 2008, 04:17:21 PM
Quote from: Jimg on September 01, 2008, 04:01:26 PM
No, no rule.  You have just exceeded the complexity capabilities of masm, and need to give it a little more direction some times.  This seems especially true when calling a macro as a function with the arguments enclosed with parens.

The macro capabilities are indeed extremely powerful, but the documentation is somewhat scarce. Yesterday I had a problem with redefinitions of string variables:

--- This fails miserably: ---
  aPass2 equ <0>
  aPass3 equ <0>
  if AriMode
   aSize2 = ChkNum(arg2a)
   % aPass2 equ <aPass$>
   tmp$ CATSTR <Pass2:  >, aPass2, <, size >, %NumSize
   % echo tmp$
   if AriMode ge 256
      aSize3 = ChkNum(arg3a)
      % aPass3 equ <aPass$>
      tmp$ CATSTR <Pass3:  >, <aPass3>, <, size >, %NumSize
      % echo tmp$
   endif
  endif

--- This works perfectly: ---

  if AriMode
   aSize2 = ChkNum(arg2a)
   % aPass2 equ <aPass$>
   tmp$ CATSTR <Pass2:  >, aPass2, <, size >, %NumSize
   % echo tmp$
   if AriMode ge 256
      aSize3 = ChkNum(arg3a)
      % aPass3 equ <aPass$>
      tmp$ CATSTR <Pass3:  >, <aPass3>, <, size >, %NumSize
      % echo tmp$
   else
      aPass3 equ <0>
   endif
  else
   aPass2 equ <0>
   aPass3 equ <0>
  endif

... which is compatible with the documentation saying you cannot redefine a string. However, in many instances you can perfectly redefine a string inside a macro...! It's a lot of trial and error :bg
Title: Re: Line continuation when calling macros
Post by: Jimg on September 01, 2008, 04:30:23 PM
I have usually found that you can generally redefine a variable defined with equ until it get an actual numeric value, at which point, it can't be redefined again.  But this is by trial an error, there is nothing in the documentation I can find, and it's not 100%.
Title: Re: Line continuation when calling macros
Post by: MichaelW on September 01, 2008, 06:02:42 PM
The information is in the documentation, just not where I would expect it to be. From the MASM 6.0 Programmer's Guide, in Chapter 1 under Language Components of MASM, Symbolic Integer Constants:

Quote
The difference between EQU and = is that integers defined with the = directive can be changed in your source code, but those defined with EQU cannot. Once a symbolic integer constant has been defined with the EQU directive, attempting to redefine it generates an error.

And a slightly different, and less clear, statement from the 6.11 guide:

Quote
The directives EQU and = have slightly different purposes. Integers defined with the = directive can be redefined with another value in your source code, but those defined with EQU cannot. Once you've defined a symbolic constant with the EQU directive, attempting to redefine it generates an error.
Title: Re: Line continuation when calling macros
Post by: jj2007 on September 01, 2008, 08:22:26 PM
Quote from: MichaelW on September 01, 2008, 06:02:42 PM
Once a symbolic integer constant has been defined with the EQU directive, attempting to redefine it generates an error.

Thanks, Michael. I will test whether assigning MyVar equ <NULL> is a workaround...
EDIT:

This works:
ChkNum MACRO argX:REQ
  MacTest equ <1>               ;; first assignment is a string
  MacTest equ 0               ;; several times redefined, no problem...!
  MacTest equ 2               ;; several times redefined, no problem...!
  MacTest equ <3>               ;; several times redefined, no problem...!
  % echo MacTest
  .err
ENDM

This doesn't:
ChkNum MACRO argX:REQ
  MacTest equ 0               ;; first assignment is numeric
  MacTest equ <1>               ;; bang in the face...
  % echo MacTest
  .err
ENDM
Title: Re: Line continuation when calling macros
Post by: BlackVortex on September 01, 2008, 10:37:53 PM
Guys, if you haven't already, test these with jwasm as well. Masm may not be improved since the 6 series, but there's a new tool to take over.



Yes, I am a jwasm fanboy, don't tease me plz.
Title: Re: Line continuation when calling macros
Post by: Jimg on September 01, 2008, 11:33:45 PM
and apparently, it doesn't have to be an angle bracket delimited text, any text will do.  This works

aasx equ .
aasx equ 3
aasx equ 5


Title: Re: Line continuation when calling macros
Post by: jj2007 on September 02, 2008, 08:36:16 AM
Quote from: Jimg on September 01, 2008, 11:33:45 PM
and apparently, it doesn't have to be an angle bracket delimited text, any text will do.  This works

aasx equ .
aasx equ 3
aasx equ 5


I am afraid it's even more tricky:

include \masm32\include\masm32rt.inc

mt MACRO
; LOCAL c$, assx
c$ equ xx
aasx equ zz

c$ CATSTR c$, aasx
% echo FIRST c$
echo

aasx equ aa
c$ CATSTR c$, assx
% echo SECOND c$

.err
ENDM

.data
AppName db "Macro test", 0

.code

start: mt

end start


Output:

FIRST xxzz

tmp_file.asm(25) : error A2006: undefined symbol : assx
mt(10): Macro Called From
  tmp_file.asm(25): Main Line Code
SECOND xxzz
tmp_file.asm(24) : error A2052: forced error
mt(13): Macro Called From
  tmp_file.asm(24): Main Line Code


No complaints until the moment you want to use assx in the CATSTR...
Title: Re: Line continuation when calling macros
Post by: jj2007 on September 02, 2008, 09:00:25 AM
Now it gets weird. This assembles fine, but watch what the MsgBox displays...

EDIT: workaround added, try it out to see the difference.


include \masm32\include\masm32rt.inc

mt MACRO
LOCAL c1$, assx

workaround = 0 ; replace with 1 to see a working example

aasx equ <Str1>
if workaround
% c1$ CATSTR <addr >, <aasx>
else
c1$ CATSTR <addr >, <aasx>
endif
% echo c1$
print chr$(13,10,"The text:",9)
print c1$

aasx equ <Str2>
if workaround
% c2$ CATSTR <addr >, <aasx>
else
c2$ CATSTR <addr >, <aasx>
endif
% echo c2$
print chr$(13,10,"The title:",9)
print c2$

aasx equ <Nirwana>

ec$ CATSTR <MessageBox, 0, >, c1$, <, >, c2$, <, MB_OK>
% echo ec$

invoke MessageBox, 0, c1$, c2$, MB_OK
echo
echo
echo

; .err ; uncomment to see macro output

ENDM

.data
AppName db "Macro test", 0
Str1 db "This is the text", 0
Str2 db "This is the TITLE", 0
Nirwana db "That's not how it should be!", 0

.code

start: mt
exit

end start
Title: Re: Line continuation when calling macros
Post by: Jimg on September 02, 2008, 01:32:48 PM
Regarding your first example, perhaps you didn't notice you misspelled assx aasx?
Title: Re: Line continuation when calling macros
Post by: jj2007 on September 02, 2008, 01:45:13 PM
Quote from: Jimg on September 02, 2008, 01:32:48 PM
Regarding your first example, perhaps you didn't notice you misspelled assx aasx?
Oops :red
But the second "workaround" example remains valid.
Title: Re: Line continuation when calling macros
Post by: Mark Jones on September 02, 2008, 02:30:50 PM
Lol, you guys are making a virtual pandora's box for poor Japeth. :lol
Title: Re: Line continuation when calling macros
Post by: jj2007 on September 02, 2008, 02:57:20 PM
Quote from: Mark Jones on September 02, 2008, 02:30:50 PM
Lol, you guys are making a virtual pandora's box for poor Japeth. :lol
You haven't seen my really complex macros. But JWasm handles them without problems :cheekygreen: