# Introduction
- A macro represent a commonly used group of statements in the source programming language.
- The macro processor replaces each macro instruction with the corresponding group of source language statements. This is called expanding the macros.
- When to use macro?
- Suppose that it is necessary to save the contents of all registers before calling a subprogram.
- On SIC/XE, this would require a sequence of seven instructions (
STA
,STB
, etc…). - Using a macro instruction, the programmer could simply write one statement like SAVEREGS.
- A similar macro instruction (perhaps named LOADREGS) could be used to reload the register contents after returning from the subprogram.
# Macro Definition and Expansion
Figure 4.1 Each parameter begins with the character `&`
Line Source statement
5 COPY START 0 COPY FILE FROM INPUT TO OUTPUT
10 RDBUFF MACRO &INDEV,&BUFADR,&RECLTH
15 .
20 . MACRO TO READ RECORD INTO BUFFER
25 .
30 CLEAR X CLEAR LOOP COUNTER
35 CLEAR A
40 CLEAR S
45 +LDT #4096 SET MAXIMUM RECORD LENGTH
50 TD =X'&INDEV' TEST INPUT DEVICE
55 JEQ *-3 LOOP UNTIL READY
60 RD =X'&INDEV' READ CHARACTER INTO REG A
65 COMPR A,S TEST FOR END OF RECORD
70 JEQ *+11 EXIT LOOP IF EOR
75 STCH &BUFADR, X STORE CHARACTER IN BUFFER
80 TIXR T LOOP UNLESS MAXIMUM LENGTH
85 JLT *-19 HAS BEEN REACHED
90 STX &RECLTH SAVE RECORD LENGTH
95 MEND
100 WRBUFF MACRO &OUTDEV , &BUFADR, &RECLTH
105 .
110 . MACRO TO WRITE RECORD FROM BUFFER
115 .
120 CLEAR X CLEAR LOOP COUNTER
125 LDT &RECLTH
130 LDCH &BUFADR,X GET CHARACTER FROM BUFFER
135 TD =X'&OUTDEV' TEST OUTPUT DEVICE
140 JEQ *-3 LOOP UNTIL READY
145 WD =X'&OUTDEV' WRITE CHARACTER
150 TIXR T LOOP UNTIL ALL CHARACTERS
155 JLT *-14 HAVE BEEN WRITTEN
160 MEND
165 .
170 . MAIN PROGRAM
175 .
180 FIRST STL RETADR SAVE RETURN ADDRESS
190 CLOOP RDBUFF F1,BUFFER,LENGTH READ RECORD INTO BUFFER
195 LDA LENGTH TEST FOR END OF FILE
200 COMP #0
205 JEQ ENDFIL EXIT IF EOF FOUND
210 WRBUFF 05,BUFFER,LENGTH WRITE OUTPUT RECORD
215 J CLOOP LOOP
220 ENDFIL WRBUFF 05,EOF,THREE INSERT EOF MARKER
225 J @RETADR
230 EOF BYTE C'EOF '
235 THREE WORD 3
240 RETADR RESW 1
245 LENGTH RESW 1 LENGTH OF RECORD
250 BUFFER RESB 4096 4096-BYTE BUFFER AREA
255 END FIRST
Figure 4.2 The arguments and parameters are associated with one another according to their positions
Line Source statement
5 COPY START 0 COPY FILE FROM INPUT TO OUTPUT
180 FIRST STL RETADR SAVE RETURN ADDRESS
190 .CLOOP RDBUFF Fl,BUFFER,LENGTH READ RECORD INTO BUFFER
190a CLOOP CLEAR X CLEAR LOOP COUNTER
190b CLEAR A
190c CLEAR S
190d +LDT #4096 SET MAXIMUM RECORD LENGTH
190e TD =X'Fl' TEST INPUT DEVICE
190f JEQ *-3 LOOP UNTIL READY
190g RD =X'Fl' READ CHARACTER INTO REG A
190h COMPR A,S TEST FOR END OF RECORD
190i JEQ *+11 EXIT LOOP IF EOR
190j STCH BUFFER,X STORE CHARACTER IN BUFFER
190k TIXR T LOOP UNLESS MAXIMUM LENGTH
190l JLT *-19 HAS BEEN REACHED
190m STX LENGTH SAVE RECORD LENGTH
195 LDA LENGTH TEST FOR END OF FILE
200 COMP #0
205 JEQ ENDFIL EXIT IF EOF FOUND
210 WRBUFF 05,BUFFER,LENGTH WRITE OUTPUT RECORD
210a CLEAR X CLEAR LOOP COUNTER
210b LDT LENGTH
210c LDCH BUFFER, X GET CHARACTER FROM BUFFER
210d TD =X'05' TEST OUTPUT DEVICE
210e JEQ *-3 LOOP UNTIL READY
210f WD =X'05' WRITE CHARACTER
210g TIXR T LOOP UNTIL ALL CHARACTERS
210h JLT *-14 HAVE BEEN WRITTEN
215 J CLOOP LOOP
220 .ENDFIL WRBUFF 05,EOF,THREE INSERT EOF MARKER
220a ENDFIL CLEAR X CLEAR LOOP COUNTER
220b LDT THREE
220c LDCH EOF, X GET CHARACTER FROM BUFFER
220d TD =X'05' TEST OUTPUT DEVICE
220e JEQ *-3 LOOP UNTIL READY
220f WD =X'05' WRITE CHARACTER
220g TIXR T LOOP UNTIL ALL CHARACTERS
220h JLT *-14 HAVE BEEN WRITTEN
225 J @RETADR
230 EOF BYTE C'EOF'
235 THREE WORD 3
240 RETADR RESW 1
245 LENGTH RESW 1 LENGTH OF RECORD
250 BUFFER RESB 4096 4096-BYTE BUFFER AREA
255 END FIRST
# Macro Processor Algorithm and Data Structures
- It is easy to design a two-pass macro processor in which all macro definitions are processed during the first pass, and all macro invocation statements are expanded during the second pass.
- However, such a two-pass macro processor would not allow the body of one macro instruction to contain definitions of other macros.
Figure 4.3 Definitions of macros by other macros can be useful in certain cases
1 MACROS MACRO {Defines SIC standard version macros}
2 RDBUFF MACRO &INDEV,&BUFADR,&RECLTH
.
. {SIC standard version}
.
3 MEND {End of RDBUFF}
4 WRBUFF MACRO &OUTDEV,&BUFADR,&RECLTH
.
. {SIC standard version}
.
5 MEND {End of WRBUFF}
.
.
.
6 MEND {End of MACROS}
(a)
1 MACROX MACRO {Defines SIC/XE macros}
2 RDBUFF MACRO &INDEV,&BUFADR,&RECLTH
.
. {SIC/XE version}
.
3 MEND {End of RDBUFF}
4 WRBUFF MACRO &OUTDEV,&BUFADR,&RECLTH
.
. {SIC/XE version}
.
5 MEND {End of WRBUFF}
.
.
.
6 MEND {End of MACROX}
(b)
- The same program could run on either a standard SIC machine or a SIC/XE machine.
- The only change required would be the invocation of either MACROS or MACROX
- Defining MACROS or MACROX does not define RDBUFF and the other macro instructions. These definitions are processed only when an invocation of MACROS or MACROX is expanded
# Data Stucture
- Definition table (DEFTAB)
- Reference to the macro instruction parameters are converted to a positional notation for efficiency in substituting arguments
- Name table (NAMTAB), serving as an index to DEFTAB
- Argument table (ARGTAB)
# Algorithm
- Algorithm for a one-pass macro processor
- The handling of macro definitions within macros
procedure DEFINE | |
begin | |
enter macro name into NAMTAB | |
enter macro prototype into DEFTAB | |
LEVEL := 1 | |
while LEVEL > 0 do | |
begin | |
GETLINE | |
if this is not a comment line then | |
begin | |
substitute positional notation for parameters | |
enter line into DEFTAB | |
if OPCODE = 'MACRO' then | |
LEVEL := LEVEL + 1 | |
else if OPCODE = 'MEND' then | |
LEVEL := LEVEL - 1 | |
end {if not comment} | |
end {while} | |
store in NAMTAB pointers to beginning and end of definition | |
end {DEFINE} | |
procedure EXPAND | |
begin | |
EXPANDING := TRUE | |
get first line of macro definition {prototype} from DEFTAB | |
set up arguments from macro invocation in ARGTAB | |
write macro invocation to expanded file as a comment | |
while not end of macro definition do | |
begin | |
GETLINE | |
PROCESSLINE | |
end {while} | |
EXPANDING := FALSE | |
end {EXPAND} | |
procedure GETLINE | |
begin | |
if EXPANDING then | |
begin | |
get next line of macro definition from DEFTAB | |
substitute arguments from ARGTAB for positional notation | |
end {if} | |
else | |
read next line from input file | |
end {GETLINE} |
- Most macro processors allow the definitions of commonly used macro instructions to appear in a standard system library, rather than in the source program.
# Concatenation of Macro Parameters
- Suppose that a program contains one series of variables named by the symbols XA1, XA2, XA3…, another series named by XB1, XB2, XB3… If similar processing is to be performed on each series of variables, the programmer might want to incorporate this processing into a macro instruction.
- The parameter to such a macro instructin could specify the series of variables to be operated on. The macro processor would use this parameter to construct the symbols required in the macro expansion.
Figure 4.6
1 SUM MACRO &ID
2 LDA X&ID-->1
3 ADD X&ID-->2
4 ADD X&ID-->3
5 STA X&ID-->S
6 MEND
(a)
SUM A
|
|
\|/
LDA XAl
ADD XA2
ADD XA3
STA XAS
(b)
SUM BETA
|
|
\|/
LDA XBETAl
ADD XBETA2
ADD XBETA3
STA XBETAS
(c)
# Generation of Unique Labels
- It is general not possible for the body of a macro instruction to contain labels of the usual kind. This leads to the use of relative addressing at the source statement level.
- However, the use of statements like
JLT *-14
is generally considered to be a poor programming practice
Figure 4.7 illustrates one technique for generating unique labels within a macro expansion
The character $
will be replaced by $XX, where XX is a two-character alphanumeric counter of the number of macro instructions expanded, AA, AB, AC, etc.
25 RDBUFF MACRO &INDEV,&BUFADR,&RECLTH
30 CLEAR X CLEAR LOOP COUNTER
35 CLEAR A
40 CLEAR S
45 +LDT #4096 SET MAXIMUM RECORD LENGTH
50 $LOOP TD =X'&INDEV' TEST INPUT DEVICE
55 JEQ $LOOP LOOP UNTIL READY
60 RD =X'&INDEV' READ CHARACTER INTO REG A
65 COMPR A,S TEST FOR END OF RECORD
70 JEQ $EXIT EXIT LOOP IF EOR
75 STCH &BUFADR,X STORE CHARACTER IN BUFFER
80 TIXR T LOOP UNLESS MAXIMUM LENGTH
85 JLT $LOOP HAS BEEN REACHED
90 $EXIT STX &RECLTH SAVE RECORD LENGTH
95 MEND
(a)
RDBUFF Fl,BUFFER,LENGTH
30 CLEAR X CLEAR LOOP COUNTER
35 CLEAR A
40 CLEAR S
45 +LDT #4096 SET MAXIMUM RECORD LENGTH
50 $AALOOP TD =X'Fl' TEST INPUT DEVICE
55 JEQ $AALOOP LOOP UNTIL READY
60 RD =X'Fl' READ CHARACTER INTO REG A
65 COMPR A,S TEST FOR END OF RECORD
70 JEQ $AAEXIT EXIT LOOP IF EOR
75 STCH BUFFER,X STORE CHARACTER IN BUFFER
80 TIXR T LOOP UNLESS MAXIMUM LENGTH
85 JLT $AALOOP HAS BEEN REACHED
90 $AAEXIT STX LENGTH SAVE REJORD LENGTH
(b)
# Conditional Macro Expansion
Figure 4.8
25 RDBUFF MACRO &INDEV, &BUFADR , &RECLTH ,&EOR ,&MAXLTH
26 IF (&EOR NE ")
27 &EORCK SET 1
28 ENDIF
30 CLEAR X CLEAR LOOP COUNTER
35 CLEAR A
38 IF (&EORCK EQ 1 )
40 LDCH =X'&EOR' SET EOR CHARACTER
42 RMO A,S
43 ENDIF
44 IF (&MAXLTH EQ '')
45 +LDT #4096 SET MAX LENGTH = 4096
46 ELSE
47 +LDT #&MAXLTH SET MAXIMUM RECORD LENGTH
48 ENDIF
50 $LOOP TD =X'&INDEV' TEST INPUT DEVICE
55 JEQ $LOOP LOOP UNTIL READY
60 RD =X'&INDEV' READ CHARACTER INTO REG A
63 IF (&EORCK EQ 1 )
65 COMPR A,S TEST FOR END OF RECORD
70 JEQ $EXIT EXIT LOOP IF EOR
73 ENDIF
75 STCH &BUFADR ,X STORE CHARACTER IN BUFFER
80 TIXR T LOOP UNLESS MAXIMUM LENGTH
85 JLT $LOOP HAS BEEN REACHED
90 $EXIT STX &RECLTH SAVE RECORD LENGTH
95 MEND
(a)
RDBUFF F3,BUF,RECL,04,2048
30 CLEAR X CLEAR LOOP COUNTER
35 CLEAR A
40 LOCH =X'04' SET EOR CHARACTER
42 RMO A,S
47 +LDT #2048 SET MAXIMUM RECORD LENGTH
50 $AALOOP TD =X'F3' TEST INPUT DEVICE
55 JEQ $AALOOP LOOP UNTIL READY
60 RD =X'F3' READ CHARACTER INTO REG A
65 COMPR A,S TEST FOR END OF RECORD
70 JEQ $AAEXIT EXIT LOOP IF EOR
75 STCH BUF,X STORE CHARACTER IN BUFFER
80 TIXR T LOOP UNLESS MAXIMUM LENGTH
85 JLT $AALOOP HAS BEEN REACHED
90 $AAEXIT STX RECL SAVE RECORD LENGTH
(b)
?RDBUFF OE,BUFFER,LENGTH,,80
30 CLEAR X CLEAR LOOP COUNTER
35 CLEAR A
47 +LDT #80 SET MAXIMUM RECORD LENGTH
50 $ABLOOP TD =X'OE' TEST INPUT DEVICE
55 JEQ $ABLOOP LOOP UNTIL READY
60 RD =X'OE' READ CHARACTER INTO REG A
75 STCH BUFFER,X STORE CHARACTER IN BUFFER
80 TIXR T LOOP UNLESS MAXIMUM LENGTH
87 JLT $ABLOOP HAS BEEN REACHED
90 $ABEXIT STX LENGTH SAVE RECORD LENGTH
(c)
RDBUFF Fl,BUFF,RLENG,04
30 CLEAR X CLEAR LOOP COUNTER
35 CLEAR A
40 LDCH =X'04' SET EOR CHARACTER
42 RMO A,S
45 +LDT #4096 SET MAX LENGTH = 4096
50 $ACLOOP TD =X'Fl' TEST INPUT DEVICE
55 JEQ $ACLOOP LOOP UNTIL READY
60 RD =X'Fl' READ CHARACTER INTO REG A
65 COMPR A,S TEST FOR END OF RECORD
70 JEQ $ACEXIT EXIT LOOP IF EOR
75 STCH BUFF, X STORE CHARACTER IN BUFFER
80 TIXR T LOOP UNLESS MAXIMUM LENGTH
85 JLT $ACLOOP HAS BEEN REACHED
90 $ACEXIT STX RLENG SAVE RECORD LENGTH
(d)
- Two additional parameters: &EOR and &MAXLTH for conditional macro expansion
- IF statement
- Macro processor directive SET
- Macro-time variable, beginning with the character & for storing working values during the macro expansion. All such variables are initialized to a value of 0.
- It is extremely important to understand that the testing of Boolean expression in IF statements occurs at the time macros are expanded, not during program execution.
Figure 4.9
25 RDBUFF MACRO &INDEV,&BUFADR,&RECLTH,&EOR
27 &EORCT SET %NITEMS(&EOR)
30 CLEAR X CLEAR LOOP COUNTER
35 CLEAR A
45 +LDT #4096 SET MAX LENGTH = 4096
50 $LOOP TD =X'&INDEV' TEST INPUT DEVICE
55 JEQ $LOOP LOOP UNTIL READY
60 RD =X'&INDEV' READ CHARACTER INTO REG A
63 &CTR SET 1
64 WHILE (&CTR LE &EORCT)
65 COMP =X'0000&EOR[&CTR]'
70 JEQ $EXIT
71 &CTR SET &CTR+l
73 ENDW
75 STCH &BUFADR,X STORE CHARACTER IN BUFFER
80 TIXR T LOOP UNLESS MAXIMUM LENGTH
85 JLT $LOOP HAS BEEN REACHED
90 $EXIT STX &RECLTH SAVE RECORD LENGTH
100 MEND
(a)
RDBUFF F2,BUFFER,LENGTH,(00,03,04)
30 CLEAR X CLEAR LOOP COUNTER
35 CLEAR A
45 +LDT #4096 SET MAX LENGTH = 4096
50 $AALOOP TD =X'F2' TEST INPUT DEVICE
55 JEQ $AALOOP LOOP UNTIL READY
60 RD =X'F2' READ CHARACTER INTO REG A
65 COMP =X'000000'
70 JEQ $AAEXIT
65 COMP =X'000003'
70 JEQ $AAEXIT
65 COMP =X'000004'
70 JEQ $AAEXIT
75 STCH BUFFER,X STORE CHARACTER IN BUFFER
80 TIXR T LOOP UNLESS MAXIMUM LENGTH
85 JLT $AALOOP HAS BEEN REACHED
90 $AAEXIT STX LENGTH SAVE RECORD LENGTH
(b)
- Looping statement WHILE
- A list (00, 03, 04) corresponding to the parameter &EOR
- %NITEMS is a macro processor function that returns as its value the number of members in an argument list
- &EOR[&CTR]
# Keyword Macro Parameters
- With positional parameters, if an argument is to be omitted, the macro invocation statement must contain a null argument (two consecutive commas) to maintain the correct argument positions
- However, if a macro has a large number of parameters, and only a few of these are given values in a typical invocation, a different form of parameter specification is more useful
- Perhaps an entire operating system is to be generated from a macro invocation. In such cases, most of the parameters may have acceptable default values; the macro invocation specifies only the changes from the default set of values.
- GENER ,DIRECT,3
- GENER TYPE=DIRECT, CHANGE=3
Figure 4.10
25 RDBUFF MACRO &INDEV=F1,&BUFADR=,&RECLTH=,&EOR=04,&MAXLTH=4096
26 IF (&EOR NE ")
27 &EORCK SET 1
28 ENDIF
30 CLEAR X CLEAR LOOP COUNTER
35 CLEAR A
38 IF (&EORCK EQ 1)
40 LDCH =X'&EOR' SET EOR CHARACTER
42 RMO A,S
43 ENDIF
47 +LDT #&MAXLTH SET MAXIMUM RECORD LENGTH
50 $LOOP TD =X'&INDEV' TEST INPUT DEVICE
55 JEQ $LOOP LOOP UNTIL READY
60 RD =X'&INDEV' READ CHARACTER INTO REG A
63 IF (&EORCK EQ 1)
65 COMPR A,S TEST FOR END OF RECORD
70 JEQ $EXIT EXIT LOOP IF EOR
73 ENDIF
75 STCH &BUFADR ,X STORE CHARACTER IN BUFFER
80 TIXR T LOOP UNLESS MAXIMUM LENGTH
85 JLT $LOOP HAS BEEN REACHED
90 $EXI T STX &RECLTH SAVE RECORD LENGTH
95 MEND
(a)
RDBUFF BUFADR=BUFFER,RECLTH=LENGTH
30 CLEAR X CLEAR LOOP COUNTER
35 CLEAR A
40 LDCH =X'04' SET EOR CHARACTER
42 RMO A, S
47 +LDT #4096 SET MAXIMUM RECORD LENGTH
50 $AALOOP TD =X'F1' TEST INPUT DEVICE
55 JEQ $AALOOP LOOP UNTIL READY
60 RD =X'F1' READ CHARACTER INTO REG A
65 COMPR A,S TEST FOR END OF RECORD
70 JEQ $AAEXIT EXIT LOOP IF EOR
75 STCH BUFFER,X STORE CHARACTER IN BUFFER
80 TIXR T LOOP UNLESS MAXIMUM LENGTH
85 JLT $AALOOP HAS BEEN REACHED
90 $AAEXIT STX LENGTH SAVE RECORD LENGTH
(b)
RDBUFF RECLTH=LENGTH,BUFADR=BUFFER,EOR=,INDEV=F3
30 CLEAR X CLEAR LOOP COUNTER
35 CLEAR A
47 +LDT #4096 SET MAXIMUM RECORD LENGTH
50 $ABLOOP TD =X'F3' TEST INPUT DEVICE
55 JEQ $ABLOOP LOOP UNTIL READY
60 RD =X'F3' READ CHARACTER INTO REG A
75 STCH BUFFER, X STORE CHARACTER IN BUFFER
80 TIXR T LOOP UNLESS MAXIMUM LENGTH
85 JLT $ABLOOP HAS BEEN REACHED
90 $ABEXIT STX LENGTH SAVE RECORD LENGTH
(c)
- Default values can simplify the macro definition in many cases
- Figure 4.10(a) and 4.8(a) both provide for setting the maximum record length to 4096 unless a different value is specified by the user.
- The default value established in Figure 4.10(a) takes care if this automatically
- In Figure 4.8(a), an IF-ELSE-ENDIF structure is required to accomplish the same thing
# Recursive Macro Expansion
Figure 4.11 Nested macro invocation
10 RDBUFF MACRO &BUFADR,&RECLTH,&INDEV
15 .
20 . MACRO TO READ RECORD INTO BUFFER
25 .
30 CLEAR X CLEAR LOOP COUNTER
35 CLEAR A
40 CLEAR S
45 +LDT #4096 SET MAXIMUM RECORD LENGTH
50 $LOOP RDCHAR &INDEV READ CHARACTER INTO REG A
65 COMPR A,S TEST FOR END OF RECORD
70 JEQ $EXIT EXIT LOOP IF EOR
75 STCH &BUFADR,X STORE CHARACTER IN BUFFER
80 TIXR T LOOP UNLESS MAXIMUM LENGTH
85 JLT $LOOP HAS BEEN REACHED
90 $EXIT STX &RECLTH SAVE RECORD LENGTH
95 MEND
(a)
5 RDCHAR MACRO &IN
10 .
15 . MACRO TO READ CHARACTER INTO REGISTER A
20 .
25 TD =X'&IN' TEST INPUT DEVICE
30 JEQ *-3 LOOP UNTIL READY
35 RD =X'&IN' READ CHARACTER
40 MEND
(b)
RDBUFF BUFFER,LENGTH,FI
(c)
- When applying the algorithm of Figure 4.5 to the macro invocation statement in Figure 4.11©
- When the end of the definition of RDCHAR was recognized, EXPANDING would be set to FALSE. Thus the macro processor would forget that it had been in the middle of expanding a macro when it encountered the RDCHAR statement
- The arguments from the original macro invocation (RDBUFF) would be lost because the values in ARGTAB were overwritten with the arguments from the invocation of RDCHAR
# General-Purpose Macro Processors
- The advantage of a general-purpose approach to macro processing is that the programmer does not need to learn about a different macro facility for each compiler or assembler language.
- In spite of the advantages noted, there are still relatively few general-purpose macro processors. One of the reasons for this situation is the large number of details that must be dealt with in a real programming language.
- In a typical programming language, there are several situations in which normal macro parameter substitution should not occur
- For example, comments should usually be ignored by a macro processor.
- However, each programming language has its own methods for identifying comments.
- With most special-purpose macro processors, macro invocations are very similar in form to statements in the source programming language. This similarity of form tends to make the source program easier to write and read.
- However, it is difficult to achieve with a general-purpose macro processor that is to be used with different programming languages.
# Macro Processing within Language Translators
- The macro processors that we have discussed so far might be called preprocessors.
- They process macro definitions and expand macro invocations, producing an expanded version of the source program. This expanded program is then used as input to an assembler or compiler.
- An alternative is combining the macro processing functions with the language translator itself.
- The simplest method of achieving this sort of combination is a line-by-line macro processor.
- The output lines are passed to the language translator as they are generated (one at a time), instead of being written to an expanded source file.
- Thus the macro processor operates as a sort of input routine for the assembler or compiler.
- This line-by-line approach has several advantages.
- It avoids making an extra pass over the source program, so it can be more efficient.
- Some of the data structures required by the macro processor and the language translator can be combine.
- ex. OPTAB in an assembler and NAMTAB in the macro processor could be implemented in the same table.
# Implement Example
# MASM Macro Processor
- The macro processor of MASM is integrated with Pass 1 of the assembler.
- Macro may be redefined during a program. The new definition of the macro simply replaces the first one.
Figure 4.12 Conditional assembly statements.
- Line 2 declare that EXIT is a local label. When the macro is expanded, each local label is replaced by a unique name.
- The .ERR on line 6 signals to MASM that an error has been detected, and the EXITM directs MASM to terminate the expansion of the macro.
- The comment on line 9, which begins with
;;
is a macro comment. - The comment on line 10, which begins with
;
is an ordinary assembler language comment. It is included as part of the macro expansion.
1 ABSDIF MACRO OP1,OP2,SIZE
2 LOCAL EXIT
3 IFNB <SIZE> ;; IF SIZE IS NOT BLANK
4 IFDIF <SIZE>,<E> ;; THEN IT MUST BE E
5 ; ERROR -- SIZE MUST BE E OR BLANK
6 .ERR
7 EXITM
8 ENDIF ;; END OF IFDIF
9 ENDIF ;; END OF IFNB
10 MOV SIZE&AX,OP1 ; COMPUTE ABSOLUTE DIFFERENCE
11 SUB SIZE&AX,OP2 ;; SUBTRACT OP2 FROM OP1
12 JNS EXIT ;; EXIT IF RESULT GE 0
13 NEG SIZE&AX ;; OTHERWI SE CHANGE SIGN
14 EXIT:
15 ENDM
(a)
ABSDIF J,K
|
|
\|/
MOV AX,J ; COMPUTE ABSOLUTE DIFFERENCE
SUB AX,K
JNS ??0000
NEG AX
??0000:
(b)
ABSDIF M,N,E
|
|
\|/
MOV EAX,M ; COMPUTE ABSOLUTE DIFFERENCE
SUB EAX,N
JNS ??0001
NEG EAX
??0001:
(e)
ABSDIF P,Q,X
|
|
\|/
; ERROR -- SIZE MUST BE E OR BLANK
Figure 4.13 Iteration statements.
?1 NODE MACRO NAME
2 IRP S,<'LEFT','DATA','RIGHT'>
3 NAME&S DW 0
4 ENDM ;; END OF IRP
5 ENDM ;; END OF MACRO
(a)
NODE X
|
|
\|/
XLEFT DW 0
XDATA DW 0
XRIGHT DW 0
(b)