News:

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

Expanding Macros

Started by savage, June 04, 2006, 06:39:44 PM

Previous topic - Next topic

savage

Okay, I think I have it working, I really liked your first version better so I'm using that, but I can't figure out how to make things like (2+2) reduce to 4, because I don't want my variable named "const_2+2" for example

Ossa

Quote from: savage on June 05, 2006, 03:31:56 PM
Okay, I think I have it working, I really liked your first version better so I'm using that, but I can't figure out how to make things like (2+2) reduce to 4, because I don't want my variable named "const_2+2" for example

"% is your friend"  :bg

Once again from the MASM Programmer's Guide (I quoted the next section last time we talked about macros - here):

QuoteConverting Numeric Expressions to Text

The expansion operator can convert numbers to text. The operator forces immediate evaluation of a constant expression and replaces it with a text value consisting of the digits of the result. The digits are generated in the current radix (default decimal).

This application of the expansion operator is useful when defining a text macro, as the following lines show. Notice how you can enclose expressions with parentheses to make them more readable:

a       TEXTEQU <3 + 4>         ; a = "3 + 4"
c       TEXTEQU %(3 + 4)        ; c = "7"


When assigning text macros, you can use numeric equates in the constant expressions, but not text macros:
 
num     EQU     4               ; num = 4
numstr  TEXTEQU <4>             ; numstr = <4>
a       TEXTEQU %3 + num        ; a = <7>
b       TEXTEQU %3 + numstr     ; b = <7>

 
The expansion operator gives you flexibility when passing arguments to macros. It lets you pass a computed value rather than the literal text of an expression. The following example illustrates by defining a macro

work    MACRO   arg
    mov ax, arg * 4
ENDM

 
which accepts different arguments:
 
        work    2 + 3           ; Passes "2 + 3"
                                ; Code: mov ax, 2 + (3 * 4)
        work    %2 + 3          ; Passes 5
                                ; Code: mov ax, 5 * 4
        work    2 + num         ; Passes "2 + num"
        work    %2 + num        ; Passes "6"
        work    2 + numstr      ; Passes "2 + numstr"
        work    %2 + numstr     ; Passes "6"

 
You must consider operator precedence when using the expansion operator. Parentheses inside the macro can force evaluation in a desired order:
 
work    MACRO   arg
    mov ax, (arg) * 4
ENDM

        work    2 + 3           ; Code: mov ax, (2 + 3) * 4
        work    %2 + 3          ; Code: mov ax, (5) * 4

 
Several other uses for the expansion operator are reviewed in "Returning Values with Macro Functions," later in this chapter.

So if all else fails, a dummy string at the start that uses the expansion operator on the passed string would do it.

Ossa
Website (very old): ossa.the-wot.co.uk

savage

Okay, exactly whatI think I was looking for, thanks Ossa.
So the dummy string is used along with % in order to reduce expressions. 
:dance:

Gotcha.

Thanks again for being so quick.

jj2007

Quote from: Ratch on June 05, 2006, 02:02:06 AM
     If you code the MASM directive .LISTMACROALL at the beginning of your source code, the calling sequence of nested MACROS, and the variables within will be printed in the listing.  Ratch

Could it be .listall? It yields some more expansion code than .listmacroall, although it is still far from satisfactory. I am also looking for more transparency on my macros...