ICS 312         Macros


Textbook Reading (Jones): Chapter 8


Macros


Definition
 
A macro is a block of text that has been given a name. When the assembler encounters the name during assembly, it inserts the block into the program. The text may consist of instructions, pseudo-ops, comments, or references to other macros.

Syntax:

macro_name  MACRO      d1, d2, …,dn

            statements (body of macro)

            ENDM

Where d1, d2,…,dn is a list of dummy arguments.


Example: We know that the operands of the MOV instruction cannot both be word variables, but we can define a macro to move a word source variable to a word destination variable.

MOVW    MACRO WORD1, WORD2
        PUSH WORD2
        POP WORD1
        ENDM


To use a macro in a program, we invoke it.

Syntax:

macro_name a1, a2, a3,…,an

where a1, a2, …, an is a list of actual arguments.

Example: Invoke the macro MOVW to move B to A, where A and B are word variables.

.DATA
A  DW ?
B  DW ?

.CODE
...
MOVW A, B 


Macro expansion - character substitution of actual arguments.

These instructions:

MOVW A, DX
MOVW A+2, B

Insert the following (equivalent) code into a program:  

PUSH DX
POP A
PUSH B
POP A+2


Special Invocations

MOVW AX, 1ABCH         generates the code

PUSH 1ABCH
POP AX

Pushing an immediate value requires using a processor directive (e.g., .586) before the push instruction will be recognized by the assembler translator.


Restoring Registers 

Good programming practice requires that a procedure should restore the registers that it uses, unless they contain output values. The same is true for macros.


Program Listing

.MODEL SMALL
MOVW MACRO WORD1,WORD2 
    PUSH WORD2 
    POP WORD1 
    ENDM 
.STACK 100H 
.DATA
A DW 1,2
B DW 3
.CODE
MAIN PROC 
    MOV AX,@DATA
    MOV DS,AX
    MOVW A,DX 
    MOVW A+2,B 
;dos exit
    MOV AH,4C00H
    INT 21H
MAIN ENDP
    END MAIN

Listing Files

    In command line batch files for MASM, the option /Fl generates a full listing file:

        ml /Fl /Zi /W3 %1.asm

Finding Assembly Errors

Errors found during macro expansion are listed at the point of the macro invocation. To find where the mistake really is, you need to inspect the macro expansion in the .LST file --- this is especially helpful if the macro invokes other macros.


Local Labels

A macro with a loop or decision structure contains one or more labels. If such a macro is invoked more than once in a program, duplicate labels occur causing an assembly error. To avoid this, generate local labels in macros by using the LOCAL pseudo-op in the macro declaration.   The LOCAL directive must appear on the first line of the 
macro following the name of the macro.

Syntax:

    LOCAL list of labels


Example: A macro to place the largest of two words in AX:

GET_BIG   MACRO   WORD1, WORD2
      LOCAL OUT         ; local label
      MOV AX, WORD1
      CMP AX, WORD2
      JG EXIT
      MOV AX, WORD2
OUT: ENDM  

Successive invocations of this macro causes the assembler to insert labels ??0000, ??0001, ??0002, etc. into the program. These labels are unique and not likely to conflict with labels chosen by the the user.


Macros that Invoke Other Macros

Macros may invoke other macros, or themselves. When this happens, the assembler expands each macro as it is encountered.


Macro Libraries

Macros may be stored in separate files, called libraries.  Use the INCLUDE pseudo-op to include the library file in a program.   This copies all of the macros defined in the library file into the program listing.  The INCLUDE statement can appear anywhere before the included macros are invoked in the program.

Syntax:

    INCLUDE    A:\MACROS.INC         ; path and filename


Repetition Macros

The REPT macro can be used to repeat a block of statements.

Syntax:

    REPT expression
        statements

    ENDM


Example: Write a program to initialize a block of memory to the first N integers. Then invoke it in a program to initialize an array to the first 100 integers.

BLOCK MACRO N
    K=1  
  REPT  N
    DW  K        ; generates program code
    K=K+1  
  ENDM  
ENDM 

Note:  The "=" pseudo-op can be used to assign a name to a macro constant.  The expression to the right of the "=" must have an integer value, and a constant defined with "=" may be redefined.  This is different from the EQU pseudo-op, in which the constant defined may not be redefined.

Note:  The value of a macro argument cannot be changed within the macro.  Consequently to implement loops, macro constants are needed.

To define an array A of word-sized values and initialize it to the first 100 integers, we can use the following in the data segment:

A LABEL WORD
  BLOCK 100

Invoking the BLOCK macro initializes K to 1 and the statements in the REPT macro are assembled 100 times.  The final result is equivalent to:

A DW 1
  DW 2
  DW 3
  DW 4
        .  
  DW 100

      Example:  Write a macro to initialize an n-word array to 1!, 2!,..n! and show how to invoke it.

FACTORIALS MACRO N
    M = 1  
    FAC = 1  
  REPT N
    DW FAC        ; assembler statement that generates code
    M = M+1  
    FAC = M*FAC  
  ENDM  
ENDM  

To define a word array B initialized to the value of the first 8 factorials, the data segment can contain:

B LABEL WORD
  FACTORIALS    8

8! = 40320 is the largest factorial that will fit in a 16-bit word.

The (equivalent) expansion for this is:
B DW 1
  DW 2
  DW 6
  DW 24
  DW 120
  DW 720
  DW 5040
  DW 40320


The Indefinite Repeat Macro (IRP)

Syntax:

IRP    D, <a1, a2, ..an>
      statements  
ENDM    


Note:  The angle brackets are part of the syntax and must be used.

When expanded, this macro causes the statements to be assembled n times, on the ith expansion, each occurrence of parameter d is replaced by ai.


Tradeoffs between Macros and Procedures

Assembly Time
A program containing macros normally takes longer to assemble than a program containing procedures because of the time required to do the macro expansions.
 
Execution Time
A program containing macros typically executes faster than a program with procedures, because the macro code is "in-line" and there is no requirement to transfer control.
 
Program Size
A program containing macros will usually be larger than a program with procedures because of the additional lines of code generated during the macro expansion.
 
Best Uses of Macros and Procedures
Macros are very good for short, frequently executed tasks (e.g., short utility functions).  Procedures are good for handling longer, more complicated (and less frequently used) tasks.