Implementing Multi-pass Assembler in C

Here is implementation of multi-pass assembler in C. You have to provide Assembly Language Program, MOT table and POT table as input.

#include<stdio.h>
#include<conio.h>
#include<math.h>
#include<stdlib.h>
#define NULL 0

struct mot
{
char mnemo[6];
int opcode,no_opnds,loi;
};

struct pot
{
char ps_opcode[6];
int opnds;
};

struct alp
{
char label[7],mne[7],opnd[30];
};

struct st
{
char sym[10],type[10];
int sym_add;
};

struct of
{
int lc,mac_code,add;
};

struct addnvalue
{
int addr,value;
};

struct addnvalue add_const[15];
struct mot m[12];
struct pot p[9];
struct alp a[25];
struct st s[15];
struct of o[25];

int searchmot(char str[]);
int searchpot(char str[]);
int searchst(char str[]);
int str2num(char str[]);
int getvalue(int add);
void pass1();
void pass2();

int motptr,poptr,endpos,nmot,npot,nacode,nadata,lc,error,flagm,flagp;
int naot,nast,stptr,firstloc,flagst;

void main()
{
int i,j,k,c,len,x;
char str[8],str1[8],str2[30],ch;
FILE *fp;
clrscr();
fp=fopen("mot.txt","r");
if(fp==NULL)
 {
  printf("'mot.txt' File Does not exist!!");
  exit(0);
 }

 else
 {
  i=0;
  while(!feof(fp))
  {
   fscanf(fp,"%s %d %d %d",&m[i].mnemo,&m[i].opcode,&m[i].no_opnds,&m[i].loi);
   i++;
  }
   nmot=i;
   fclose(fp);
 }
 fp=fopen("pot.txt","r");
 if(fp==NULL)
 {
  printf("'pot.txt'File does not exist!");
  exit(0);
 }
 else
 {
  i=0;
  while(!feof(fp))
  {
   fscanf(fp,"%s %d",&p[i].ps_opcode,&p[i].opnds);
   i++;
  }
   npot=i;
   fclose(fp);
 }
  fp=fopen("alp.txt","r");
  if(fp==NULL)
   printf("'alp.txt'File does not exist\n");
  else
   {
    i=0;
    do
     {
      fscanf(fp,"%s",str);
      flagm=0;
      flagp=0;
      len=strlen(str);
      if(str[len-1]==':')
       {
	for(j=0;j<len-1;j++)
	a[i].label[j]=str[j];
	fscanf(fp,"%s",str);
       }
	else
	strcpy(a[i].label,NULL);
	flagm=searchmot(str);
	flagp=searchpot(str);
if(flagm==1||flagp==1)
{
if(strcmp(str,"STOP")==0)
{
strcpy(a[i].mne,str);
strcpy(a[i].opnd,NULL);
}
else if(strcmp(str,"ENDP")==0)
{
strcpy(a[i].mne,str);
strcpy(a[i].opnd,NULL);
endpos=i;
break;
}
else
{
strcpy(a[i].mne,str);
fscanf(fp,"%s",str);
strcpy(a[i].opnd,str);
}
i++;
}
}while(!feof(fp));
nacode=endpos;
i=endpos+1;
while(!feof(fp))
{
fscanf(fp,"%s %s %s",&a[i].label,&a[i].mne,&a[i].opnd);
if(strcmp(a[i].mne,"END")==0)
{
strcpy(a[i].opnd,NULL);
break;
}
i++;
}
nadata=i;
}
fclose(fp);
i=0;
while(i!=nadata)
{
if(strcmp(a[i].opnd,"?")!=0)
{
naot=i;
i++;
}
else
break;
}
pass1();

fp=fopen("SymT.txt","w+");
j=0;
while(strcmp(s[j].sym,"END")!=0)
{
fputs(s[j].sym,fp);
fputs(s[j].type,fp);
fprintf(fp,"%d\n",s[j].sym_add);
j++;
}
fclose(fp);
if(error==0)
pass2();
getch();
}

int searchmot(char str1[])
{
int i,x;
for(i=0;i<nmot;i++)
{
x=strcmp(m[i].mnemo,str1);
if(x==0)
{
motptr=i;
return 1;
}
}
return 0;
}

int searchpot(char str1[])
{
int i,y;
for(i=0;i<npot;i++)
{
y=strcmp(p[i].ps_opcode,str1);
if(y==0)
{
poptr=i;
return 1;
}
}
return 0;
}

int searchst(char str1[])
{
int i,y,z,len,j,x;
char str[30],str2[30];
for(i=0;i<15;i++)
{
z=strcmp(s[i].sym,str1);
if(z==0)
{
stptr=i;
return 1;
}
}
return 0;
}

void pass1()
{
 int i,k,y,add,len,j,num=0;
 FILE *fp;
 char str2[30];
 motptr=0;
 poptr=0;
 stptr=0;
 lc=0;
 error=0;
 i=0;
 k=0;
 add=0;
 while(i!=nadata)
  {
   if(strcmp(a[i].mne,"END")==0)
   {
    if(error==0)
      pass2();
    else
      printf("\nUnsuccessful Assembly!!!");
   }
   else
      if((strcmp(a[i].mne,"START")==0)||(strcmp(a[i].mne,"ORG")==0))
      {
       flagp=searchpot(a[i].mne);
       if(flagp==1)
	{
	 if(strcmp(a[i].opnd,"NULL")==0)
	   lc=0;
	 else
	   {
	    firstloc=atoi(a[i].opnd);
	    lc=firstloc;
	   }
	}
      }
     else
	if(strcmp(a[i].mne,"ENDP")==0)
	{
	 flagp=searchpot(a[i].mne);
	 if(flagp==1)
	  {
	   motptr=0;
	   poptr=0;
	   stptr=0;
	  }
	}
	else
	   if(strcmp(a[i].mne,"DB")==0)
	     {
	      flagp=searchpot(a[i].mne);
	      if(flagp==1)
		{
		 flagst=searchst(a[i].label);
		 if(flagst==1)
		  {
		   s[stptr].sym_add=lc;
		   if(strcmp(a[i].opnd,"?")==0)
		    {
		     strcpy(s[stptr].type,"VAR");
		     lc=lc+1;
		    }
		  }
		}
	     }
	   else
	      if(strcmp(a[i].mne,"DW")==0)
	       {
		flagp=searchpot(a[i].mne);
		if(flagp==1)
		{
		 flagst=searchpot(a[i].label);
		 if(flagst==1)
		   s[stptr].sym_add=lc;
		   if(flagp==1)
		    {
		     motptr=0;
		     poptr=0;
		     stptr=0;
		    }
		}
	     }
	      else
		if(strcmp(a[i].mne,"DB")==0)
		{
		 flagp=searchpot(a[i].mne);
		 if(flagp==1)
		  {
		   flagst=searchst(a[i].label);
		    if(flagst==1)
		     {
			s[stptr].sym_add=lc;
			if(strcmp(a[i].opnd,"?")==0)
			 {
			  strcpy(s[stptr].type,"VAR");
			  lc=lc+1;
			  }
		     }
		  }
		}
		else
		  if(strcmp(a[i].mne,"DW")==0)
		   {
		    flagp=searchpot(a[i].mne);
		    if(flagp==1)
		     {
		      flagst=searchpot(a[i].label);
		      if(flagst==1)
			{
			s[stptr].sym_add=lc;
			if(strcmp(a[i].opnd,"?")==0)
			 {
			  strcpy(s[k].type,"VAR");
			  lc=lc+2;
			 }
			else
			 {
			  num=atoi(a[i].opnd);
			  s[stptr].sym_add=lc;
			  add_const[add].addr=lc;
			  add_const[add].value=num;
			  strcpy(s[k].type,"CONST");
			  add++;
			  lc+=2;
			 }
			}
		     }
		  }
	   else
	   if(strcmp(a[i].mne,"CONST")==0)
	    {
	     flagp=searchpot(a[i].mne);
	     if(flagp==1)
	      {
		flagst=searchst(a[i].label);
		if(flagst==1)
		 {
		  s[stptr].sym_add=lc;
		  strcpy(s[stptr].type,"CONST");
		  add_const[add].addr=lc;
		  add_const[add].value=atoi(a[i].opnd);
		  add++;
		  lc+=1;
		 }
	      }
	    }
	else
	 if((strcmp(a[i].label,"NULL")!=0)&&
	    (strcmp(a[i].mne,"NULL")==0)&&
	    (strcmp(a[i].opnd,"NULL")==0))
	     {
	      y=searchst(a[i].label);
		if(y==0)
		{
		 strcpy(s[k].sym,a[i].label);
		 strcpy(s[k].type,"LABEL");
		 s[k].sym_add=lc;
		 k++;
		}
		else
		{
		printf("\nDuplicate Label!!");
		error=1;
		}
	     }
	else
	   if((strcmp(a[i].label,"NULL")==0)&&
	      (strcmp(a[i].mne,"NULL")!=0)&&
	      (strcmp(a[i].opnd,"NULL")==0))
	      {
		flagm=searchmot(a[i].mne);
		lc=lc+m[motptr].loi;
	      }
	   else
	      if((strcmp(a[i].label,"NULL")==0)&&
		 (strcmp(a[i].mne,"NULL")!=0)&&
		 (strcmp(a[i].opnd,"NULL")!=0))
		 {
		  flagm=searchmot(a[i].mne);
		  if(flagm==1)
		    {
		     flagst=searchst(a[i].opnd);
		     if(flagst==0)
		       {
			strcpy(s[k].sym,a[i].opnd);
			strcpy(s[k].type,"IDN");
			s[k].sym_add=NULL;
			k++;
		       }
		     lc=lc+m[motptr].loi;
		    }
		 }
	      else
		 if((strcmp(a[i].label,"NULL")!=0)&&
		    (strcmp(a[i].mne,"NULL")!=0)&&
		    (strcmp(a[i].opnd,"NULL")==0))
		    {
		     flagst=searchst(a[i].label);
		     if(flagst==0)
		       {
			strcpy(s[k].sym,a[i].label);
			strcpy(s[k].type,"LABEL");
			s[k].sym_add=lc;
		       }
		     else
		       {
			strcpy(str2,s[stptr].type);
			if(strcmp(str2,"IDN")==0)
			  {
			   strcpy(s[stptr].type,"LABEL");
			   s[stptr].sym_add=lc;
			  }
		       }
		 flagm=searchmot(a[i].mne);
		 if(flagm==1)
		   lc+=m[motptr].loi;
		 else
		   error=1;
		    }
		else
		   if((strcmp(a[i].label,"NULL")!=0)&&
		      (strcmp(a[i].mne,"NULL")!=0)&&
		      (strcmp(a[i].opnd,"NULL")!=0))
		      {
			flagst=searchst(a[i].label);
			if(flagst==0)
			 {
			  strcpy(s[k].sym,a[i].label);
			  strcpy(s[k].type,"LABEL");
			  s[k].sym_add=lc;
			  k++;
			 }
		   else
		      {
			if(strcmp(s[stptr].type,"LABEL")!=0)
			{
			 strcpy(s[stptr].type,"LABEL");
			 s[k].sym_add=lc;
			}
		      }
	   flagm=searchmot(a[i].mne);
	   if(flagm==1)
	   {
	      flagst=searchst(a[i].opnd);
	      if(flagst==1)
	      {}
	      else
	      {
	       strcpy(s[k].sym,a[i].opnd);
	       strcpy(s[k].type,"IDN");
	       s[k].sym_add=lc;
	       k++;
	      }
	     lc+=m[motptr].loi;
	   }
	}
     i++;
   }
 nast=k-1;
 
strcmp(s[j].sym,"");
strcmp(s[j].type," ");
fclose(fp);
}
void pass2()
{
 FILE *fp;
 int i,k;
 fp=fopen("OUTPUTNEW.txt","w+");
 motptr=0;
 poptr=0;
 stptr=0;
 lc=0;error=0;k=0;i=0;
 while(i!=nadata)
  {
   if(strcmp(a[i].mne,"STOP")==0)
     {
      flagm=searchmot(a[i].mne);
      if(flagm==1)
	{
	 o[k].lc=lc;
	 o[k].mac_code=m[motptr].opcode;
	 o[k].add=NULL;
	 k++;
	 printf("\nASSEMBLY COMPLETE!!\n");
	}
    }
  else
     if((strcmp(a[i].mne,"START")==0)||
	(strcmp(a[i].mne,"ORG")==0))
	{
	 flagp=searchpot(a[i].mne);
	 if(flagp==1)
	   {
	    if(strcmp(a[i].opnd,"NULL")==0)
	      lc=0;
	    else
	      {
	      firstloc=atoi(a[i].opnd);
	      lc=firstloc;
	      }
	   }
	}
     else
	if(strcmp(a[i].mne,"ENDP")==0)
	  {
	   flagp=searchpot(a[i].mne);
	   if(flagp==1)
	     {
	      motptr=0;
	      poptr=0;
	      stptr=0;
	     }
	  }
	else
	  if(strcmp(a[i].mne,"DB")==0)
	    {
	    flagp=searchpot(a[i].mne);
	    if(flagp==1)
	      {
	       flagst=searchpot(a[i].label);
	       if(flagst==1)
		 {
		  o[k].lc=lc;
		  o[k].add=s[stptr].sym_add;
		  lc+=1;
		  k++;
		 }
	       }
	    }
	 else
	    if(strcmp(a[i].mne,"DW")==0)
	      {
	       flagp=searchpot(a[i].mne);
	       if(flagp==1)
		 {
		  flagst=searchst(a[i].label);
		  if(flagst==1)
		    {
		    o[k].lc=lc;
		    o[k].add=s[stptr].sym_add;
		    lc+=2;
		    k++;
		    }
		 }
	      }
	    else
		if(strcmp(a[i].mne,"CONST")==0)
		  {
		   flagp=searchpot(a[i].mne);
		   if(flagp==1)
		     {
		      flagst=searchst(a[i].label);
		      if(flagst==1)
			{
			 o[k].lc=NULL;
			 o[k].mac_code=getvalue(s[stptr].sym_add);
			 o[k].add=s[stptr].sym_add;
			 k++;
			}
		    }
		  }
		else
		   if((strcmp(a[i].label,"NULL")==0)&&
		      (strcmp(a[i].mne,"NULL")!=0)&&
		      (strcmp(a[i].opnd,"NULL")!=0))
		      {
			flagm=searchmot(a[i].mne);
			if(flagm==1)
			  {
			   o[k].lc=lc;
			   o[k].mac_code=m[motptr].opcode;
			   flagst=searchst(a[i].opnd);
			   if(flagst==0)
			      printf("\nUndefined Sysmbol!!");
			   else
			      {
			      o[k].add=s[stptr].sym_add;
			      k++;
			      }
			  }
			lc+=m[motptr].loi;
		      }
		   else
		      if((strcmp(a[i].label,"NULL")!=0)&&
			 (strcmp(a[i].mne,"NULL")!=0)&&
			 (strcmp(a[i].opnd,"NULL")==0))
			 {
			  flagm=searchmot(a[i].mne);
			  if(flagm==1)
			    {
			     o[k].lc=lc;
			     o[k].mac_code=m[motptr].opcode;
			     k++;
			     lc+=m[motptr].loi;
			    }
			  else
			    error=1;
			 }
		      else
			  if((strcmp(a[i].label,"NULL")!=0)&&
			    (strcmp(a[i].mne,"NULL")!=0)&&
			    (strcmp(a[i].opnd,"NULL")!=0))
			    {
			     flagm=searchmot(a[i].mne);
			     if(flagm==1)
			       {
				o[k].lc=lc;
				o[k].mac_code=m[motptr].opcode;
				flagst=searchst(a[i].opnd);
				if(flagst==1)
				  {
				   o[k].add=s[stptr].sym_add;
				   k++;
				  }
				else
				   printf("\n Undefined Symbol!!");
				lc+=m[motptr].loi;
			       }
																		    }
			i++;
		      }
for(i=0;i<naot-1;i++)
fprintf(fp,"%d %d %d\n",o[i].lc,o[i].mac_code,o[i].add);
}

int getvalue(int add)
{
 int i=0; while(i!=nast)
  {
   if(add_const[i].addr==add)
   return(add_const[i].value);
   i++;
  }
return 0;
}

Assembly Language Program provided as input (alp.txt)

START 2000 
READ N 
LOAD ZERO 
STORE COUNT 
STORE SUM 
LOOP: READ X 
LOAD X 
ADD SUM 
STORE SUM 
LOAD COUNT 
ADD ONE 
STORE COUNT 
SUB N 
JZ OUTER 
JMP LOOP 
OUTER: WRITE SUM 
STOP 
ENDP 
ZERO CONST 0 
ONE CONST 1 
SUM DB ? 
COUNT DB ? 
N DB ? 
X DB ? 
END 

MOT table (mot.txt)

ADD 1 1 2 
SUB 2 1 2 
MULT 3 1 2 
JMP 4 1 2 
JNEG 5 1 2 
JPOS 6 1 2 
JZ 7 1 2 
LOAD 8 1 2 
STORE 9 1 2 
READ 10 1 2 
WRITE 11 12 
STOP 12 0 1 
JNZ 13 1 2 

POT Table (pot.txt)

DB 2 
DW 2 
EQU 2 
CONST 2 
START 1 
ORG 1 
LTORG 1 
ENDP 0 
END 0 

Symbol Table (symt.txt)

NVAR2033
ZEROCONST2029
COUNTVAR2032
SUMVAR2031
LOOPLABEL2008
XVAR2034
ONECONST2030
OUTERLABEL2024

Output (outputne.txt)

2000 10 2033
2002 8 2029
2004 9 2032
2006 9 2031
2008 10 2034
2010 8 2034
2012 1 2031
2014 9 2031
2016 8 2032
2018 1 2030
2020 9 2032
2022 2 2033
2024 7 2024
2026 4 2008
2028 11 2031
2028 12 0
0 0 2029
0 1 2030

2 thoughts on “Implementing Multi-pass Assembler in C”

  1. Hey, can you explain the working of MOT, POT, and how this output came? I ran the same code with input files, but that isn’t working…, can you please help..

Leave a Reply to balamuruganCancel reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.