Chapter-3: Macro Processors
Topics in this chapter:
● Use of Macro and its Definition.
● Structure of a macro.
● Functions of Macro Processors
● Difference between Macro and Functions / Subroutine
● Parameterized Macros
● Nested Macros
● Conditional Macro
● Recursive Macro
● Design of a Simple Macro Processor
o Sample program assembly by a simple pass macro processor
3.1 Need of Macro and Definition of a Macro
Macros are defined as “single-line abbreviation for a small sequence of commands”.
Often in ALP, there are small sequences of instructions that are used repeatedly in the
program.
In such situations, we can put commonly occurring sequence of instructions in a macro.
Now, wherever these instructions are to be used in the program, we simply call the macro
instead of writing the same code again and again.
3.2 Structure of a Macro
MACRO <macroName> [<arg1>, <arg2>,…,<argN>] ; Macro header
. ; Macro body starts here
.
.
MEND ; End of Macro
.
.
<macroName> ; Only name of the macro used to call it
1
The macro header consists of MACRO keyword, name of the macro and optionally, the
parameters passed to the macro. MEND is used to indicate end of a macro. The macro is
called simply by using its name.
For example: Suppose the programmer uses following sequence of instructions
repeatedly in his program
.
.
LOAD A
ADD B
STORE B
.
.
LOAD A
ADD B
STORE B
Instead he can use a Macro for the same operation as follows:
MACRO AddAB ; Macro definition starts
LOAD A
ADD B
STORE B
MEND ; Macro definition ends
.
.
AddAB ; Macro call
.
.
AddAB ; Macro call
2
3.3 Functions of a Macro Processor
Assembler does not recognize the macro calls. So, the macro processor works as a
preprocessor and expands the macro calls by replacing them with corresponding
sequence of instructions.
Functions of a Macro Processor:
1. Detect the definition of a Macro – MACRO and MEND keywords are used by
the macro processor to recognize the start and end of a macro.
2. Save the definition – The macro processor uses Macro Name Table (MNT) to
store a list of macros used in the program and Macro Definition Table (MDT) to
store their corresponding definitions. Argument List Array (ALA) is used to
convert the formal parameters to positional parameter within a macro.
3. Detect the call to a Macro – The macro processor detects a macro call by
searching first token of the statement in the MNT.
4. Expand the Macro call – MNT and MDT are used to get the stored definition of
macro being called. ALA is used to convert positional parameters to actual
parameters given in the call.
Following example shows how macros are expanded:
3
3.4 Comparison: Macro vs. Functions (or Subroutines)
Macros appear to be functionally similar to Functions (or Subroutines). But there are
several fundamental differences between the two. Following table highlights these
differences:
Macro Functions
(or Subroutines)
Definition Macros are single-line Functions are blocks of
abbreviations of a small code that are to be executed
sequence of instructions. repeatedly by the program
Lines of Code Macros are used when Functions can be used for
number of repeating any length of code that is to
instructions is very small (3 be executed repeatedly.
to 5 instructions)
Use of CALL mnemonic Only the macro name is CALL mnemonic is used
used to call the macro along with the function
name (as its operand), to
call the function
4
Time of processing Macros are processed at Functions are processed
compilation time during execution time
Processing the call Macro calls are replaced by When a function is called,
corresponding sequence of its corresponding
instructions; these instructions are actually
instructions are not actually executed.
executed.
Housekeeping No housekeeping operations The return address is
operations (pushing and popping on pushed onto stack, when a
the stack) are needed. function is called and is
popped back when the
function returns
Need of a Preprocessor Macro calls are not Functions (or Subroutines)
recognized by the are executed by the
assembler. So, a separate Assembler itself (as
Macro Processor is needed Procedures)
to expand them
Return value Macros cannot return a Functions can return a value
value
Size of the program Macro calls are expanded Functions do not increase
inline. So, they increase the the size of the program
size of the program
Speed of execution Since there are no Housekeeping operations
housekeeping operations make programs using
involved, programs using functions execute at lesser
macros execute slightly speed.
faster than the ones using
functions
5
3.5 Parameterized Macros
One of the significant features of Macro facility is that we can pass parameters to a
macro, resulting in same macro being expanded into different sequences of instructions.
Parameters are of two types: Formal and Actual.
● Formal Parameters are the ones that appear in the macro header and are
preceded by an ‘&’ sign.
● Actual Parameters are the ones that appear in the macro call i.e. the
values/variables actually passed to the macros.
For example:
MACRO Add2 &arg1, &arg2 ; arg1 and arg2 are formal parameters
LOAD &arg1
ADD &arg2
STORE &arg1
MEND
.
.
.
Add2 ABC, DEF ; ABC and DEF are actual parameters
Parameters can be passed to the macro in two ways: By Position and By Keywords
● By Position: Actual parameters correspond to formal parameters by position.
Positional parameters are used by the macro processor to map actual
parameters (in the macro call) to formal parameters (in the macro
definition).
6
For example, the example given above for formal and actual
parameters uses parameters passing by position.
● By Keywords: Actual parameters correspond to formal parameters by keywords.
(Note that: The actual parameters passed by a nested macro call can begin with ‘&’
sign.)
Both the parameter passing techniques can be combined but then, all parameters passed
by position must appear before the parameters passed by keywords (in macro header as
well as in the call).
3.6 Nested Macros
Nested macro means we can use one macro within the other.
There are two ways of using Nested Macro facility:
1. Nested Macro Call
2. Nested Macro Definition
3.6.1 Nested Macro Call
When a macro is called from within the definition of another macro, it is called a Nested
Macro call.
Early Expansion: In case of Early Expansion, the inner macro call is expanded right at
the time of storing the definition of outer macro.
For example: The call to macro ADD3 in the example given above
will be expanded fully and output of the macro processor will store
following statements in its databases follows:
.
.
7
LOAD A ; macro call expanded here
ADD B
STORE A
ADD C
STORE A
.
.
Late Expansion: In case of Late Expansion, nested macro calls are expanded only when
a call to its outer macro is made.
When call to an inner macro is encountered while expanding an outer
macro, the ALA for expansion of outer macro is pushed onto stack, the
inner macro is expanded, the ALA for outer macro is popped back
from the stack and the expansion of outer macro continues.
For example: For the same code as in above example, the macro
processor will store following statements in its databases:
.
.
ADD2 A,B ; macro call not expanded while it is stored
ADD C
STORE A
.
.
When a call to outer macro ADD3 is made, inner macro Add2 gets
expanded.
.
.
LOAD A ; macro call expanded here
ADD B
STORE A
ADD C
STORE A
8
3.6.2 Nested Macro Definition
Nested Macro Definition means the call means a macro is defined within the definition of
another macro.
Expansion for nested macro definition requires a separate definition flag and an
expansion flag for each macro and MEND also requires the name of terminating macro
as its operand.
When an inner macro definition is encountered, the ALA of outer macro (and its other
related information) is pushed onto stack and a new ALA is used for the inner macro.
When inner macro definition has been processed, the ALA of outer macro is popped back
from the stack.
3.7 Conditional Macro Expansion
To achieve more dynamism than just parameterized macros, we can use the conditional
macro expansion facility.
Conditional Macro Expansion means based on evaluation of certain condition, different
sequences of instructions can be inserted into the macro body using the same macro
definition.
For conditional macro expansion, two macro pseudo-opcodes are used (also called as
“macro processor directives”).
1. AIF
2. AGO
9
3.7.1 AIF
AIF is used to evaluate a condition and depending on its result, the flow of control inside
the macro body is changed.
As a result, different statements are inserted into the macro body depending on evaluation
of the condition.
Syntax: AIF <condition> <label>
3.7.2 AGO
AGO is an unconditional branching statement for the macro processor.
Syntax: AGO <label>
(Note: The labels used here begin with a “.” and do not end with a “:”, as in case of
labels in Assembler)
For example:
3.8 Recursive Macros
Recursive macros are special cases of nested macro calls where we make a call from
within a macro to the same macro itself; it uses stack for maintaining status of macro
calls.
Conditional macro expansion (with AIF and AGO) must be used carefully here; If a
proper condition is not given to terminate the recursion, the program may go into infinite
recursive loop.
10
And as a result of it, all of the available stack space may get exhausted right at the time of
processing the macros, which is not desired at all.
3.9 Design of a Simple (Two-Pass) Macro Processor
A Simple Macro Processor performs 2 passes over the input program.
In Pass 1, it recognizes all macro definitions and stores them in data structures called
Macro Name Table (MNT) and Macro Definition Table (MDT).
In Pass 2, it recognizes macro calls and expands them by replacing with corresponding
sequences of instructions.
But it works on certain assumptions:
11
a. A macro is defined before it can be called.
b. Nested macros are not permitted. (So, definition and expansion flags for the macro
are not used here).
c. Parameters are passed by position
3.9.1 Basic Data Structures of a Simple (Two-pass) Macro Processor
A two-pass macro processor uses following data structures:
1. Macro Name Table (MNT) :
MNT stores a list of macros defined in the program along with their number of
parameters and starting location in MDT (i.e. from what index onwards they are stored in
MDT)
Pass 1 uses MNT to gather a list of macros used in the program; Pass 2 uses MNT to
check if an ALP statement is a macro call.
The structure of MNT is as follows:
Macro Name No_of_parameters MDT_Index
. . .
. . .
. . .
MNT is dynamic and its contents depend on number of macros used in the program.
12
2. Macro Definition Table (MDT) :
MDT stores the actual definitions of macros listed in MNT, along with MEND statement
to indicate the end of macro.
Pass 1 uses MDT to store the definition statements of macros listed in MNT; Pass 2 uses
MDT to retrieve the definition statements of a macro, starting from the location pointed
by “MDT Index” field of the corresponding macro entry in MNT.
The structure of MDT is as follows:
Index Statement
1
. .
. .
. .
N
MDT is also dynamic and its contents depend on all the macros used in the program.
3. Argument List Array (ALA) :
ALA is used as a temporary storage during the parameter replacement process.
Pass 1 uses ALA as a “Formal vs. Positional Parameter List” i.e. to replace formal
parameters by their respective positional parameters.
Structure of ALA in Pass 1 is as follows:
Formal Parameter Positional Parameter
&arg1 #1
. .
. .
. .
&argN #N
Pass 2 uses ALA as a “Positional vs. Actual Parameter List” i.e. to replace positional
parameters by their respective actual parameters.
13
Structure of ALA in Pass 2 is as follows:
Positional Parameter Actual Parameter
#1
.
.
.
#N
3.9.2 Pass 1 of a Simple (Two-pass) Macro Processor
Following data structures are used in Pass 1 :
1. Source ALP File
2. Macro Name Table (MNT)
3. Macro Definition Table (MDT)
4. Argument List Array (ALA)
5. Intermediate File (IF)
Additionally following pointers are also used in Pass 1:
6. MNT_PTR – To indicate the entry currently available in MNT
7. MDT_PTR – To indicate the entry currently available in MDT
[Link] Overall Pass 1 Flowchart
(Fig. 3.2 comes here)
[Link] Algorithm for Pass 1
Step 1: Initializations:
1.1 🡪 Open Source File in Read mode and Intermediate File (IF) in Write mode.
1.2 🡪 Setup MNT and MDT tables.
14
1.3 🡪 Setup MNT_PTR and MDT_PTR and point them to first entries of respective
tables.
1.4 🡪 Setup ALA for use as “Formal vs. Positional Parameter List”.
Step 2: Read a line from Source File
2.1 🡪 Is END pseudo-opcode reached?
If YES, then go to Step 3.
If NO, then continue
2.2 🡪 Read first token. Is it MACRO Keyword?
If NO, then insert it into IF, since macro calls (and regular ALP statements) will
be processed in Pass 2.
If YES, then continue
2.3 🡪 Read next token as the macro name and validate macro name from MNT.
If found in MNT, display “Duplicate Macro Definition”, set error_flag=ON and
repeat Step 2.
If not found in MNT, make its entry into MNT along with number of parameters
2.4 🡪 Refresh ALA i.e. delete all previously used entries from it and enter a positional
parameter for each formal parameter in the macro header (this indicates ALA acts
as temporary storage).
2.5 🡪 Read a line from Source File. Is MEND reached?
If YES, then write MEND into MDT using MDT_PTR, increment MDT_PTR
and repeat Step 2.
If NO, then replace formal parameters in that statement by positional parameters
using ALA and write that line into MDT using MDT_PTR. Increment MDT_PTR
and repeat Step 2.5.
15
Step 3: END Pseudo-Opcode reached
Is error_flag=OFF?
If YES, then go to Pass 2
If NO, then display “Errors in processing macros” and STOP.
At the end of Pass 1, we have following entities as output:
1. Intermediate File (IF) will contain the same source code, without any macro
definitions.
2. MNT will contain list of macros used in the program, along with starting index of
their definition in MDT.
3. MDT will store the actual definitions of the macros along with MEND for each
macro.
[Link] Overall Pass 2 Flowchart
(Fig. 3.3 comes here)
[Link] Algorithm for Pass 2
Step 1: Initializations:
1.1 🡪 Open Intermediate File (IF) in Read mode and Output File (OF) in Write mode.
1.2 🡪 Setup MNT_PTR and MDT_PTR and point them to first entries of respective
tables.
1.5 🡪 Setup ALA for use as “Positional vs. Actual Parameter List”.
Step 2: Read a line from Source File
2.1 🡪 Is END pseudo-opcode reached?
If YES, then go to Step 3.
If NO, then continue
16
2.2 🡪 Read first token. Search it in MNT. Is it a macro call?
If NO, then it is a regular ALP statement. So, insert it into OF, since it is not to be
processed by macro processor.
If YES, then continue
2.3 🡪 Validate the macro call (i.e. check number of parameters) from MNT.
If not validated from MNT, display “Error in Macro Call”, set error_flag=ON and
repeat Step 2.
If validated from MNT, then continue.
2.4 🡪 Refresh ALA i.e. delete all previously used entries from it and enter a positional
parameter for each actual parameter in the macro call.
2.5 🡪 Read a line from MDT using MDT_PTR. Is MEND reached?
If YES, repeat Step 2.
If NO, then replace positional parameters in that statement by actual parameters
using ALA and write that line into OF. Increment MDT_PTR and repeat Step 2.5.
Step 3: END Pseudo-Opcode reached
Is error_flag=OFF?
If YES, then display “Macro Processing successful” and STOP.
If NO, then display “Errors in processing macros” and STOP.
At the end of Pass 2, the ALA will be discarded and we’ll have the same source code in
output file, after expanding all the macros.
17
3.9.3 Sample Program Assembly using a Simple (Two-pass) Macro Processor:
Sample ALP Code:
START
MACRO ADD1 &arg1, &arg2
LOAD &arg1
ADD &arg2
STORE &arg1
MEND
ADD N1, N2 ; Macro call after it is defined
MACRO MUL1 &arg3, arg4
MOV A,00
MOV C, &arg4
Repeat: ADD &arg3
DEC C
JNZ Repeat
MEND
MUL1 N3, N4 ; Macro call after it is defined
ENDP
N1 DB 01
N2 DB 02
N3 DB 03
N4 DB 04
END ; End of program
Pass 1 Processing:
Pass 1 reads from Source File and writes into Intermediate File (IF). It creates MNT and
MDT depending on the macros defined in the program.
Macro Name Table (MNT):
Macro Name No_of_parameters MDT_Index
ADD1 2 1
MUL1 2 5
18
Argument List Array (ALA):
For macro ADD1:
Formal Parameter Positional Parameter
&arg1 #1
&arg2 #2
Refresh: For macro MUL1:
Formal Parameter Positional Parameter
&arg3 #1
&arg4 #2
Macro Definition Table (MDT):
Index Statement
1 LOAD #1
2 ADD #2
3 STORE #1
4 MEND
5 MOV A, 00
6 MOV C, #2
7 REPEAT: ADD #1
8 DEC C
9 JNZ REPEAT
10 MEND
Intermediate File (IF):
START
ADD N1, N2
MUL1 N3, N4
ENDP
N1 DB 01
N2 DB 02
N3 DB 03
N4 DB 04
END
19
Pass 2 Processing:
Pass 2 reads from IF and writes into OF (Output File). It uses MNT, MDT created by
Pass 1 for expanding the macro calls.
Argument List Array (ALA):
For macro ADD1:
Actual Parameter Positional Parameter
N1 #1
N2 #2
Refresh: For macro MUL1:
Actual Parameter Positional Parameter
N3 #1
N4 #2
Output File (OF):
START
LOAD N1, N2
ADD N2
STORE N1
MOV A, 00
MOV C, N4
REPEAT: ADD N3
DEC C
JNZ REPEAT
ENDP
N1 DB 01
N2 DB 02
N3 DB 03
N4 DB 04
END
20
3.10 Chapter Summary
● Macros are single-line abbreviations for a small sequence of commands.
● Macros appear functionally similar to functions (or subroutines). But there are
many fundamental differences between them.
● Macros are expanded inline i.e. the macro call is replaced by corresponding
sequence of instructions; these instructions are not actually executed.
● Functions are used to repeatedly execute a long enough sequence of instructions.
● Also, processing of macros does not require any housekeeping operations,
whereas executing functions needs return address (and sometimes current state of
the program) to be pushed onto stack.
● Functions of Macro Processor are:
o Recognize the macro definition
o Store the macro definition
o Recognize the macro call
o Expand the macro call
● Features of macro facility include:
o Parameterized Macros – Passing arguments to a macro, either by
position or by Keywords
o Nested Macros – Using one macro from within another macro
◊ Nested Macro Calls: Calling a macro from within another macro
◊ Nested Macro Definition: Defining one macro inside definition of
another macro.
o Conditionally Macro Expansion – Using AIF and AGO statements to
conditionally decide which part of code to insert into the macro body.
AIF is used as a conditional jump; AGO is used for unconditional jump.
o Recursive Macros – Calling a macro from within itself. But to limit the
depth of recursion, proper conditions must be given to terminate the
recursion.
21
● A Simple Macro Processor takes two passes to completely process and expand the
macros.
◊ In Pass 1, All macros used in the program get listed in MNT and
their definitions get stored in MDT. ALA is used to convert formal
parameters to positional parameters.
◊ In Pass 2, macro calls in the program get expanded by using MNT
and MDT. ALA is used to convert positional parameters to actual
parameters.
3.11 Expected Viva Questions:
Q.1.) What are macros? What do you mean when you say that macros are “expanded
inline”?
Q.2.) How is a macro different from a function? Do functions require a preprocessor? If
not, then how are they processed?
Q.3.) What are functions or activities of macro processor?
Q.4.) What are “default parameter” macros?
(Ans: Default parameter macros use keyword technique for parameter passing. But
some or all of the arguments have default values. If a parameter, whose default
value has been given, is not passed while calling the macro, then its default value is
taken into consideration.)
Q.5.) What do you mean by Early Expansion and Late Expansion?
Q.6.) What is the use of AIF and AGO statements?
Q.7.) What are the restrictions with a simple macro processor? (Hint: Refer to
assumptions for a simple macro processor).
22
Q.8.) Can two macros have same name? Can a macro and a procedure have same name?
(Hint: Two macros can have same name as long as their number and type of
parameters are different. A macro and procedure too can have same name, because
macros are handled during translation phase by macro processor; they begin with
MACRO keyword and procedures begin with PROC keyword. So, a macro
processor can easily differentiate between them. Moreover, by the time program
reaches execution stage, all macros get expanded. So, there would be no ambiguity
with the name of procedure, as the macro with the same name has already been
expanded.)
Q.9.) What is the use of stack with nested macros? (Refer section 3.6)
Q.10.) What are different parameter passing techniques used for macros?
23