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...? ::)
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)
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.
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.
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
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%.
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.
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
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.
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
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...
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
Regarding your first example, perhaps you didn't notice you misspelled assx aasx?
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.
Lol, you guys are making a virtual pandora's box for poor Japeth. :lol
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: