Title : Write a program to implement II pass assembler. (For hypothetical instruction set from Dhamdhere). Consider Literal processing , forward references not expected
 a. Use of literals and not symbols
b. LTORG, END
c. Error handling
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#define MAX 80

#define INT_DIGITS 19  /* enough for 64 bit integer */


char *strrev(char *str){
    char c, *front, *back;

    if(!str || !*str)
 return str;
    for(front=str,back=str+strlen(str)-1;front < back;front++,back--){
 c=*front;*front=*back;*back=c;
    }
    return str;
}

char *itoa(int v, char *buff, int radix_base){
    static char table[] = "0123456789abcdefghijklmnopqrstuvwxyz";
    char *p=buff;
    unsigned int n = (v < 0 && radix_base == 10)? -v : (unsigned int) v;
    while(n>=radix_base){
 *p++=table[n%radix_base];
 n/=radix_base;
    }
    *p++=table[n];
    if(v < 0 && radix_base == 10) *p++='-';
    *p='\0';
    return strrev(buff);
}


typedef struct MOT
{

 char mn[25];
 char dir[25];
 int opcode;
 int length;
}m;

typedef struct POT
{
 char mn[25];
 char dir[25];
 int opcode;
 int length;
}p;

typedef struct SYMBOL_TABLE
{
 int addr;
 char symbol[25];
}s;

typedef struct LITERAL_TABLE
{
 char literal[25];
 int addr;
}l;

int pool_tab[MAX];
s sym[MAX];
l littab[MAX];


m mot[MAX]={
     {"MOVER","IS",1,1},
     {"MOVEM","IS",2,1},
     {"ADD","IS",3,1},
     {"MUL","IS",4,1},
     {"SUB","IS",5,1},
     {"DIV","IS",6,1},
     {"BC","IS",7,1},
     {"COMP","IS",8,1}
     };



p pot[MAX]={
    {"START","AD",1,0},
    {"END","AD",2,0},
    {"ORIGIN","AD",3,0},
    {"LTORG","AD",4,0},
    {"DC","DL",5,0},
    {"DS","DL",6,0}
    };


int search_pot(char s[MAX])
{
 int i;
 for(i=0;i<6;i++)
 {
  if(strcmp(pot[i].mn,s)==0)
  {
   return i;
  }
 }
 return -1;
}

int search_mot(char s[MAX])
{
 int i,flag=0;
 for(i=0;i<8;i++)
 {
  if(strcmp(mot[i].mn,s)==0)
  {
   flag=1;
   break;
  }
 }
 if(flag==1)
 {
  return i;
 }
 else
 {
  return -1;
 }
}

int main()
{
 FILE *fp,*fo,*fp1,*fo1;
 char or_ch=' ',reg[10],const_str[MAX],new_str[MAX],new_str1[MAX],new1[MAX],s[MAX],brand[80],temp_new[MAX],output[80],ocode[5],str1[MAX],lc_val[MAX],temp[80],len[MAX],m1[MAX],reg_val[1];
 int pptr=0,pot_i,inst_c=0,pass2_n,n1,IS_n,addr_l,ptr_set=0,addr,str_count,m,i,sym_flag=0,opcode,lit_flag=0,flag=0,ori,lc,lit_count=0,sym_count=0,flag_sym=0,n,len_str;
 int ltorg=0,start_flag=0;

 fp=fopen("FILE1.ASM","r");
 fo=fopen("op_file.txt","w+");
 printf("\n\n\tINTERMEDIATE CODE");
 printf("\n\t--------------------\n");

 while(!feof(fp))
 {
  fscanf(fp,"%s",s);
  if(start_flag==1)
  {
   m=atoi(s);
   if(m>0)
   {
    start_flag=0;
    lc=m;
    ori=m;
    flag=1;
   }
   else
   {
    lc=0;
    ori=0;
    start_flag=0;
   }


   strcpy(output,"     ( ");
   strcat(output,pot[0].dir);
   strcat(output," , ");
   itoa(pot[0].opcode,str1,10);
   strcat(output,str1);
   strcat(output," ) ");

   strcat(output,"  ( ");
   strcat(output,"C , ");

   itoa(lc,str1,10);
   strcat(output,str1);
   strcat(output,")\n");
   printf("\n\tLocation Value : %s\n\n",str1);

   printf("\n%s",output);
   fwrite(output,strlen(output),1,fo);

  }


 if(s[(strlen(s)-1)]==':')
 {
  s[strlen(s)-1]='\0';
  for(i=0;i<sym_count;i++)
  {
   flag_sym=0;
   if(strcmp(sym[i].symbol,s)==0)
   {
    flag_sym=1;
    break;
   }
   else
   {
    flag_sym=0;
   }
  }
  if(flag_sym==0)
  {
   strcpy(sym[sym_count].symbol,s);
   sym[sym_count].addr=lc;
   sym_count++;
  }
 }

 else if(strcmp(s,"START")==0)
 {
  i=search_pot(s);
  start_flag=1;
 }

 else if(strcmp("ORIGIN",s)==0)
 {
  do
  {

   or_ch=fgetc(fp);
  }while(or_ch!=10);
 }

 else if(strcmp("LTORG",s)==0)
 {
  if(flag==1)
  {
   lc=ori;
   flag=0;
  }
  pot_i=search_pot(s);
  ptr_set=0;
  inst_c=0;   //FOR ONLY ONCE MOVING IN A LTORG STMT BLOCK

  for(i=pool_tab[pptr-1];i<(lit_count);i++)
  {
   littab[i].addr=lc;

   itoa(lc,lc_val,10);
   strcpy(output,lc_val);
   if(inst_c==0)
   {
    strcat(output,"  ( ");
    strcat(output,pot[pot_i].dir);
    strcat(output," , ");
    itoa(pot[pot_i].opcode,str1,10);
    strcat(output,str1);
    strcat(output," ) ");
    //itoa(pot[pot_i].length,str1,10);
    //strcat(output,str1);
    inst_c=1;
    strcat(output,"    \t");
    strcat(output,littab[i].literal);//Retrival of literal
    strcat(output,"\n");             //from literal table
    printf("%s",output);
    fwrite(output,strlen(output),1,fo);
   }
   else
   {
    strcat(output,"\t\t\t");
    strcat(output,littab[i].literal);
    strcat(output,"\n");
    printf("%s",output);
    fwrite(output,strlen(output),1,fo);
   }
   lc++;
  }
 }




 else if(strcmp("DS",s)==0)
 {
  if(flag==1)
  {
   lc=ori;
   flag=0;
  }
  pot_i=search_pot(s);

  for(i=0;i<sym_count;i++)
  {
   sym_flag=0;
   if(strcmp(sym[i].symbol,brand)==0) //SYMBOL AVAIL IN S_TABLE
   {
    sym[i].addr=lc;
    sym_flag=1;
    break;
   }
  }
  if(sym_flag==0)  //NOT AVAILABLE...MAKE COPY
  {
   strcpy(sym[sym_count].symbol,brand);
   sym[sym_count].addr=lc;
   sym_count++;
  }

  itoa(lc,lc_val,10);
  strcpy(output,lc_val);
  strcat(output,"  ( ");
  strcat(output,pot[pot_i].dir);
  strcat(output," , ");
  itoa(pot[pot_i].opcode,str1,10);
  strcat(output,str1);
  strcat(output," ) ");
  //itoa(pot[i].length,str1,10);
  //strcat(output,str1);

  strcat(output,"  ( ");
  strcat(output,"C , ");
  fscanf(fp,"%s",s);
  strcat(output,s);
  strcat(output," )\n");

  printf("%s",output);
  fwrite(output,strlen(output),1,fo);
  lc=lc+2;
 }

 else if(strcmp("DC",s)==0)
 {
  if(flag==1)
  {
   lc=ori;
   flag=0;
  }

  pot_i=search_pot(s);

  for(i=0;i<sym_count;i++)
  {
   sym_flag=0;
   if(strcmp(sym[i].symbol,brand)==0)
   {
    sym[i].addr=lc;
    sym_flag=1;
    break;
   }
  }
  if(sym_flag==0)
  {
   strcpy(sym[sym_count].symbol,brand);
   sym[sym_count].addr=lc;
   sym_count++;
  }
  itoa(lc,lc_val,10);
  strcpy(output,lc_val);
  strcat(output,"  ( ");
  strcat(output,pot[pot_i].dir);
  strcat(output," , ");
  itoa(pot[pot_i].opcode,str1,10);
  strcat(output,str1);
  strcat(output," ) ");
  //itoa(pot[i].length,str1,10);
  //strcat(output,str1);

  strcat(output,"  ( ");
  strcat(output,"C , ");
  fscanf(fp,"%s",s);
  strcat(output,s);
  strcat(output," )\n");

  printf("%s",output);
  fwrite(output,strlen(output),1,fo);
  lc=lc+1;
 }


 else if((search_mot(s))>=0)
 {
  i=search_mot(s);
  if(flag==1)
  {
   lc=ori;
   flag=0;
  }
  itoa(lc,len,10);
  strcpy(output,len);
  strcat(output,"  ( ");
  strcat(output,mot[i].dir);
  strcat(output," , ");
  itoa(pot[i].opcode,str1,10);
  strcat(output,str1);
  strcat(output," ) ");

  fscanf(fp,"%s",reg);
  if(strcmp("AREG",reg)==0)
  {
   strcpy(reg_val,"1");
  }

  else if(strcmp("BREG",reg)==0)
  {
   strcpy(reg_val,"2");
  }
  else if(strcmp("CREG",reg)==0)
  {
   strcpy(reg_val,"3");
  }
  else if(strcmp("DREG",reg)==0)
  {
   strcpy(reg_val,"4");
  }

  strcat(output,reg_val);
  fscanf(fp,"%s",s);

  if(strcmp("=",s)==0)
  {
   if(ptr_set==0)
   {
    pool_tab[pptr]=lit_count;
    ptr_set=1;      //THERE IS AT LEAST 1 LITERAL
    pptr++;         //1 POOL TABLE
   }
   fscanf(fp,"%s",s); //LITERAL VALUE
   len_str=strlen(s);
   str_count=0;

   for(i=0;i<len_str;i++)
   {
    if(s[i]>=48 && s[i]<=57)
    {
     new_str[str_count]=s[i];
     str_count++;
    }
   }
   new_str[str_count]='\0';
   strcpy(s,new_str);

   for(i=pool_tab[pptr-1];i<(lit_count);i++)
   {
    lit_flag=0;
    if(strcmp(littab[i].literal,s)==0)
    {
     lit_flag=1;
     break;
    }
   }
   if(lit_flag==0)
   {
    strcpy(littab[lit_count].literal,s);
    lit_count++;
   }

   strcat(output," ( ");
   strcat(output,"L , ");
   itoa(lit_count,str1,10);
   strcat(output,str1);
   strcat(output," )\n");

   printf("%s",output);
   fwrite(output,strlen(output),1,fo);
   lc=lc+mot[i].length;
  }
  else
  {
   strcpy(temp,s);
   for(i=0;i<sym_count;i++)
   {
    flag_sym=0;

    if(strcmp(sym[i].symbol,temp)==0)
    {
     flag_sym=1;
     break;
    }
   }
   if(flag_sym==0)
   {
    strcpy(sym[sym_count].symbol,temp);
    i=sym_count;
    sym_count++;

   }
   strcat(output," ( ");
   strcat(output,"S , ");
   itoa(i+1,str1,10);
   strcat(output,str1);
   strcat(output," )\n");

   printf("%s",output);
   fwrite(output,strlen(output),1,fo);
   lc=lc+mot[i].length;
  }
 }

 else if(strcmp("EQU",s)==0)
 {
  fscanf(fp,"%s",s);

  for(i=0;i<sym_count;i++)
  {
   sym_flag=0;
   if(strcmp(sym[i].symbol,s)==0)
   {
    addr=sym[i].addr;
    sym_flag=1;
    break;
   }
  }

  for(i=0;i<sym_count;i++)
  {
   sym_flag=0;
   if(strcmp(sym[i].symbol,brand)==0)
   {
    sym[i].addr=addr;
    sym_flag=1;
    break;
   }
  }
  if(sym_flag==0)
  {
   strcpy(sym[sym_count].symbol,brand);
   sym[sym_count].addr=addr;
   sym_count++;
  }


 }

 else if(strcmp("END",s)==0)
 {
  pot_i=search_pot(s);
  inst_c=0;
  //ptr_set=0;
  for(i=pool_tab[pptr-1];i<(lit_count);i++)
  {
   littab[i].addr=lc;
   itoa(lc,lc_val,10);
   strcpy(output,lc_val);
   if(inst_c==0)
   {
    strcat(output,"  ( ");
    strcat(output,pot[pot_i].dir);
    strcat(output," , ");
    itoa(pot[pot_i].opcode,str1,10);
    strcat(output,str1);
    strcat(output," ) ");
    //itoa(pot[i].length,str1,10);
    //strcat(output,str1);
    inst_c=1;
    strcat(output,"  \t");
    strcat(output,littab[i].literal);
    strcat(output,"\n");

    printf("%s",output);
    fwrite(output,strlen(output),1,fo);
   }
   else
   {
    strcat(output,"\t\t\t");
    strcat(output,littab[i].literal);
    strcat(output,"\n");

    printf("%s",output);
    fwrite(output,strlen(output),1,fo);
   }
   lc++;
  }
 }
 else
 {
  strcpy(brand,s);
 }

 }

 printf("\n\n     Pool Table");
 for(i=0;i<pptr;i++)
 {
  printf("\n       %d    %d",(i+1),(pool_tab[i])+1);
 }


 printf("\n\n     LITERAL TABLE");
 for(i=0;i<lit_count;i++)
 {
  printf("\n     %d    %s    %d",(i+1),littab[i].literal,littab[i].addr);
 }

/*
 printf("\n\n   SYMBOL TABLE");
 for(i=0;i<sym_count;i++)
 {
  printf("\n   %d    %s       %d",(i+1),sym[i].symbol,sym[i].addr);
 }

*/
 fclose(fp);
 fclose(fo);


return 0;
}

OUTPUT:
Content of ASM FILE 

START 200
MOVER AREG = '5'
MOVEM AREG A

LOOP: MOVER AREG A
MOVER CREG B
ADD CREG = '1' 
LTORG

NEXT1: SUB BREG = '1'
ORIGIN LOOP + 6
MUL CREG B
ADD CREG = '5' 
A DS 2
B DC 3

NEXT2 EQU LOOP
END