VMS Help  —  MACRO  /ALPHA  Macros
    By using macros, you can use a single source statement to insert
    a sequence of source statements into a program.

    A macro definition contains the source statements of the macro.
    The macro definition may have formal arguments. You can use these
    formal arguments throughout the sequence of source statements
    within the definition. When the macro is called, the formal
    arguments are replaced by the actual arguments within the macro
    call.

    The macro call is a single source statement consisting of the
    macro name, optionally followed by arguments. When the macro
    is called, the assembler replaces the line containing the macro
    call with the source statements in the macro definition. The
    assembler replaces any occurrences of formal arguments in the
    macro definition with the actual arguments specified in the macro
    call. This process is called the macro expansion.

    By default, macro expansions are not printed in the assembly
    listing. To print the macro expansions, you must specify the
    /SHOW=EXPANSIONS qualifier and argument in the command line. Note
    that the examples of macro expansions used in this chapter are
    listed as they would appear using the /SHOW=EXPANSIONS qualifier
    and argument.

    Use .SHOW with a symbolic argument of EXPANSIONS in the source
    text of a program to specify the listing of expansions.

1  –  Arguments

    Macros have two types of arguments: actual and formal. Actual
    arguments are the text given in the macro call after the name
    of the macro. Formal arguments are specified by name in the
    macro definition; that is, after the macro name in the .MACRO
    directive. Actual arguments in macro calls and formal arguments
    in macro definitions can be separated by commas (,),  tabs, or
    spaces.

    The number of actual arguments in the macro call can be less
    than or equal to the number of formal arguments in the macro
    definition. If the number of actual arguments is greater than
    the number of formal arguments, the assembler displays an error
    message.

    Formal and actual arguments normally maintain a strict positional
    relationship. That is, the first actual argument in a macro call
    replaces all occurrences of the first formal argument in the
    macro definition. This strict positional relationship can be
    overridden by using keyword arguments. See the section on keyword
    arguments.

    An example of a macro definition using formal arguments follows:

    .MACRO  STORE  ARG1,ARG2,ARG3
    .LONG   ARG1                     ; ARG1 is first argument
    .WORD   ARG3                     ; ARG3 is third argument
    .BYTE   ARG2                     ; ARG2 is second argument
    .ENDM   STORE

    The following two examples show possible calls and expansions of
    the macro previously defined:

    STORE   3,2,1                    ; Macro call
    .LONG   3                        ; 3 is first argument
    .WORD   1                        ; 1 is third argument
    .BYTE   2                        ; 2 is second argument

    STORE   X,X-Y,Z                  ; Macro call
    .LONG   X                        ; X is first argument
    .WORD   Z                        ; Z is third argument
    .BYTE   X-Y                      ; X-Y is second argument

2  –  Default Values

    Default values are values that are defined in the macro
    definition. They are used when no value for a formal argument
    is specified in the macro call.

    Default values are specified in the .MACRO directive as follows:

    formal-argument-name = default-value

    An example of a macro definition specifying default values
    follows:

    .MACRO  STORE   ARG1=12,ARG2=0,ARG3=1000
    .LONG   ARG1
    .WORD   ARG3
    .BYTE   ARG2
    .ENDM   STORE

    The following three examples show possible calls and expansions
    of the macro defined previously:

    STORE                   ; No arguments supplied
    .LONG   12
    .WORD   1000
    .BYTE   0

    STORE   ,5,X            ; Last two arguments supplied
    .LONG   12
    .WORD   X
    .BYTE   5

    STORE   1               ; First argument supplied
    .LONG   1
    .WORD   1000
    .BYTE   0

3  –  Keyword Arguments

    Keyword arguments allow a macro call to specify the arguments
    in any order. In this case, the macro call must specify the
    same formal argument names that appear in the macro definition.
    Keyword arguments are useful when a macro definition has more
    formal arguments than necessary in the call.

    In any one macro call, it is good practice to specify the
    arguments as either all positional arguments or all keyword
    arguments. For example, the following macro definition specifies
    three arguments:

    .MACRO  STORE   ARG1,ARG2,ARG3
    .LONG   ARG1
    .WORD   ARG3
    .BYTE   ARG2
    .ENDM   STORE

    The following macro call specifies keyword arguments:

    STORE   ARG3=27+5/4,ARG2=5,ARG1=SYMBL
    .LONG   SYMBL
    .WORD   27+5/4
    .BYTE   5

    Because the keywords are specified in the macro call, the
    arguments in the macro call need not be given in the order they
    were listed in the macro definition.

    Positional and keyword arguments may be mixed. Usually,
    positional arguments are placed before keyword arguments. For
    example:

    .MACRO  STORE   ARG1,ARG2,ARG3=27+5/4
    .LONG   ARG1
    .BYTE   ARG2
    .WORD   27+5/4
    .ENDM   STORE

                                   NOTE

       Keyword arguments are not counted when positional arguments
       are parsed. This means that when positional and keyword
       arguments are used in the same macro, one argument can be
       specified twice. The last value specified for the argument
       is used.

4  –  String Arguments

    If an actual argument is a string containing characters that
    the assembler interprets as separators (such as a tab, space,
    or comma), the string must be enclosed by delimiters. String
    delimiters for macro arguments are usually paired angle brackets
    (<>). A quoted literal enclosed in double quotes ("")  is also a
    valid string argument.

    The assembler also interprets any character
    (except A, B, C, D, O, or X) after an initial circumflex (^)
    as a delimiter. Note that ^B, ^D, ^O, and ^X are used as radix
    control operators rather than argument delimiters. ^A is used
    as the ASCII operator and ^C is used as the complement operator.
    To pass an angle bracket as part of a string, you can use the
    circumflex form of the delimiter.

    The following are examples of delimited macro arguments:

    <HAVE THE SUPPLIES RUN OUT?>
    <LAB:    CLR     R4>

    "A quoted literal is taken as a single parameter value."

    ^%ARGUMENT IS <LAST,FIRST> FOR CALL%
    ^?EXPRESSION IS <5+3>*<4+2>?

    In the last two examples, the initial circumflex indicates
    that the percent sign (%)  and question mark (?) are the
    delimiters. Note that only the left-hand delimiter is preceded
    by a circumflex.

    The assembler interprets a string argument enclosed by delimiters
    as one actual argument and associates it with one formal
    argument. If a string argument that contains separator characters
    is not enclosed by delimiters, the assembler interprets it as
    successive actual arguments and associates it with successive
    formal arguments.

    For example, the following macro definition has one formal
    argument:

    .MACRO DOUBLE_ASCII STRNG
    .ASCII  "STRNG"
    .ASCII  "STRNG"
    .ENDM   DOUBLE_ASCII

    The following two macro calls demonstrate actual arguments with
    and without delimiters:

    DOUBLE_ASCII <A B C D E>
    .ASCII  "A B C D E"
    .ASCII  "A B C D E"

    DOUBLE_ASCII  A B C D E
    %MACRO64-E-TOOMNYARGS, Too many arguments in macro call

    Note that the assembler interprets the second macro call as
    having five actual arguments instead of one actual argument with
    spaces.

    When a macro is called, the assembler removes normal delimiters
    around a string before associating it with the formal arguments.
    However, a quoted literal within double quotes is treated as a
    single token and retains its double quote delimiters.

    If a string contains a semicolon (;),  the string must be
    enclosed by delimiters; otherwise, the semicolon will mark the
    start of the comment field. Further, if the string contains a
    semicolon, you cannot continue the line unless the string is a
    quoted literal.

    You can nest macro invocations, that is, a macro definition can
    contain a call to another macro. If, within a macro definition,
    another macro is called and is passed a string argument, you must
    delimit the argument so that the entire string is passed to the
    second macro as one argument.

    The following macro definition contains a call to the DOUBLE_
    ASCII macro defined earlier:

            .MACRO     CNTDA LAB1,LAB2,STR_ARG
    LAB1:   .BYTE      LAB2-LAB1-1            ; Length of 2*string
              DOUBLE_ASCII   <STR_ARG>
       ; Call DOUBLE_ASCII macro
    LAB2:
            .ENDM    CNTDA

    Note that the argument in the call to DOUBLE_ASCII is enclosed in
    angle brackets even though it does not contain any separator
    characters. The argument is thus delimited because it is a
    formal argument in the definition of the macro CNTDA and will
    be replaced with an actual argument that may contain separator
    characters.

    The following example calls the macro CNTDA, which in turn calls
    the macro DOUBLE_ASCII:

    CNTDA  ST,FIN,<LEARN YOUR ABC'S>
    ST:     .BYTE   FIN-ST-1
            DOUBLE_ASCII <LEARN YOUR ABC'S>
            .ASCII  "LEARN YOUR ABC'S"
            .ASCII  "LEARN YOUR ABC'S"
    FIN:

    In addition to nested macro invocations, you can
    also nest macro definitions. That is, you can define
    one macro within another. In this example, the
    INNER_MACRO_DEF macro is not defined until the OUTER_MACRO_DEF
    macro is invoked and expanded:

            .macro OUTER_MACRO_DEF
                .macro INNER_MACRO_DEF
                    ...
                .endm INNER_MACRO_DEF
            .endm OUTER_MACRO_DEF

    You can use this capability to define a macro that redefines
    itself:

            .macro SETUP
                A = 75
                B = 92
                C = 87
                D = 0
                E = -12
                F = 42
                .macro SETUP
                    ; Setup is done - do nothing
                .endm SETUP
            .endm SETUP

    In this example, the SETUP macro defines a number of assembly
    constants. After the SETUP macro has been expanded once, its
    work is done. Subsequent expansions of the setup macro need not
    take any action. Therefore, the SETUP macro redefines itself
    to a macro whose expansion includes only a comment statement.
    As described elsewhere, when you redefine a macro, the original
    version of the macro is automatically deleted. If that macro is
    currently expanding (as would be the case with the previous SETUP
    macro), the new definition is immediately associated with the
    macro name. However, the old definition is retained until all
    pending expansions complete normally. When all pending expansions
    complete, the old version of the macro is deleted. Thus, the
    SETUP macro may be invoked any number of times in the assembly
    unit. Since the first expansion redefines itself, the expansion
    of the SETUP macro has no effect other than the first time it is
    invoked.

    Another way to pass string arguments in nested macros is to
    enclose the macro argument in nested delimiters.

                                   NOTE

       Each time you use the delimited argument in a macro call,
       the assembler removes the outermost pair of delimiters
       before associating it with the formal argument. This method
       is not recommended because it requires that you know how
       deeply a macro is nested.

    The following macro definition also contains a call to the
    DOUBLE_ASCII macro:

           .MACRO  CNTDA2 LAB1,LAB2,STR_ARG
    LAB1:  .BYTE   LAB2-LAB1-1             ; Length of 2*string
           DOUBLE_ASCII  STR_ARG           ; Call DOUBLE_ASCII macro
    LAB2:
           .ENDM   CNTDA2

    Note that the argument in the call to DOUBLE_ASCII is not
    enclosed in angle brackets.

    The following example calls the macro CNTDA2:

           CNTDA2 BEG,TERM,<<MIND YOUR P'S AND Q'S>>
    BEG:   .BYTE   TERM-BEG-1              ; Length of 2*string
           DOUBLE_ASCII  <MIND YOUR P'S AND Q'S>
           ; Call DOUBLE_ASCII macro
           .ASCII  "MIND YOUR P'S AND Q'S"
           .ASCII  "MIND YOUR P'S AND Q'S"
    TERM:

    Note that even though the call to DOUBLE_ASCII in the macro
    definition is not enclosed in delimiters, the call in the
    expansion is enclosed because the call to CNTDA2 contains nested
    delimiters around the string argument.

5  –  Argument Concatentation

    The argument concatenation operator, the apostrophe ('),
    concatenates a macro argument with constant text or another
    argument. Apostrophes can either precede or follow a formal
    argument name in the macro source.

    If an apostrophe precedes the argument name, the text before
    the apostrophe is concatenated with the actual argument when
    the macro is expanded. For example, if ARG1 is a formal argument
    associated with the actual argument TEST, then ABCDE'ARG1 is
    expanded to ABCDETEST.

    If an apostrophe follows the formal argument name, the actual
    argument is concatenated with the text that follows the
    apostrophe when the macro is expanded. The apostrophe itself
    does not appear in the macro expansion.

    To concatenate two arguments, separate the two formal arguments
    with two successive apostrophes. Two apostrophes are needed
    because each concatenation operation discards an apostrophe from
    the expansion.

    An example of a macro definition that uses concatenation follows:

            .MACRO CONCAT   A,B
    A''B:   .WORD 0
            .ENDM CONCAT

    Note that two successive apostrophes are used when concatenating
    the two formal arguments A and B.

    An example of a macro call and expansion follows:

            CONCAT  X,Y
    XY:     .WORD 0

6  –  Passing Numeric Values of Symbols

    When a symbol is specified as an actual argument, the name of
    the symbol, not the numeric value of the symbol, is passed to
    the macro. You can pass the value of the symbol by inserting a
    backslash (\) before the symbol in the macro call. The assembler
    passes the characters representing the decimal value of the
    symbol to the macro. For example, if the symbol COUNT has a value
    of 2 and the actual argument specified is \COUNT, the assembler
    passes the string 2 to the macro; it does not pass the name of
    the symbol, COUNT.

    Passing numeric values of symbols is especially useful with the
    apostrophe (')  concatenation operator for creating new symbols.

    An example of a macro definition for passing numeric values of
    symbols follows:

            .MACRO WORD n
    WORD'n: .WORD n
            .ENDM WORD

    The following example shows a possible call and expansion of the
    macro previously defined:

           X = 1       ; Start counting at 1
           WORD \X
    WORD1: .WORD 1

7  –  Created Temporary Labels

    Temporary labels are often very useful in macros. You can create
    a macro definition that specifies temporary labels within it,
    but these temporary labels might be duplicated elsewhere in the
    temporary label block, possibly causing errors. However, the
    assembler can create temporary labels in the macro expansion that
    will not conflict with other temporary labels. These labels are
    called created temporary labels.

    Created temporary labels range from 30000$ to 65535$. Each time
    the assembler creates a new temporary label, it increments the
    numeric part of the label name by 1. Consequently, no user-
    defined temporary labels should be in the range of 30000$ to
    65535$.

    A created temporary label is specified by a question mark (?)  in
    front of the formal argument name. When the macro is expanded,
    the assembler creates a new temporary label if the corresponding
    actual argument is blank. If the corresponding actual argument is
    specified, the assembler substitutes the actual argument for the
    formal argument.

    The following example is a macro definition specifying a created
    temporary label:

            .MACRO  POSITIVE        ARG1,?L1
            BGE     ARG1,L1
            NEGQ    ARG1,ARG1
    L1:    .ENDM    POSITIVE

    The following three calls and expansions of the macro defined
    previously show both created temporary labels and a user-defined
    temporary label:

            POSITIVE  R0
            BGE     R0,30000$
            NEGQ    R0,R0
    30000$:

            POSITIVE  R5
            BGE     R5,30001$
            NEGQ    R5,R5
    30001$:

            POSITIVE  R7,10$
            BGE     R7,10$
            NEGQ    R7,R7
    10$:
Close Help