Design suitable data structures and implement pass-I of a two-pass assembler for 8 bit microprocessor/ pseudo-machine. Implementation should consist of a few instructions from each category and few assembler directives

, by Prashant Gunjal

 
You will require a.txt in current folder where your program is located 

contents of a.txt

    start 200
    mover areg,one
    mover breg,='4'
    mover creg,='5'
    mover breg,='6'
    mover creg,='7'
    add breg,areg
    sub breg,creg
    movem res,breg
    one dc 1
    res ds 5
    print res
    ltorg
        ='5'
        ='4'
loop equ one
    end

Main program code (ap1.c)

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

struct mottab
{
    char name[8];
    int class;
    char info[4];
};

struct symtab
{
    char sym[8];
    int address;
    int len;
}st[20];

struct littab
{
    int lit;
    int address;
}lt[20];

int pt[5]={0};

struct ino
{
    int lc;
    int class1,no1;
    int class2,no2;
    int class3,no3;
}ic[50];

int ipt=0,ilt=0,ist=0,iic=0;

static struct mottab mot[30]={{"STOP",1,"00"},{"ADD",1,"01"},{"SUB",1,"02"},{"MULT",1,"03"},{"MOVEM",1,"04"},{"MOVER",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 searchmot(char s[])
{
    int i;
    for(i=0;i<28;i++)
        if(strcmp(s,mot[i].name)==0)
            return(i);
    return(-1);
}
int searchsym(char s[])
{
    int i;
    for(i=0;i<ist;i++)
        if(strcmp(s,st[i].sym)==0)
            return(i);
    return(-1);
}
int searchlit(int sno)
{
    int i;
    for(i=0;i<ist;i++)
        if(sno==lt[i].lit)
            return(i);
    return(-1);
}
int insertsym(char s[],int addr,int len)
{
    strcpy(st[ist].sym,s);
    st[ist].address=addr;
    st[ist++].len=len;
    return(ist-1);
}
int insertlit(int lit,int addr)
{
    lt[ilt].lit=lit;
    lt[ilt++].address=addr;
    return(ilt-1);
}
void display();
int main()
{
    FILE * fp;
    char s1[10],s2[10],s3[10],s4[10],label[8],fname[8],buffer[50];
    int i,j,index,cnt,lc,flag=0;
    printf("\n\tEnter file name to be read : ");
    scanf("%s",fname);
    fp=fopen(fname,"r");
    strcpy(buffer,"");
    while(fgets(buffer,40,fp)!=0)
    {
        for(i=0;i<strlen(buffer);i++)
            if(!isalnum(buffer[i]))
                buffer[i]=' ';
            else
                buffer[i]=toupper(buffer[i]);
    jump:
        printf("\n\t*** %s ****",buffer);
        cnt=sscanf(buffer,"%s%s%s%s",s1,s2,s3,s4);
        if(strcmp(s1,"END")==0)
        {
            ic[iic].lc=lc++;
            ic[iic].class1=mot[searchmot(s1)].class;
            ic[iic++].no1=atoi(mot[searchmot(s1)].info);
            break;
        }
        if(searchmot(s1)==-1)
        {
            printf("\n\tSymbol found %s ",s1);
            cnt=sscanf(buffer,"%s%s%s%s%s",label,s1,s2,s3,s4);
            index=searchsym(label);
            if(index==-1)
                insertsym(label,lc,1);
        }
        switch(mot[searchmot(s1)].class)
        {
            case 1:    printf("\n\tImperative statement");
                    ic[iic].lc=lc++;
                    ic[iic].class1=mot[searchmot(s1)].class;
                    ic[iic].no1=atoi(mot[searchmot(s1)].info);
                    if(cnt>1)
                    {
                        if(searchmot(s2)!=-1)        //if regester
                        {
                        ic[iic].class2=mot[searchmot(s2)].class;
                        ic[iic].no2=atoi(mot[searchmot(s2)].info);
                        }
                        else    //may be var (from dc or ds statement)
                        {
                            index=searchsym(s2);
                            if(index==-1)
                            {
                                index=insertsym(s2,0,0);
                            }
                            ic[iic].class2=7;        // 7 for variable
                            ic[iic].no2=index;
                        }
                    }
                    if(cnt>2)
                    {
                        if(searchmot(s3)!=-1)
                        {
                        ic[iic].class3=mot[searchmot(s3)].class;
                        ic[iic].no3=atoi(mot[searchmot(s3)].info);
                        }
                        else
                        {
                            if(isdigit(*s3))
                            {
                                printf("\n\t Literal found ");
                                index=searchlit(atoi(s3));
                                if(index==-1)
                                {
                                    index=insertlit(atoi(s3),0);
                                }
                                ic[iic].class3=8;        // 8 for literal
                                ic[iic].no3=index;
                            }
                            else
                            {   
                                index=searchsym(s3);
                                if(index==-1)
                                {
                                    index=insertsym(s3,0,0);
                                }
                                ic[iic].class3=7;        // 7 for variable
                                ic[iic].no3=index;
                            }
                        }
                    }
                    iic++;
                break;
            case 2:    printf("\n\tDeclaration statement");
                    if(strcmp(s1,"DC")==0)
                    {
                        ic[iic].lc=lc;
                        ic[iic].class1=mot[searchmot(s1)].class;
                        ic[iic].no1=atoi(mot[searchmot(s1)].info);

                        ic[iic].class2=6;            //6 for constant
                        ic[iic++].no2=atoi(s2);
                        st[searchsym(label)].address=lc++;    //back patching
                            st[searchsym(label)].len=1;
                    }
                    if(strcmp(s1,"DS")==0)
                    {
                        ic[iic].lc=lc;
                        ic[iic].class1=mot[searchmot(s1)].class;
                        ic[iic].no1=atoi(mot[searchmot(s1)].info);

                        ic[iic].class2=6;            //6 for constant
                        ic[iic++].no2=atoi(s2);

                        st[searchsym(label)].address=lc;    // back patching
                        st[searchsym(label)].len=atoi(s2);
                        lc+=atoi(s2);
                    }
                break;
            case 3:    printf("\n\tAssembler Directive ");
                if(strcmp(s1,"START")==0 || strcmp(s1,"ORIGIN")==0)
                {
                    lc=atoi(s2);
                    ic[iic].lc=lc;
                    ic[iic].class1=mot[searchmot(s1)].class;
                    ic[iic].no1=atoi(mot[searchmot(s1)].info);
                    ic[iic].class2=6;
                    ic[iic++].no2=atoi(s2);
                }
                if(strcmp(s1,"LTORG")==0)
                {
                    printf("processing ltorg....");
                    ic[iic].lc=lc++;
                    ic[iic].class1=mot[searchmot(s1)].class;
                    ic[iic++].no1=atoi(mot[searchmot(s1)].info);
                    while(1)
                    {
                        fgets(buffer,40,fp);
                        for(i=0;i<strlen(buffer);i++)
                            if(!isalnum(buffer[i]))
                                buffer[i]=' ';
                            else
                                buffer[i]=toupper(buffer[i]);

                        printf("\n\t$$ %s $$",buffer);
                        cnt=sscanf(buffer,"%s%s%s%s",s1,s2,s3,s4);
                        if(isdigit(*s1))
                        {
                            lt[searchlit(atoi(s1))].address=lc++;
                            pt[ipt]++;
                        }
                        else
                        {
                            ipt++;
                            goto jump;
                            break;
                        }
                    }
                }
                if(strcmp(s1,"EQU")==0)
                {
                    index=searchsym(label);
                    st[index].address=st[searchsym(s2)].address;

                    ic[iic].lc=lc++;
                    ic[iic].class1=mot[searchmot(s1)].class;
                    ic[iic++].no1=atoi(mot[searchmot(s1)].info);
                }
                break;   
       
        }
        strcpy(buffer,"");
    }
//**************Lit process ***********
    for(i=pt[ipt-1];i<ilt;i++)
    {
        lt[i].address=lc++;
        pt[ipt]++;
        flag=1;
    }
    if(flag==1)
    {
        pt[ipt]+=pt[ipt-1];
        ipt++;
    }
    display();
    return(0);
}
void display()
{
    int i;
    FILE * fp;
    fp = fopen("st.txt","w");
    printf("\n\t **************Sym tab ***************** ");
    for(i=0;i<ist;i++)
    {
        printf("\n\t%s\t%d\t%d",st[i].sym,st[i].address,st[i].len);
        fprintf(fp,"%s\t%d\t%d\n",st[i].sym,st[i].address,st[i].len);
    }
    close(fp);
    fp = fopen("lt.txt","w");
    printf("\n\t **************Lit tab ******************");
    for(i=0;i<ilt;i++)
    {
        printf("\n\t%d\t%d",lt[i].lit,lt[i].address);
        fprintf(fp,"%d\t%d\n",lt[i].lit,lt[i].address);
    }
    close(fp);
    printf("\n\t **************Pool tab ******************");
    for(i=0;i<ipt;i++)
    {
        printf("\n\t%d",pt[i]);
    }
    printf("\n\t **************IC tab ****************** ");
    fp=fopen("ic.txt","w");
    for(i=0;i<iic;i++)
    {
        if(ic[i].class1==1)
        {
            printf("\n%d)\t(IS,%d)",ic[i].lc,ic[i].no1);
        }
        else
        {
            if(ic[i].class1==2)
            {
                printf("\n%d)\t(DL,%d)",ic[i].lc,ic[i].no1);
            }
            else
            {
                printf("\n%d)\t(AD,%d)",ic[i].lc,ic[i].no1);
            }
        }
       
// *********class 2******************
        if(ic[i].class2==4)
            printf("\t(Reg,%d)",ic[i].no2);
        else
            if(ic[i].class2==7)
                    printf("\t(S,%d)",ic[i].no2);
            else
                if(ic[i].class2==6)
                    printf("\t(C,%d)",ic[i].no2);
//*****************class 3*************
        if(ic[i].class3==4)
            printf("\t(Reg,%d)",ic[i].no3);
        else
            if(ic[i].class3==6)
                printf("\t(C,%d)",ic[i].no3);
            else   
                if(ic[i].class3==7)
                    printf("\t(Sym,%d)",ic[i].no3);
                else
                    if(ic[i].class3==8)
                        printf("\t(Lit,%d)",ic[i].no3);

        fprintf(fp,"%d\t%d\t%d\t%d\t%d\t%d\t%d\n",ic[i].lc,ic[i].no1,ic[i].class1,ic[i].no2,ic[i].class2,ic[i].no3,ic[i].class3);           
    }
    close(fp);
}

Execute in this way ->
  1) Go to that folder through terminal
  2) Compile that .c file (gcc file_name.c)
  3) run it . (./a.out)

Output :
root@prashant-HP-ENVY-4-Notebook-PC:~/SPOS Programs/ass pass1# gcc ap1.c
root@prashant-HP-ENVY-4-Notebook-PC:~/SPOS Programs/ass pass1# ./a.out

    Enter file name to be read : a.txt

    ***  START 200  ****
    Assembler Directive
    ***  MOVER AREG ONE  ****
    Imperative statement
    ***  MOVER BREG   4   ****
    Imperative statement
     Literal found
    ***  MOVER CREG   5   ****
    Imperative statement
     Literal found
    ***  MOVER BREG   6   ****
    Imperative statement
     Literal found
    ***  MOVER CREG   7   ****
    Imperative statement
     Literal found
    ***  ADD BREG AREG  ****
    Imperative statement
    ***  SUB BREG CREG  ****
    Imperative statement
    ***  MOVEM RES BREG  ****
    Imperative statement
    ***  ONE DC 1  ****
    Symbol found ONE
    Declaration statement
    ***  RES DS 5  ****
    Symbol found RES
    Declaration statement
    ***  PRINT RES  ****
    Imperative statement
    ***  LTORG  ****
    Assembler Directive processing ltorg....
    $$     5   $$
    $$     4   $$
    $$ LOOP EQU ONE  $$
    *** LOOP EQU ONE  ****
    Symbol found LOOP
    Assembler Directive
    ***  END  ****
     **************Sym tab *****************
    ONE    208    1
    RES    209    5
    LOOP    208    1
     **************Lit tab ******************
    4    217
    5    216
    6    220
    7    221
     **************Pool tab ******************
    2
    4
     **************IC tab ******************
200)    (AD,1)    (C,200)
200)    (IS,5)    (Reg,1)    (Sym,0)
201)    (IS,5)    (Reg,2)    (Lit,0)
202)    (IS,5)    (Reg,3)    (Lit,1)
203)    (IS,5)    (Reg,2)    (Lit,2)
204)    (IS,5)    (Reg,3)    (Lit,3)
205)    (IS,1)    (Reg,2)    (Reg,1)
206)    (IS,2)    (Reg,2)    (Reg,3)
207)    (IS,4)    (S,1)    (Reg,2)
208)    (DL,2)    (C,1)
209)    (DL,1)    (C,5)
214)    (IS,10)    (S,1)
215)    (AD,5)
218)    (AD,4)
219)    (AD,2)root@prashant-HP-ENVY-4-Notebook-PC:~/SPOS Programs/ass pass1#

#################################################

After this execution you will see 1)ic.txt ie intermediate code 2) st.txt ie symbol table and 3) lt.txt ie literal table

ic.txt
200    1    3    200    6    0    0
200    5    1    1    4    0    7
201    5    1    2    4    0    8
202    5    1    3    4    1    8
203    5    1    2    4    2    8
204    5    1    3    4    3    8
205    1    1    2    4    1    4
206    2    1    2    4    3    4
207    4    1    1    7    2    4
208    2    2    1    6    0    0
209    1    2    5    6    0    0
214    10    1    1    7    0    0
215    5    3    0    0    0    0
218    4    3    0    0    0    0
219    2    3    0    0    0    0

st.txt

ONE    208    1
RES    209    5
LOOP    208    1

lt.txt

4    217
5    216
6    220
7    221

Above files will require for assembler  pass 2...

 

0 comments: