ICS 312 Macros
Textbook Reading (Jones): Chapter 8
macro_name MACRO d1, d2, ,dn
statements (body of macro)
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
To use a macro in a program, we invoke it.
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.
A DW ?
B DW ?
MOVW A, B
MOVW A, DX
MOVW A+2, B
Insert the following (equivalent) code into a program:
MOVW AX, 1ABCH generates the code
Pushing an immediate value requires using a processor directive (e.g., .586) before the push instruction will be recognized by the assembler translator.
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 SMALLMOVW 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,AXMOVW A,DX MOVW A+2,B;dos exit MOV AH,4C00H INT 21H MAIN ENDP END MAIN
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.
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.
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
MOV AX, WORD2
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.
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.
INCLUDE A:\MACROS.INC ; path and filename
The REPT macro can be used to repeat a block of statements.
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
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
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
8! = 40320 is the largest factorial that will fit in a 16-bit word.
The (equivalent) expansion for this is:
B DW 1
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.