Showing posts with label C PROGRAMS. Show all posts
Showing posts with label C PROGRAMS. Show all posts

Saturday, July 30

C PROGRAM TO IMPLEMENT MACRO PROCESSOR

 Here is my C program implementing a Macro Processor. We know that Macro is a single line abbreviation for a group of statements. We should define that sentence - cluster before using them in actual program. Macro processor will analyse the program and on encountering  macro variable, it will replace that 'Macro invocation' to corresponding Macro definition. It should also take care the number  and position of arguments used in Macro invocation.



ALGORITHM

MACROPROCESSOR
  • EXPANDING=FALSE.
  • Read each line and call GETLINE() and PROCESSLINE() until END encounters.

PROCESSLINE ( )
  • If OPCODE is a macroname then EXPAND ( ).
  • Else if OPCODE is MACRO ,then DEFINE ( ).
  • Else write line to expanded file as such.
DEFINE( )
  • Enter Macro name into NMATAB.
  • Enter macro prototype into DEFTAB.
  • Set LEVEL=1.
  • Substitute parameters with positional notations and enter to DEFTAB.
  • If OPCODE=MACRO, LEVEL++;
  • If OPCODE=MEND, LEVEL--;
  • Continue this until LEVEL=0
  • Store beginning and end of definition as pointers within NAMTAB

EXPAND ( )
  • EXPANDING = TRUE
  • Set up arguments from macro invocation in ARGTAB.
  • Write macro invocation statement to expanded file  as a comment line.
  • Call GETLINE() and PROCESSLINE() till macro definition ends.
  • Set EXPANDING=FALSE.


GETLINE ( )
  • If EXPANDING is TRUE, read from DEFTAB (data structure where macro body is stored) and substitute arguments for positional notations.
  • If  EXPANDING is FALSE , read next line from input file.




MACROPROCESSOR.C

 /*
PROGRAM NAME:MACRO.C
AIM: TO IMPLEMENT MACRO PROCESSOR.
INPUT : "INPUT.TXT"
OUTPUT: "EXPANDED.TXT"
DATE: 07/28/2011
*/


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

void GETLINE();
void PROCESSLINE();
void DEFINE();
void EXPAND();


 FILE *expanded;
 FILE *input;

 char label[10],opcode[10],operand[25];
 char line[20];
 int namcount=0, defcount=0;
 int EXPANDING;
 int curr;



 struct namtab
 {
 char name[10];
 int start,end;
}mynamtab[15];
     
 struct deftab
 {
        char macroline[25];
  }mydeftab[25];

struct argtab
{
       char arg[3][9];
 }myargtab;
///MACRO MAIN
int main()

{
    EXPANDING=0;

    input =fopen("input.txt","r");                          
 expanded=fopen("expanded.txt","w");
GETLINE();
 
     while(strcmp(opcode,"END")!=0)
{  

     PROCESSLINE();
       GETLINE();
 }
              fprintf(expanded,"%s",line);
      getch();
     return 1;
  }
                            


//   GETLINE
     void GETLINE()
     {    char word1[10],word2[10],word3[10],buff[10];
int count=0,i,j=0;
if(EXPANDING)strcpy(line,mydeftab[curr++].macroline);
 else fgets(line,20,input);
        opcode[0]='\0';label[0]='\0';operand[0]='\0';word1[0]='\0';word2[0]='\0';word3[0]='\0';
        
                      for(i=0;line[i]!='\0';i++)
                      {
                                        
                                                if(line[i]!=' ')
                                                buff[j++]=line[i];
                    
                                                 else
                      {
                                                   
                      buff[j]='\0';
                 
                   
                      strcpy(word3,word2);
                      strcpy(word2,word1);
                       strcpy(word1,buff);
                     j=0;count++;
                      }
                    
                    
                      }

                       buff[j-1]='\0';
                      strcpy(word3,word2);
                      strcpy(word2,word1);
                       strcpy(word1,buff);
                   
   
      switch(count)
                       {
                                    case 0:strcpy(opcode,word1);break;
                                    case 1:{strcpy(opcode,word2);strcpy(operand,word1);}break;
                                    case 2:{strcpy(label,word3);strcpy(opcode,word2);strcpy(operand,word1);}break;
                       }
                   
                     
                       }
                   



//     PROCESSLINE
                       void PROCESSLINE()
                       {
                            int i;
                        for(    i=0;i<namcount;i++)
                      
                                if(!strcmp(opcode,mynamtab[i].name))
                                {
                                                               
                                                                  EXPAND();return;
                                                          
                                                        
                                                             
                                                                  }
                                                           
                                                               { 
                                                                  if(!strcmp(opcode,"MACRO"))
                                                                
                                                                 DEFINE();
                                                               
                                                                 else fprintf(expanded,"%s",line);
                                                                   }
                                                                   }
   
   
     void DEFINE()
     {
          int LEVEL,i=0,j=0,k=0;
       char param[5][9];
       char s[3];
      strcpy(s,"123");
 
          strcpy(mynamtab[namcount].name,label);
          mynamtab[namcount].start=defcount;
          strcpy(mydeftab[defcount].macroline,line);
      
       
          while(operand[i]!='\0')
          {
                                if(operand[i]!=',')
                                param[j][k++]=operand[i];
                                else
                                {
                                    param[j++][k]='\0';
                                
                                    k=0;
                                    }
                              
                               i++;
                                }
                                param[j][k]='\0';
                             
        
          LEVEL=1;
     
        while(LEVEL>0)
          {
                   
            GETLINE();
           
              if(operand[0]!='\0')
             {
            for(i=0;i<3;i++)
            {
            if(!strcmp(operand,param[i]))
            {

            operand[0]='?';
            operand[1]=s[i];
            operand[2]='\0';
             }
             }
             }
           if(!strcmp(opcode,"MACRO"))
            LEVEL++;
           else if(!strcmp(opcode,"MEND"))
            LEVEL--;

            strcpy(mydeftab[defcount].macroline,opcode);
            if(operand[0]!='\0')
            {
            strcat(mydeftab[defcount].macroline," ");
            strcat(mydeftab[defcount].macroline,operand);
            strcat(mydeftab[defcount].macroline,"\n");
            }
            strcat(mydeftab[defcount++].macroline,"\n");

                        }
                        mynamtab[namcount++].end=defcount;
                   
                    
                        }
                      
         

//Expand
        
    void EXPAND()
                        {
                             int i,end=0,j=0,k=0;
                             EXPANDING=1;
                             int arg=0;
                      
                         fprintf(expanded,"//%s",line);
                             for(i=0;i<namcount;i++)
                             {
                             if(!strcmp(opcode,mynamtab[i].name))
                             {
                                                             
                             curr=mynamtab[i].start;
                             end=mynamtab[i].end;
                          
                           
                                   while(operand[i]!='\0')
                                {
                                if(operand[i]!=',')
                                myargtab.arg[j][k++]=operand[i];
                                else
                                {
                                    myargtab.arg[j++][k]='\n';
                                
                                    k=0;
                                    }
                              
                               i++;
                                }                              
                                 myargtab.arg[j][k]='\n';
                           
                        
                             }
                             }
                           
                             while(curr<(end-1))
                             {
                                              GETLINE();
                           if(operand[0]=='?')
                                         
                          strcpy(operand,myargtab.arg[operand[1]-'0'-1]);

                           fprintf(expanded,"%s %s %s",label,opcode,operand);
                        
                             }
                             EXPANDING=0;
                           
                           
                         }



/*************************************************************************************/


  Let us have a look on what will be the output of the program for a sample input.


input.txt



COPY START 1000

RDBUFF MACRO P,Q,R
CLEAR A
CLEAR S
CLEAR X
+LDT #4096
TD P
JEQ *-3
RD P
STCH Q
JLT *-19
LDA R
COMP #0
STX R
MEND

//main program





FIRST STL RETADR
RDBUFF F1,BUFF1,L1
CLEAR X
RDBUFF F2,BUFF2,L2
RDBUFF F3,BUFF3,L3
JLT *-19
STA
END



The output produced will be,

expanded.txt

COPY START 1000
//main program
FIRST STL RETADR
//RDBUFF F1,BUFF1,L1
 CLEAR A
 CLEAR S
 CLEAR X
 +LDT #4096
 TD F1
 JEQ *-3
 RD F1
 STCH BUFF1
 JLT *-19
 LDA L1
 COMP #0
 STX L1
CLEAR X
//RDBUFF F2,BUFF2,L2
 CLEAR A
 CLEAR S
 CLEAR X
 +LDT #4096
 TD F2
 JEQ *-3
 RD F2
 STCH BUFF2
 JLT *-19
 LDA L2
 COMP #0
 STX L2
//RDBUFF F3,BUFF3,L3
 CLEAR A
 CLEAR S
 CLEAR X
 +LDT #4096
 TD F3
 JEQ *-3
 RD F3
 STCH BUFF3
 JLT *-19
 LDA L3
 COMP #0
 STX L3
JLT *-19
STA
END



















        


IMPLEMENTATION OF TWO PASS ASSEMBLER IN C

Hi friends,

Here I'm posting a complete C program to implement a two pass assembler. A 2-pass assembler is a program that accepts an assembly language program as input and produces its machine language equivalent along with the information for the loader. The assembling of source program to object code requires to accomplish following functions.

  • Convert mnemonic opcodes to their machine language equivalent.(e.g, LDA to 00)
  • Convert symbolic operands to their equivalent machine address   (eg, LOOP to 2045)
  • Allocate necessary memory.
  • Convert data constants to internal machine equivalents.
  • Write the object program and assembly listing.    

                      A two pass assembler do these functions in two passes ,i.e., two times the input programs will be scanned/processed.

 PASS 1
  1. Assign addresses to all statements in the program.
  2. Addresses of symbolic labels are stored.
  3. Some assemble directives will be processed.
PASS 2
  1. Translate opcodes and symbolic operands.
  2. Generate data values defined by BYTE,WORD etc.
  3. Assemble directives will be processed.
  4. Write the object program and assembly listing.
  The following C program take assembly program saved in "input.txt" and in pass 1 write intermediate code to "inter.txt". After pass - 2 Object program will be written to "output.txt".


                                                          ASSEMBLER.C


/*
PROGRAM NAME: ASSEMBLER.C
AIM: TO IMPLEMENT A TWO-PASS ASSEMBLER
INPUT: "input.txt"
OUTPUT: "inter.txt" , "output.txt"
DATE: 08/09/2011
*/



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

void chk_label();
void chk_opcode();
void READ_LINE();

struct optab
{
    char   code[10],objcode[10];
}myoptab[3]={
                   {"LDA","00"},
                   {"JMP","01"},
                   {"STA","02"}
             };
                  
                  
struct symtab{
                    char symbol[10];
                    int addr;
              }mysymtab[10];
                   
int startaddr,locctr,symcount=0,length;
char line[20],label[8],opcode[8],operand[8],programname[10];
                   
//                void PASS1()
                  {
                       FILE *input,*inter;                                  
                       input=fopen("input.txt","r");                            
                       inter=fopen("inter.txt","w");
                        printf("LOCATION LABEL\tOPERAND\tOPCODE\n");
                        printf("_____________________________________");                      
                        fgets(line,20,input);
                     
                      READ_LINE();
                     
                     if(!strcmp(opcode,"START"))
                      {
                     
                       startaddr=atoi(operand);
                       locctr=startaddr;                    
                      strcpy(programname,label);
                      
                           fprintf(inter,"%s",line);
                       fgets(line,20,input);
                       }
                      else
                      {
                          programname[0]='\0';
                          startaddr=0;
                          locctr=0;
                      }
                         printf("\n %d\t %s\t%s\t %s",locctr,label,opcode,operand); 
                         
                           while(strcmp(line,"END")!=0)
                          {
                  
                                   READ_LINE();
                                   printf("\n %d\t %s \t%s\t %s",locctr,label,opcode,operand);
                                   if(label[0]!='\0')chk_label();
                                   chk_opcode();
                                   fprintf(inter,"%s %s %s\n",label,opcode,operand);
                                   fgets(line,20,input);
                          }
                         
                   printf("\n %d\t\t%s",locctr,line);
                   fprintf(inter,"%s",line);
 
                    fclose(inter);
                    fclose(input);
                      }
//=====================================================================================================================================                     
          void PASS2()
          {
                FILE *inter,*output;
                char record[30],part[6],value[5];
                int currtxtlen=0,foundopcode,foundoperand,chk,operandaddr,recaddr=0;
                inter=fopen("inter.txt","r");
                output=fopen("output.txt","w");
                fgets(line,20,inter);
              
                READ_LINE();
                if(!strcmp(opcode,"START")) fgets(line,20,inter);
               printf("\n\nCorresponding Object code is..\n");
               printf("\nH^ %s ^ %d ^ %d ",programname,startaddr,length);
               fprintf(output,"\nH^ %s ^ %d ^ %d ",programname,startaddr,length);
               recaddr=startaddr; record[0]='\0';
               while(strcmp(line,"END")!=0)
                          {
                                             operandaddr=foundoperand=foundopcode=0;
                                             value[0]=part[0]= '\0';

                                             READ_LINE();
           for(chk=0;chk<3;chk++)
             {
               if(!strcmp(opcode,myoptab[chk].code))
               {                                    
               foundopcode=1;
               strcpy(part,myoptab[chk].objcode);
            
             if(operand[0]!='\0')
             {
             for(chk=0;chk<symcount;chk++)
                                  
             if(!strcmp(mysymtab[chk].symbol,operand))
             {
             itoa(mysymtab[chk].addr,value,10);
             strcat(part,value);
             foundoperand=1;
             }
              if(!foundoperand)strcat(part,"err");
              }
              }
              }
               if(!foundopcode)
               {
                               if(strcmp(opcode,"BYTE")==0 || strcmp(opcode,"WORD")||strcmp(opcode,"RESB"))
                               {strcat(part,operand);
                              }}
               if((currtxtlen+strlen(part))<=8)
               {
                strcat(record,"^");
                strcat(record,part);
               
                currtxtlen+=strlen(part);
               }
                else
                {
                 printf("\nT^ %d ^%d %s",recaddr,currtxtlen,record);
                 fprintf(output,"\nT^ %d ^%d %s",recaddr,currtxtlen,record);
                 recaddr+=currtxtlen;
                 currtxtlen=strlen(part);
                 strcpy(record,part);
               
              
              
                }
          fgets(line,20,inter);
                }  
                      printf("\nT^ %d ^%d %s",recaddr,currtxtlen,record);
                      fprintf(output,"\nT^ %d ^%d %s",recaddr,currtxtlen,record);
                      printf("\nE^ %d\n",startaddr);
                      fprintf(output,"\nE^ %d\n",startaddr);
                      fclose(inter);
                      fclose(output);
       }          
//=================================================
 
       void READ_LINE()
       {
            char buff[8],word1[8],word2[8],word3[8];
            int i,j=0,count=0;
             label[0]=opcode[0]=operand[0]=word1[0]=word2[0]=word3[0]='\0';
                 for(i=0;line[i]!='\0';i++)
                      {
                   if(line[i]!=' ')buff[j++]=line[i];
                   else
                      {
                     buff[j]='\0';
                     strcpy(word3,word2);strcpy(word2,word1);strcpy(word1,buff);
                     j=0;count++;
                      }
                      }
                      buff[j-1]='\0';
                      strcpy(word3,word2);
                      strcpy(word2,word1);
                      strcpy(word1,buff);
                    switch(count)
                       {
                                    case 0:strcpy(opcode,word1);break;
                                    case 1:{strcpy(opcode,word2);strcpy(operand,word1);}break;
                                    case 2:{strcpy(label,word3);strcpy(opcode,word2);strcpy(operand,word1);}break;
                       }
                       }
//======================================================
            void chk_label()
                  {
                       int k,dupsym=0;
                     for(k=0;k<symcount;k++)
                     if(!strcmp(label,mysymtab[k].symbol))
                     {
                                                          mysymtab[k].addr=-1;
                                                          dupsym=1;
                                                          break;
                                                          }
               if(!dupsym)
               {
               strcpy(mysymtab[symcount].symbol,label);
               mysymtab[symcount++].addr=locctr;
                }
                }
//  =====================================================     

  void chk_opcode()
         {
                      
          int k=0,found=0;
          for(k=0;k<3;k++)
         
                   
                          if(!strcmp(opcode,myoptab[k].code))
                          {
                                                          
                                                     locctr+=3;
                                                  
                                                     found=1;
                                                     break;            
                           }
              if(!found)
              {
                        if(!strcmp( opcode,"WORD")) locctr+=3;
                        else if (!strcmp(opcode,"RESW"))locctr+=(3*atoi(operand));
                        else if(!strcmp(opcode,"RESB"))locctr+=atoi(operand);
               }
    }
            

//==================================================
  int main()
                    {
                    
                   
                        PASS1();
                        length=locctr-startaddr;
                        PASS2();                                              
                        getch();
                    }    


/*
Do not forget to create "input.txt","inter.txt" and "output.txt" prior to run this program. For sake of simplicity, only a few opcodes are included in this program. So for better results try to include input programs with these opcodes.

Here is one sample program (of course, it has no logic..)

input.txt

MYPGM START 1000
STA
LOOP1 JMP LOOP2
LDA
LOOP2 JMP LOOP1
RESB 04
LDA
STA
JMP LOOP1
END

inter.txt

MYPGM START 1000
STA
LOOP1 JMP LOOP2
LDA
LOOP2 JMP LOOP1
RESB 04
LDA
STA
JMP LOOP1
END


 output.txt


H^ MYPGM ^ 1000 ^ 25
T^ 1000 ^8 ^02^011009
T^ 1008 ^8 00^011003
T^ 1016 ^6 04^00^02
T^ 1022 ^6 011003
E^ 1000











                                                    Happy programming..!!!!!!!

*/