Write a program to implement II pass assembler.


Write a program to implement II pass assembler. ( For hypothetical instruction set from Dhamdhere) a. Consider following cases only (Literal processing not expected)
b. Forward references
c. DS and DC statement
d. START, EQU
e. Error handling: symbol used but not defined, invalid instruction/register etc

/*Experiment No. 1 : A Two Pass Assembler*/ 



#include<stdio.h>
#include<string.h>

struct MOTtable

  {
 char Mnemonic[6];
 int  Class;
 char Opcode[3];
  };


struct symboltable

  {
 char Symbol[8];
 int  Address;
 int  Size;

  }ST[20];




struct intermediatecode
  {

    int LC;
    int Code1,Type1;
    int Code2,Type2;
    int Code3,Type3;

  }IC[30];


static struct MOTtable MOT[28]={{"STOP",1,"00"},{"ADD",1,"01"},{"SUB",1,"02"},

         {"MULT",1,"03"},{"MOVER",1,"04"},{"MOVEM",1,"05"},

         {"COMP",1,"06"},{"BC",1,"07"},{"DIV",1,"08"},

         {"READ",1,"09"},{"PRINT",1,"10"},

         {"START",3,"01"},{"END",3,"02"},{"ORIGIN",3,"03"},

         {"EQU",3,"04"},{"LTORG",3,"05"},

         {"DS",2,"01"},{"DC",2,"02"},

         {"AREG",4,"01"},{"BREG",4,"02"},{"CREG",4,"03"},

         {"EQ",5,"01"},{"LT",5,"02"},{"GT",5,"03"},{"LE",5,"04"},

         {"GE",5,"05"},{"NE",5,"06"},{"ANY",5,"07"}};



int nMOT=28; //Number of entries in MOT

int LC=0;    //Location counter

int iST=0;   //Index of next entry in Symbol Table

int iIC=0;   //Index of next entry in intermediate code table

int searchST(char symbol[])

   {
      int i;

      for(i=0;i<iST;i++)

  if(strcmp(ST[i].Symbol,symbol)==0)

       return(i);
      return(-1);
   }

int searchMOT(char symbol[])

   {
      int i;

      for(i=0;i<nMOT;i++)

  if(strcmp(MOT[i].Mnemonic,symbol)==0)

  return(i);
      return(-1);
   }

int insertST( char symbol[],int address,int size)
    {
       strcpy(ST[iST].Symbol,symbol);

       ST[iST].Address=address;

       ST[iST].Size=size;

       iST++;

       return(iST-1);

    }

void imperative();  //Handle an executable statement

void declaration(); //Handle a declaration statement

void directive();  //Handle an assembler directive

void print_symbol(); //Display symbol table

void print_opcode();  //Display opcode table

void intermediate();  //Display intermediate code

void mcode();           //Generate machine code

char s1[8],s2[8],s3[8],label[8];



void DC();   //Handle declaration statement DC

void DS();   //Handle declaration statement DS

void START();  //Handle START directive

int tokencount;  //total number of words in a statement

void main()
 {
 char file1[40],nextline[80];
 int len,i,j,temp,errortype;
 FILE *ptr1;
 
 printf("\nenter Source file name:");
 gets(file1);
 ptr1=fopen(file1,"r");

 while(!feof(ptr1))
   {
  //Read a line of assembly program and remove special characters
  i=0;
  nextline[i]=fgetc(ptr1);
  while(nextline[i]!='\n'&& nextline[i]!=EOF )
      {
    if(!isalnum(nextline[i]))
     nextline[i]=' ';
    else
     nextline[i]=toupper(nextline[i]);
    i++;
    nextline[i]=fgetc(ptr1);
      }
  nextline[i]='\0';
  sscanf(nextline,"%s",s1); //read from the nextline in s1

  if(strcmp(s1,"END")==0) //if the nextline is an END statement
        break;

          //if the nextline contains a label
  if(searchMOT(s1)==-1)
       {
   if(searchST(s1)==-1)
      insertST(s1,LC,0);
   //separate opcode and operands
   tokencount=sscanf(nextline,"%s%s%s%s",label,s1,s2,s3);
   tokencount--;
       }
  else
   //separate opcode and operands
   tokencount=sscanf(nextline,"%s%s%s",s1,s2,s3);

  if(tokencount==0)//blank line
        continue;//goto the beginning of the loop

  i=searchMOT(s1);

  if(i==-1)
    {
   printf("\nWrong Opcode .... %s",s1);

   continue;
    }
  switch (MOT[i].Class)
     {
   case 1: imperative();break;
   case 2: declaration();break;
   case 3: directive();break;
   default: printf("\nWrong opcode ...%s",s1);
     break;
     }

   }

  

  

   print_opcode();
 

  intermediate();


  mcode();
  
 }

void imperative()
  {
    int index;
    index=searchMOT(s1);
    IC[iIC].Type1=IC[iIC].Type2=IC[iIC].Type3=0; //intialize
    IC[iIC].LC=LC;
    IC[iIC].Code1=index;
    IC[iIC].Type1=MOT[index].Class;
    LC=LC+1;

    if(tokencount>1)
      {
 index=searchMOT(s2);
 if(index != -1)
    {
  IC[iIC].Code2=index;
  IC[iIC].Type2=MOT[index].Class;
    }
 else
    {   //It is a variable
        index=searchST(s2);
        if(index==-1)
      index=insertST(s2,0,0);
  IC[iIC].Code2=index;
  IC[iIC].Type2=7; //VALUE 7 IS FOR VARIABLES
    }
      }

    if(tokencount>2)
      {
   
      {
  index=searchST(s3);
  if(index==-1)
      index=insertST(s3,0,0);
  IC[iIC].Code3=index;
  IC[iIC].Type3=7; //VALUE 7 IS FOR VARIABLES

      }

      }

   iIC++;
}

void declaration()
{
   if(strcmp(s1,"DC")==0)
     {
 DC();
 return;
     }
   if(strcmp(s1,"DS")==0)
 DS();
}

void directive()
{
    if(strcmp(s1,"START")==0)
       {
   START();
   return;
       }
 }


void DC()
{
 int index;
 index=searchMOT(s1);
 IC[iIC].Type1=IC[iIC].Type2=IC[iIC].Type3=0; //intialize
 IC[iIC].LC=LC;
 IC[iIC].Code1=index;
 IC[iIC].Type1=MOT[index].Class;
 IC[iIC].Type2=6;        //6 IS TYPE FOR CONSTANTS
 IC[iIC].Code2=atoi(s2);
 index=searchST(label);
 if(index==-1)
  index=insertST(label,0,0);
 ST[index].Address=LC;
 ST[index].Size=1;
 LC=LC+1;
 iIC++;

}
void DS()
{
 int index;
 index=searchMOT(s1);
 IC[iIC].Type1=IC[iIC].Type2=IC[iIC].Type3=0; //intialize
 IC[iIC].LC=LC;
 IC[iIC].Code1=index;
 IC[iIC].Type1=MOT[index].Class;
 IC[iIC].Type2=6;        //6 IS TYPE FOR CONSTANTS
 IC[iIC].Code2=atoi(s2);
 index=searchST(label);
 if(index==-1)
  index=insertST(label,0,0);
 ST[index].Address=LC;
 ST[index].Size=atoi(s2);
 LC=LC+atoi(s2);
 iIC++;
}


void START()
{
  int index;
  index=searchMOT(s1);
  IC[iIC].Type1=IC[iIC].Type2=IC[iIC].Type3=0; //intialize
  IC[iIC].LC=LC;
  IC[iIC].Code1=index;
  IC[iIC].Type1=MOT[index].Class;
  IC[iIC].Type2=6;        //6 IS TYPE FOR CONSTANTS
  IC[iIC].Code2=atoi(s2);
  LC=atoi(s2);
  iIC++;

}

void intermediate()
{  int i;
 char decode[9][3]={" ","IS","DL","AD","RG","CC","C","S"};
 printf("\n\nIntermediate Code :");
 for(i=0;i<iIC;i++)
  {
  printf("\n%3d)   (%s,%2s)",IC[i].LC,decode[IC[i].Type1]
        ,MOT[IC[i].Code1].Opcode);
  if(IC[i].Type2!=0)
     {
        if(IC[i].Type2<6)
    printf(" (%s,%2s)",decode[IC[i].Type2]
        ,MOT[IC[i].Code2].Opcode);
        else
          printf("  (%s,%2d)",decode[IC[i].Type2]
        ,IC[i].Code2);
     }
  if(IC[i].Type3!=0)
          printf("  (%s,%2d)",decode[IC[i].Type3]
        ,IC[i].Code3);
   }
}
void print_symbol()
 {
 int i;
 printf("\n*******symbol table ***********\n");
 for(i=0;i<iST;i++)
  printf("\n%10s  %3d   %3d",ST[i].Symbol,ST[i].Address
       ,ST[i].Size);
}

 
void print_opcode()
  {
 int i;
 printf("\nopcode table *************");
 for(i=0;i<nMOT;i++)
  if(MOT[i].Class==1)
         printf("\n%6s   %2s",MOT[i].Mnemonic,MOT[i].Opcode);

  }

void mcode()
 {
 int i;
 printf("\n\nMachine Code :");
 for(i=0;i<iIC;i++)
   {


  if(IC[i].Type1==1 )
      {
   printf("\n%3d)  %s ",IC[i].LC,MOT[IC[i].Code1].Opcode);
   if(IC[i].Type2==0)
      printf("00 000");

   else
      if(IC[i].Type2>6)//No Register Operand
    printf("00 %3d",ST[IC[i].Code2].Address);
   else
     {
       printf("%2s ",MOT[IC[i].Code2].Opcode);
       if(IC[i].Type3==7)
          printf("%3d",ST[IC[i].Code3].Address);
       
     }

        }
   else
      if(IC[i].Type1==2 && strcmp(MOT[IC[i].Code1].Mnemonic,"DC")==0)
         {
       printf("\n%3d)  ",IC[i].LC);
       printf("00 00 %3d",IC[i].Code2);
         }

      }


 }



/*
************** Input / Output *******************


enter Source file name:xx.asm

*******symbol table ***********

 L1  100     0
  X  108     1
  Y  109     2

pool table *********

0
2

literal table*******

    5     103
    2     104
    4     111

opcode table *************
  STOP   00
   ADD   01
   SUB   02
  MULT   03
 MOVER   04
 MOVEM   05
  COMP   06
    BC   07
   DIV   08
  READ   09
 PRINT   10

Intermediate Code :
  0)   (AD,01)  (C,100)
100)   (IS,04) (RG,01)  (L, 0)
101)   (IS,05) (RG,02)  (S, 1)
102)   (IS,02) (RG,01)  (L, 1)
103)   (DL,02)  (C, 5)
104)   (DL,02)  (C, 2)
105)   (IS,04) (RG,01)  (S, 2)
106)   (IS,07) (CC,07)  (S, 0)
107)   (IS,01) (RG,03)  (L, 2)
108)   (DL,02)  (C, 5)
109)   (DL,01)  (C, 2)
111)   (DL,02)  (C, 4)

Machine Code :
100)  04 01 103
101)  05 02 108
102)  02 01 104
103)  00 00   5
104)  00 00   2
105)  04 01 109
106)  07 07 100
107)  01 03 111
108)  00 00   5
111)  00 00   4


*/

OUTPUT:
Contents of the ASM file xx.asm
----------------------------
START 100
L1  MOVER AREG,=5
    MOVEM BREG X
    SUB   AREG,=2
    LTORG
    MOVER AREG Y
    BC any,L1
    ADD CREG,4
X   DC  5
Y   DS  2
    END

Post a Comment