0% found this document useful (0 votes)
144 views8 pages

Experiment No1 SPCC

The document describes implementing the second pass of a two-pass assembler. The first pass defines symbols and the second pass generates machine code. It includes data structures like symbol and opcode tables. The pass 2 algorithm searches the opcode and symbol tables to assemble each instruction, generating an object code record with the instruction's binary encoding and updating the location counter. The program implements both passes to assemble a sample assembly language program into machine code.

Uploaded by

Chetan Gaikar
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
144 views8 pages

Experiment No1 SPCC

The document describes implementing the second pass of a two-pass assembler. The first pass defines symbols and the second pass generates machine code. It includes data structures like symbol and opcode tables. The pass 2 algorithm searches the opcode and symbol tables to assemble each instruction, generating an object code record with the instruction's binary encoding and updating the location counter. The program implements both passes to assemble a sample assembly language program into machine code.

Uploaded by

Chetan Gaikar
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 8

Experiment No.1:-To study and implementation of two pass assembler.

Aim :

To implement pass 2 for an assembler which generates the base table and base index values for
symbols.

Theory :

A common assembler focuses on forward reference problem in which a variable is referred


before it is defined. Thus, we use an assembler from pass I which defines the symbols and pass 2
generates the machine code.

The data structure modes are :

1. Copy of source program.

2. LC to keep track of location.

3. A table MOT with symbolic mnemonic length, binary machine opcode.

4. A table POT for each pseudo opcode.

5. A table ST prepared by pass 1.

6. Base table (BT) registers contents and their availability.

7. A workspace INST to hold each instruction assembled together.

8. Workspace print line used to procedure printed timing.

9. Workspace PUNCH CARD used prior to actual output.

10. An output check of assembled instruction in the format studied by the assembler.

Program Logic :

Algorithm

1.Start

2.Read the next entry from copy of pass 1

3.Search POT

4.If forward check occurs from the type of pseudo opcode, then perform the corresponding actions and
go to step 2

5.If not found, search MOT Get instruction length, binary code and type

6.Base table (BT) register content and their availability

7.Evaluate operand expressions by searching for values of symbols

8.Assemble together the parts of instructions


9 Update Lc

10 Repeat 2-9 until END

11 Stop

Conclusion

Thus, we have studied and implemented the pass 2 of assembler and generated base table.

Source Code

 #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

OUTPUT

You might also like