9.3.3 Substitution Operator (&)

In MASM 6.0, the substitution operator (&) enables substitution of macro parameters, even when the parameter occurs within a larger word or within a quoted string. It can also be used to concatenate two macro parameters after they have been expanded.

The syntax for the substitution operator looks like this:

&parametername&

The operators delimiting a name always tell the assembler to substitute the actual argument for the name. However, the substitution operator is often optional. The substitution operator is not necessary when there is a space or separation character (comma, tab, or other operator) on that side. In the case of a parameter name inside a string, at least one substitution operator must appear.

The rules for using the substitution operator have changed significantly since MASM 5.1, making macro behavior more consistent and flexible. If you have macros written for a previous version of MASM, you can specify the old behavior by using OLDMACROS or M510 with the OPTION directive (see Section 1.3.2).

In the macro

work MACRO arg

mov ax, &arg& * 4

ENDM

the & symbols tell the assembler to replace the value of arg with the corresponding argument. However, the characters on both the right and left are spaces. Therefore, the operators are unnecessary. The macro would normally be written like this:

work MACRO arg

mov ax, arg * 4

ENDM

The substitution operator is used for one of the following reasons:

To paste together two parameter names or a parameter name and text

To indicate that a parameter name inside double or single quotation marks should be expanded rather than be treated as part of the quoted string

This macro illustrates both uses:

errgen MACRO num, msg

PUBLIC err&num

err&num BYTE "Error &num: &msg"

ENDM

When called with the following arguments,

errgen 5, <Unreadable disk>

the macro generates this code:

PUBLIC err5

err5 BYTE "Error 5: Unreadable disk"

In the second line of the macro, the left & symbol must be provided because it is adjacent to the r character, which is a valid identifier symbol. The right & symbol is not needed because there is a space to the right of the m. The statement pastes the text err to the argument value 5 to generate the symbol err5.

The substitution operator is used again inside quotation marks at the start of the parameter names num and msg to indicate that these names should be expanded. In this case, no pasting operation is necessary, so either operator could be omitted, but not both. The macro line could have been written as

err&num BYTE "Error num&: msg&"

or

err&num BYTE "Error &num&: &msg&"

The assembler processes substitution operators from left to right. This can have unexpected results when you are pasting together two macro parameters. For example, if arg1 has the value var and arg2 has the value 3, you could paste them together with this statement:

&arg1&&arg2& BYTE "Text"

Eliminating extra substitution operators, you might expect the following to be equivalent:

&arg1&arg2 BYTE "Text"

However, this actually produces the symbol vararg2 because in processing from left to right the assembler associates both the first and the second & symbols with the first parameter. The assembler replaces &arg1& by var , producing vararg2 . The arg2 is never evaluated. The correct abbreviation is

arg1&&arg2 BYTE "Text"

which produces the desired symbol var3. The symbol arg1&&arg2 is replaced by var&arg2, which is replaced by var3.

The substitution operator is also necessary if you want a text macro substituted inside quotes. For example,

arg TEXTEQU <hello>

%echo This is a string "&arg" ; Produces: This is a string "hello"

%echo This is a string "arg" ; Produces: This is a string "arg"

The substitution operator can also be used in lines beginning with the expansion operator (%) symbol, even outside macros (see Section 9.3.2.3). Text macros are always expanded in such lines, but it may be necessary to use the substitution operator to paste text macro names to adjacent characters or symbol names, as shown below:

text TEXTEQU <var>

value TEXTEQU %5

% ECHO textvalue is text&&value

This echoes the message

textvalue is var5

Summary: Bit-test and macro expansion statements can be confused.

The single ampersand (&) is the bit-test operator in MASM, as it is for C. This operator is also used in macro expansion as the substitute operator. Macro substitution always occurs before evaluation of the high-level control structures; therefore, in ambiguous cases, the & operator is treated as a macro-expansion character. You can always guarantee the correct use of the bit-test operator by enclosing the bit-test operands in parentheses. The example below illustrates these two uses.

test MACRO x

.IF ax==&x ; &x substituted with parameter value

mov ax, 10

.ELSEIF ax&(x) ; & is bitwise AND

mov ax, 20

.ENDIF

ENDM