News:

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

Line continuation when calling macros

Started by jj2007, September 01, 2008, 09:35:48 AM

Previous topic - Next topic

jj2007

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, 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...?  ::)

Jimg

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)

jj2007

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.

Jimg

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.

jj2007

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

Jimg

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%.

MichaelW

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.
eschew obfuscation

jj2007

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

BlackVortex

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.

Jimg

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



jj2007

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...

jj2007

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

Jimg

Regarding your first example, perhaps you didn't notice you misspelled assx aasx?

jj2007

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.

Mark Jones

Lol, you guys are making a virtual pandora's box for poor Japeth. :lol
"To deny our impulses... foolish; to revel in them, chaos." MCJ 2003.08