Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

Exp 9 SPCC

Download as pdf or txt
Download as pdf or txt
You are on page 1of 14

Experiment No.

09
Date:
Roll No:

Aim: Write a C program to implement two pass Macro processor .


Theory:
Macro instruction is a notational convenience for the programmer. For every occurrence of
macro, the whole macro body or macroblock of statements gets expanded in the main source
code. Thus Macro instructions make writing code more convenient.
macro definition may be written using formal parameters . A macro call on such a macro
specifies actual parameters.
Salient features of Macro Processor:
● Macro represents a group of commonly used statements in the source programming
language.
● Macro Processor replaces each macro instruction with the corresponding group of
source language statements. This is known as the expansion of macros.
● Using Macro instructions programmers can leave the mechanical details to be handled
by the macro processor.
● Macro Processor designs are not directly related to the computer architecture on
which it runs.
● Macro Processor involves definition, invocation, and expansion.
Macro Expansion can be performed by using two kinds of language processors and when we
use a macro name with a set of actual parameters it is replaced by the same code generated
from its body .This is called macro expansion.

Macro Definition and Call


● It has been aforementioned that a macro consists of a name, a set of formal
parameters, and a body of codes.
● A macro can be defined by enclosing a set of statements between a macro header and
a macro end statement.
● The formal structure of a macro includes the following features:
○ Macro prototype statement: Specifies the name of the macro and name and
type of formal parameters.
○ Model statements: Specify the statements in the body of the macro from which
assembly language statements are to be generated during expansion.
○ Macro preprocessor statement: Specifies the statement used for performing
auxiliary function during macro expansion.
● A macro prototype statement can be written as follows:
<name_of_macro> [<formal parameter spec> [,...]]
where [<formal parameter spec> [,...]] defines the parameter name and its kind,
which are of the following form:
&<name_of_parameter> [<parameter_type>]

● A macro can be called by writing the name of the macro in the mnemonic field of the
assembly language. The syntax of a typical macro call can be of the following form:
<name_of_macro> [<actual_parameter_spec> [,…]]
● Eg.
Macro Definition:
MACRO
INCR &MEM_VAL, &INC_VAL, &REG
MOVER &REG &MEM_VAL
ADD &REG &INC_VAL
MOVEM &REG &MEM_VAL
MEND

Macro Call:
INCR A, B

PASS I MACRO DEFINITION


The algorithm tests for each input line. If it is a MACRO pseudo operation, the entire macro
definition that follows is saved in the next available location in the macro definition table.
The first line of the definition is the macro name line. The name is entered in to the macro
name table (MNT), along with a pointer to the first location of the MDT entry of the
definition. When the END pseudo op is encountered all of the macro definitions have been
processed, so control transfers to pass 2. The entire algorithm is explained in pass 1
flowchart.

Pass 1 of Macro Processor - Processing Macro Definitions

1. Initialize MDTC and MNTC.


2. Read the next source statement of the program.
3. If the statement contains MACRO pseudo-op. go to Step 6.
4. Output the instruction of the program.
5. If the statement contains END pseudo-op, go to Pass 2, else go to Step 2.

6. Read the next source statement of the program.


7. Make an entry of the macro name and MTDC into MNT at location MNTC and increment
the MNTC by 1.
8. Prepare the parameter (arguments) list array.
9. Enter macro name into the MDT and increment the MTDC by 1.
10. Read the next card and substitute index for the parameters (arguments).
11. Enter the statement into the MDT and increment the MDT by 1.
12. If MEND pseudo-op is found, go to Step 2, else go to Step 10.

Pass1 database
1. Input source
2. Output macro source deck copy for use by pass2
3. MDT used to store the body of the macro definitions.
4. The macro name table (MNT) used to store the names of defined macros.
5. The macro definition table counter (MDTC) used to indicate the next available entry in the
MDT.
6. The macro name table counter(MNTC)used to indicate the next available entry in the MNT
7. The Argument List Array (ALA) used to substitute index markers for dummy arguments
before storing a macro definition.

PASS 2 MACRO CALLS AND EXPANSION


When a macro call is found, the call processor sets a pointer, the MDTP, to the corresponding
macro definitions stored in the MDT. The initial value of the MDTP is obtained from the
MDT index field of the MNT entry. The macro expander prepares the ALA consisting of a
table of dummy arguments indicates and corresponding arguments to the call. Reading
proceeds from the MDT, as each successive line is read, the values from the argument list are
substituted for dummy arguments indicates in the macro definition. Reading of the MEND
line in the MDT terminates expansion of the macro and scanning continues from the input
file. When the END op is encountered the expanded source is transferred to the assembler for
further processing. The entire algorithm is explained in pass 2 flowchart.

Pass 2 of Macro Processor - Processing for Calls and Expansion of Macro

1. Read the next source statement copied by pass 1.


2. Search into the MNT for record and evaluate the operation code.
3. If the operation code has a macro name, go to Step 5.
4. Write the statement to the expanded source file.
5. If END pseudo-op is found, pass the entire expanded code to the assembler for assembling
and stop. Else go to Step 1.
6. Update the MDTP to the MDT index from the MNT entry.
7. Prepare the parameter (argument) list array.
8. Increment the MDTP by 1.
9. Read the statement from the current MDT and substitute actual parameters (arguments)
from the macro call.
10. If the statement contains MEND pseudo-op, go to Step 1, else write the expanded source
code and go to Step 8.

Pass 2 database

1. The copy of the input macro source deck 2. Expanded source output
3. MDT created by pass 1
4. MNT created by pass 1
5. MDTP used to indicate the next line of text to be used during macro expansion.
6. The ALA used to substitute macro call arguments for the index markers in the stored
macro definition.
Code:
A. PASS1 Program

#include<stdio.h>
#include<conio.h>
#include<string.h>
#include<stdlib.h>
void main()
{
FILE *f1,*f2,*f3,*f4,*f5;
int len,i,pos=1;
char arg[20],mne[20],opnd[20],la[20],name[20],mne1[20],opnd1[20],pos1[10],pos2[10];
clrscr();
f1=fopen("input.txt","r");
f2=fopen("namtab.txt","w+");
f3=fopen("deftab.txt","w+");
f4=fopen("argtab.txt","w+");
f5=fopen("op.txt","w+");
fscanf(f1,"%s%s%s",la,mne,opnd);
while(strcmp(mne,"END")!=0)
{
if(strcmp(mne,"MACRO")==0)
{
fprintf(f2,"%s\n",la);
fseek(f2,SEEK_SET,0);
fprintf(f3,"%s\t%s\n",la,opnd);
fscanf(f1,"%s%s%s",la,mne,opnd);
while(strcmp(mne,"MEND")!=0)
{
if(opnd[0]=='&')
{
itoa(pos,pos1,5);
strcpy(pos2,"?");
strcpy(opnd,strcat(pos2,pos1));
pos=pos+1;
}
fprintf(f3,"%s\t%s\n",mne,opnd);
fscanf(f1,"%s%s%s",la,mne,opnd);
}
fprintf(f3,"%s",mne);
}
else
{
fscanf(f2,"%s",name);
if(strcmp(mne,name)==0)
{
len=strlen(opnd);
for(i=0;i<len;i++)
{
if(opnd[i]!=',')
fprintf(f4,"%c",opnd[i]);
else
fprintf(f4,"\n");
}
fseek(f3,SEEK_SET,0);
fseek(f4,SEEK_SET,0);
fscanf(f3,"%s%s",mne1,opnd1);
fprintf(f5,".\t%s\t%s\n",mne1,opnd);
fscanf(f3,"%s%s",mne1,opnd1);
while(strcmp(mne1,"MEND")!=0)
{
if((opnd[0]=='?'))
{
fscanf(f4,"%s",arg);
fprintf(f5,"-\t%s\t%s\n",mne1,arg);
}
else
fprintf(f5,"-\t%s\t%s\n",mne1,opnd1);
fscanf(f3,"%s%s",mne1,opnd1);
}
}
else
fprintf(f5,"%s\t%s\t%s\n",la,mne,opnd);
}
fscanf(f1,"%s%s%s",la,mne,opnd);
fprintf(f5,"%s\t%s\t%s",la,mne,opnd);
fclose(f1);
fclose(f2);
fclose(f3);
fclose(f4);
fclose(f5);
printf("files to be viewed \n");
printf("1. argtab.txt\n");
printf("2. namtab.txt\n");
printf("3. deftab.txt\n");
printf("4. op.txt\n");
getch();
}

Output:
input.txt

op.txt:
deftab.txt:

argtab.txt:
namtab.txt:

B. PASS2 Program

#include<stdio.h>
#include<conio.h>
#include<string.h>
#include<stdlib.h>
void main()
{
FILE *f1,*f2,*f3,*f4,*f5;
int i,len;
char mne[20],opnd[20],la[20],name[20],mne1[20],opnd1[20],arg[20];
clrscr();
f1=fopen("minp2.txt","r");
f2=fopen("ntab2.txt","r");
f3=fopen("dtab2.txt","r");
f4=fopen("atab2.txt","w+");
f5=fopen("op2.txt","w");
fscanf(f1,"%s%s%s",la,mne,opnd);
while(strcmp(mne,"END")!=0)
{
if(strcmp(mne,"MACRO")==0)
{
fscanf(f1,"%s%s%s",la,mne,opnd);
while(strcmp(mne,"MEND")!=0)
fscanf(f1,"%s%s%s",la,mne,opnd);
}
else
{
fscanf(f2,"%s",name);
if(strcmp(mne,name)==0)
{
len=strlen(opnd);
for(i=0;i<len;i++)
{
if(opnd[i]!=',')
fprintf(f4,"%c",opnd[i]);
else
fprintf(f4,"\n");
}
fseek(f2,SEEK_SET,0);
fseek(f4,SEEK_SET,0);
fscanf(f3,"%s%s",mne1,opnd1);
fprintf(f5,".\t%s\t%s\n",mne1,opnd);
fscanf(f3,"%s%s",mne1,opnd1);
while(strcmp(mne1,"MEND")!=0){
if((opnd1[0]=='&')){
fscanf(f4,"%s",arg);
fprintf(f5,"-\t%s\t%s\n",mne1,arg);
}
else
fprintf(f5,"-\t%s\t%s\n",mne1,opnd1);
fscanf(f3,"%s%s",mne1,opnd1);
}}
else
fprintf(f5,"%s\t%s\t%s\n",la,mne,opnd);
}
fscanf(f1,"%s%s%s",la,mne,opnd);
}
fprintf(f5,"%s\t%s\t%s\n",la,mne,opnd);
fclose(f1);
fclose(f2);
fclose(f3);
fclose(f4);
fclose(f5);
printf("pass2");
getch();
}
Output:

minp2.txt:
dtab2.txt:

Op2.txt:
ntab2.txt:

atab2.txt:

Conclusion: Here, we have understood the Pass1 and Pass2 of two pass macro processors
and implemented it using c.

You might also like