Document revision date: 30 March 2001

## VAX MACRO and Instruction Set Reference Manual

Previous | Contents | Index

## Chapter 4
Macro Arguments and String Operators

By using macros, you can use a single line to insert a sequence of source lines into a program.

A macro definition contains the source lines of the macro. The macro definition can optionally have formal arguments. These formal arguments can be used throughout the sequence of source lines. Later, the formal arguments are replaced by the actual arguments in the macro call.

The macro call consists of the macro name optionally followed by actual arguments. The assembler replaces the line containing the macro call with the source lines in the macro definition. It 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.

The macro directives (described in Chapter 6) provide facilities for performing eight categories of functions. Table 6-2 lists these categories and the directives that fall under them.

By default, macro expansions are not printed in the assembly listing. They are printed only when the .SHOW directive (see description in Chapter 6) or the /SHOW qualifier (described in the OpenVMS DCL Dictionary) specifies the EXPANSIONS argument. In the examples in this chapter, the macro expansions are listed as they would appear if .SHOW EXPANSIONS was specified in the source file or /SHOW=EXPANSIONS was specified in the MACRO command string.

The remainder of this chapter describes macro arguments, created local labels, and the macro string operators.

## 4.1 Arguments in Macros

Macros have two types of arguments: actual and formal. Actual arguments are the strings 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 the use of keyword arguments (see Section 4.3).

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 defined previously:

    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

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

## 4.3 Keyword Arguments

Keyword arguments allow a macro call to specify the arguments in any order. 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 need to be specified in the call.

In any one macro call, the arguments should be either all positional arguments or all keyword arguments. When positional and keyword arguments are combined in a macro, only the positional arguments correspond by position to the formal arguments; the keyword arguments are not used. If a formal argument corresponds to both a positional argument and a keyword argument, the argument that appears last in the macro call overrides any other argument definition for the same argument.

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.

## 4.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 are usually paired angle brackets (<>).

The assembler also interprets any character after an initial circumflex (^) as a delimiter. 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?>
    <LAST NAME, FIRST NAME>
    <LAB:    CLRL    R4>
    ^%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 call has one formal argument:

    .MACRO  REPEAT STRNG
    .ASCII  /STRNG/
    .ASCII  /STRNG/
    .ENDM   REPEAT

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

    REPEAT  <A B C D E>
    .ASCII  /A B C D E/
    .ASCII  /A B C D E/

    REPEAT  A B C D E
    %MACRO-E-TOOMNYARGS, Too many arguments in macro call

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

When a macro is called, the assembler removes any delimiters around a string before associating it with the formal arguments.

If a string contains a semicolon (;), the string must be enclosed by delimiters, or the semicolon will mark the start of the comment field.

Strings enclosed by delimiters cannot be continued on a new line.

To pass a number containing a radix or unary operator (for example, ^XF19), the entire argument must be enclosed by delimiters, or the assembler will interpret the radix operator as a delimiter.

The following are macro arguments that are enclosed in delimiters because they contain radix operators:

    <^XF19>
    <^B01100011>
    <^F1.5>

Macros can be nested; 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 REPEAT macro defined in an earlier example:

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

Note that the argument in the call to REPEAT 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 CNTRPT and will be replaced with an actual argument that may contain separator characters.

The following example calls the macro CNTRPT, which in turn calls the macro REPEAT:

            CNTRPT  ST,FIN,<LEARN YOUR ABC'S>
    ST:     .BYTE   FIN-ST-1                ; Length of 2*string
            REPEAT  <LEARN YOUR ABC'S>      ; Call REPEAT macro
            .ASCII  /LEARN YOUR ABC'S/
            .ASCII  /LEARN YOUR ABC'S/
    FIN:

An alternative method to pass string arguments in nested macros is to enclose the macro argument in nested delimiters. Do not use delimiters around the macro calls in the macro definitions. 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 REPEAT macro:

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

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

The following example calls the macro CNTRPT2:

           CNTRPT2 BEG,TERM,<<MIND YOUR P'S AND Q'S>>
    BEG:   .BYTE   TERM-BEG-1              ; Length of 2*string
           REPEAT  <MIND YOUR P'S AND Q'S> ; Call REPEAT 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 REPEAT in the macro definition is not enclosed in delimiters, the call in the expansion is enclosed because the call to CNTRPT2 contains nested delimiters around the string argument.

## 4.5 Argument Concatenation

The argument concatenation operator, the apostrophe ('), concatenates a macro argument with some constant text. 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, 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. For example, if ARG2 is a formal argument associated with the actual argument MOV, ARG2'L is expanded to MOVL.

Note that 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   INST,SIZE,NUM
    TEST'NUM':
            INST''SIZE      R0,R'NUM
    TEST'NUM'X:
            .ENDM   CONCAT

Note that two successive apostrophes are used when concatenating the two formal arguments INST and SIZE.

An example of a macro call and expansion follows:

            CONCAT  MOV,L,5
    TEST5:
            MOVL    R0,R5
    TEST5X:

## 4.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. The value of the symbol can be passed 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  TESTDEF,TESTNO,ENTRYMASK=^?^M<>?
    .ENTRY  TEST'TESTNO,ENTRYMASK     ; Uses arg concatenation
    .ENDM   TESTDEF

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

    COUNT = 2
            TESTDEF \COUNT
            .ENTRY  TEST2,^M<>         ; Uses arg concatenation
    COUNT = COUNT + 1
            TESTDEF \COUNT,^?^M<R3,R4>?
            .ENTRY  TEST3,^M<R3,R4>    ; Uses arg concatenation

## 4.7 Created Local Labels

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

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

A created local label is specified by a question mark (?) in front of the formal argument name. When the macro is expanded, the assembler creates a new local 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. Created local symbols can be used only in the first 31 formal arguments specified in the .MACRO directive.

Created local labels can be associated only with positional actual arguments; created local labels cannot be associated with keyword actual arguments.

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

            .MACRO  POSITIVE        ARG1,?L1
            TSTL    ARG1
            BGEQ    L1
            MNEGL   ARG1,ARG1
    L1:    .ENDM    POSITIVE

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

            POSITIVE  R0
            TSTL    R0
            BGEQ    30000$
            MNEGL   R0,R0
    30000$:

            POSITIVE  COUNT
            TSTL    COUNT
            BGEQ    30001$
            MNEGL   COUNT,COUNT
    30001$:

            POSITIVE  VALUE,10$
            TSTL    VALUE
            BGEQ    10$
            MNEGL   VALUE,VALUE
    10$:

## 4.8 Macro String Operators

Following are the three macro string operators:

- %LENGTH
- %LOCATE
- %EXTRACT

These operators perform string manipulations on macro arguments and ASCII strings. They can be used only in macros and repeat blocks. The following sections describe these operators and give their formats and examples of their use.

### 4.8.1 %LENGTH Operator

Format

`%LENGTH(string)`

> #### string

> A macro argument or a delimited string. The string can be delimited by angle brackets or a character preceded by a circumflex (see Section 4.4).

Description The %LENGTH operator returns the length of a string. For example, the value of %LENGTH(<ABCDE>) is 5. Examples

> The macro definition is as follows:

#1
            .MACRO  CHK_SIZE     ARG1                ; Macro checks if ARG1
            .IF GREATER_EQUAL    %LENGTH(ARG1)-3     ;   is between 3 and
            .IF LESS_THAN        6-%LENGTH(ARG1)     ;   6 characters long
            .ERROR  ; Argument ARG1 is greater than 6 characters
            .ENDC                                    ; If more than 6
            .IF_FALSE                                ; If less than 3
            .ERROR  ; Argument ARG1 is less than 3 characters
            .ENDC                                    ; Otherwise do nothing
            .ENDM   CHK_SIZE

> The macro calls and expansions of the macro defined previously are as follows:

#2
            CHK_SIZE        A                        ; Macro checks if A
            .IF GREATER_EQUAL   1-3                  ;   is between 3 and
            .IF LESS_THAN       6-1                  ;   6 characters long.
                                                     ;   Should be too short.
            .ERROR  ; Argument A is greater than 6 characters
            .ENDC                                    ; If more than 6
            .IF_FALSE                                ; If less than 3
    %MACRO-E-GENERR, Generated ERROR: Argument A is less than 3 characters

            .ENDC                                    ; Otherwise do nothing

#3
            CHK_SIZE        ABC                      ; Macro checks if ABC
            .IF GREATER_EQUAL   3-3                  ;   is between 3 and
            .IF LESS_THAN       6-3                  ;   6 characters long.
                                                     ;   Should be ok.
            .ERROR  ; Argument ABC is greater than 6 characters
            .ENDC                                    ; If more than 6
            .IF_FALSE                                ; If less than 3
            .ERROR  ; Argument ABC is less than 3 characters
            .ENDC                                    ; Otherwise do nothing

### 4.8.2 %LOCATE Operator

Format

`%LOCATE(string1,string2 [,symbol])`

### Parameters

> #### string1

> A substring. The substring can be written either as a macro argument or as a delimited string. The delimiters can be either angle brackets or a character preceded by a circumflex.

> #### string2

> The string to be searched for the substring. The string can be written either as a macro argument or as a delimited string. The delimiters can be either angle brackets or a character preceded by a circumflex.

> #### symbol

> An optional symbol or decimal number that specifies the position in string2 at which the assembler should start the search. If this argument is omitted, the assembler starts the search at position zero (the beginning of the string). The symbol must be an absolute symbol that has been previously defined; the number must be an unsigned decimal number. Expressions and radix operators are not allowed.

Description The %LOCATE operator locates a substring within a string. If %LOCATE finds a match of the substring, it returns the character position of the first character of the match in the string. For example, the value of %LOCATE(<D>,<ABCDEF>) is 3. Note that the first character position of a string is zero. If %LOCATE does not find a match, it returns a value equal to the length of the string. For example, the value of %LOCATE(<Z>,<ABCDEF>) is 6.

The %LOCATE operator returns a numeric value that can be used in any expression.

Examples

> The macro definition is as follows:

#1
            .MACRO  BIT_NAME ARG1   ; Checks if ARG1 is in list
             .IF EQUAL  %LOCATE(ARG1,<DELDFWDLTDMOESC>)-15
                                    ; If it is not, print error
             .ERROR  ; ARG1 is an invalid bit name
             .ENDC                  ; If it is, do nothing
             .ENDM  BIT_NAME

> The macro calls and expansions of the macro defined previously are as follows:

#2
            BIT_NAME  ESC           ; Is ESC in list
            .IF EQUAL  12-15        ; If it is not, print error
            .ERROR  ; ESC is an invalid bit name
            .ENDC                   ; If it is, do nothing

            BIT_NAME  FOO           ; Not in list
            .IF EQUAL  15-15
                                    ; If it is not, print error
    %MACRO-E-GENERR, Generated ERROR:  FOO is an invalid bit name

            .ENDC                   ; If it is, do nothing

Note If the optional symbol is specified, the search begins at the character position of string2 specified by the symbol. For example, the value of %LOCATE(<ACE>,<SPACE_HOLDER>,5) is 12 because there is no match after the fifth character position.

Previous | Next | Contents | Index

| privacy and legal statement |
4515PRO_003.HTML