6. Macro Assembly

Part of the SMAL Manual
by Douglas W. Jones
THE UNIVERSITY OF IOWA Department of Computer Science

Index

  1. Macro Definitions
  2. Macro Formal Parameters
  3. Macro Calls
  4. Examples

The SMAL macro facilities allow assembly-time control structures comparable to the procedure structures of many high level languages. A macro is a named block of text which is assembled into the program wherever its name occurs in the context of a macro call. If a macro is defined as having formal parameters, the corresponding actual parameters are substituted for the formal parameters within the body of the macro before it is assembled.

Note: Macros control how the assembler sees your code. They do not control the execution of the assembled machine code.

6.1 Macro Definitions

Each macro definition begins with a MACRO directive and ends with an ENDMAC directive. The MACRO directive is followed by the name of the macro and its formal parameter list.

<symbolic directive> ::= MACRO <identifier> [ <formal list> ]
                       | ENDMAC

The semantics of a macro declaration are most easily described in terms of macro blocks which begin with a MACRO directive and end with an endmac directive. The body of the block between the two is saved by the assembler and assembled as a result of each call to the macro.

<macro block> ::= MACRO <identifier> [ <formal list> ] <line end>
                { <line> }
                  ENDMAC

Note that any labels on the line containing the MACRO directive are not interpreted as having anything to do with the macro but are processed as normal labels. Labels on the line containing the ENDMAC directive are completely ignored! If a macro block is not properly terminated with an ENDMAC directive, a "missing endmac" error will result. The following fragment of valid SMAL32 code illustrates the definition of a simple parameterless macro:

    MACRO ZO
      W 0
      W -1
    ENDMAC

A call to this macro can be used to put the two word sequence 0, -1 in memory.

Macro definitions may contain other macro definitions, but these do not create local macros, as might be expected by anology with high level languages. Instead, the internal macro definition will be processed by the assembler each time the containing macro is called. Thus, a macro may be used to create a number of other macros constructed from the values of its parameters.

6.2. Macro Formal Parameters

The formal parameter list on a macro definition gives the names of each parameter and the parameter passing mode. Forml parameter names are identifiers. There may be a limit on the number of formal parameters allowed; if this is exceded, a "too many macro parameters" error will be raised. All versions of SMAL support at least 8 parameters.

<formal list> ::= <formal parameter> { , <formal parameter> }
<formal parameter> ::= <identifier>
                     | ( <identifier> )
                     | = <identifier>

The three macro parameter modes are:

The treatment of actual parameters in each of these modes will be discussed in Section 6.3.

The following fragment of a SMAL assembly listing illustrates the definition of a simple macro with one parameter passed by name:

    MACRO WZO TEXT
      W TEXT
      ZO
    ENDMAC

Note that the above macro contains a call to the macro ZO defined in the previous example.

Within the macro body, each occurance of any macro formal parameter name is identified. This includes formal parameters embedded in comments and character strings. The only time that a formal parameter will not be identified is when it is embedded in a larger identifier. For example, if A and B are formal parameters, neither of them will be identified in the string AB. If AB is to be seen as the concatenation of two parameters, an apostrophe should be inserted between them, as in A'B. Within a macro body, single apostrophes will be deleted, and strings of two or more apostrophes will be shortened by one. Thus, special care must be taken when using apostrophes as single quotes around quoted strings in macros.

6.3. Macro Calls

A macro call takes the form of a symbolic directive which begins with the name of a previously defined macro, followed by a list of actual parameters.

<symbolic directive> ::= <identifier> <actual list>
<actual list> ::= <actual parameter> { , <actual parameter> }
<actual parameter> ::= [ <by name> | <by list> | <by value> ]

The first step in processing a macro call is to store the text of each actual parameter, according to the parameter passing rules associated with that parameter type. Individual parameters may be omitted or blank, in which case, no text is passed. In all cases, the number of actual parameters must be less than or equal to the number of formal parameters. Missing actual parameters are passed as empty strings. The following rules apply:

Macros will not be expanded when there are errors in the actual parameter list. After actual parameters processing, macro expansion proceeds by assembling the macro body. As the body is assembled, formal parameters in the body are replaced with the actual parameter text. If the resulting text for any line is longer than the implementation defined line length limit, the error "text too long for line" will result. During expansion, other macro calls may be processed, even recursive calls.

6.4. Examples

The following SMAL32 assembly listing fragments (see Section 10.2) show the correct use of macros. The first example demonstrates the use of each parameter passing mode:

                            29        MACRO TT    NAME,=NUMBER, ( LIST )
                            30          NAME  NUMBER
                            31          LIST
                            32        ENDMAC
                            33
                            34        TT    W,5+4,(COMMON A,5)
+000026: 00000009           34          W  9
                            34          COMMON A,5
                            34  END
                            35
                            36        TT W,1,(BIW -25):3
+00002A: 00000001           36          W  1
+00002E: FFFFFFE7           36          W -25
                            36  END
                            37
                            38        TT W, 1 + A + 1, ("; NONESUCH"):2:6
+000032:+00000002           38          W  A+2
                            38          ; NONE
                            38  END

All lines produced by macro expansion are listed after the call, with the same line number as the call. Normally, macro expansion listing is suppressed, but it can be turned on using the LIST directive (see Section 7.4). END directives mark the end of each macro.

In the first call to TT, the expression 5+4 was evaluated and the value 9 was substituted in the macro body. In the second call, the expression 1 was evaluated and passed as 1. In the third call, the value of 1 + A + 1 could not be converted to a number because the value is relative to the common name A; the string that was passed, A+2, is the result of evaluating the expression and then constructing a new string from the value.

The following macro shows how to package halfword and word alignment in SMAL:

                             3  MACRO ALIGN =x
                             4    IF x > 1
                             5      IF (x & 1) = 1
                             6        ERROR odd parameter to ALIGN
                             7      ELSE
                             8        ALIGN (x>>1)
                             9        .=.+(ABS(.)&(x>>1))
                            10      ENDIF
                            11    ENDIF
                            12  ENDMAC
                            13
                            14        ALIGN 1     ; no operation
+000000: 01                 15        B     1
                            16        ALIGN 2     ; align to a halfword boundary
+000002: 0002               17        H     2
                            18        ALIGN 4     ; align to a word boundary
+000004: 00000003           19        W     3
                            20        ALIGN 3     ; an improper alignment
                            20        ERROR odd parameter to ALIGN
error message

If the location counter (see Chapter 3) is absolute, this macro aligns to any power of 2; in relocatable code, it can only align to the nearest word unless alignment directives are included in the linker control file (see Chapter 8) to align the relocation process. Here, conditional and recursive macro assembly were used. This example also uses the ERROR directive (see Section 7.7) to report an imporper macro parameter.

The following two macros demonstrate the use of value parameters and concatenation for automatic label generation. The macro CATNUM simply concatenates its three parameters, where the middle parameter is an expression. This is used by the second macro, USER, to construct new symbols using a counter, LAB, which is incremented once for each call.

                            40  MACRO CATNUM (PART1),=NUM,(PART2)
                            41    PART1'NUM'PART2
                            42  ENDMAC
                            43
                            44  LAB = 1
                            45  MACRO USER
                            46    LAB = LAB + 1
                            47    CATNUM (L),LAB,(:)
                            48    W 0
                            49    CATNUM (W L),LAB
                            50  ENDMAC
                            51
                            52  USER
                            52    LAB = LAB + 1
                            52    CATNUM (L),LAB,(:)
                            52    L2:
                            52  END
+000036: 00000000           52    W 0
                            52    CATNUM (W L),LAB
+00003A:+00000036           52    W L2
                            52  END
                            52  END
                            53
                            54  USER
                            54    LAB = LAB + 1
                            54    CATNUM (L),LAB,(:)
                            54    L3:
                            54  END
+00003E: 00000000           54    W 0
                            54    CATNUM (W L),LAB
+000042:+0000003E           54    W L3
                            54  END
                            54  END

Note that the symbol LAB could have been initialized in the macro USER instead of in the main program. To do this, the initialization would have to be assembled conditionally depending on whether or not LAB had been previously defined.

The last example illustrates a macro similar to the built in ASCII directive:

                            19  MACRO TEXT S,(PART1),(PART2)
                            20    IF LEN(S) > 0
                            21      TEXT ,(S):2:1,(S):3:LEN(S)-3
                            22    ELSEIF LEN(''PART1'') > 2
                            23      B ''PART1''
                            24      TEXT ,(PART2):1:1,(PART2):2
                            25    ENDIF
                            26  ENDMAC
                            27
+00003E: 43  41  4C  43     28        TEXT  "CALCULATE"
         55  4C  41  54
         45

This example demonstrates the combination of conditional and macro assembly, the use of substring parameters, the use of the function LEN to detect missing parameters, and the use of recursion. Note also the use of doubled single quotes within the macro definition which result in single quotes at expansion time.