# 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)

Figure 4.4

# Algorithm

  • Algorithm for a one-pass macro processor
    • The handling of macro definitions within macros
Figure 4.5
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)