Here is implementation of multi-pass assembler in C. You have to provide Assembly Language Program, MOT table and POT table as input.
#include<stdio.h> #include<conio.h> #include<math.h> #include<stdlib.h> #define NULL 0 struct mot { char mnemo[6]; int opcode,no_opnds,loi; }; struct pot { char ps_opcode[6]; int opnds; }; struct alp { char label[7],mne[7],opnd[30]; }; struct st { char sym[10],type[10]; int sym_add; }; struct of { int lc,mac_code,add; }; struct addnvalue { int addr,value; }; struct addnvalue add_const[15]; struct mot m[12]; struct pot p[9]; struct alp a[25]; struct st s[15]; struct of o[25]; int searchmot(char str[]); int searchpot(char str[]); int searchst(char str[]); int str2num(char str[]); int getvalue(int add); void pass1(); void pass2(); int motptr,poptr,endpos,nmot,npot,nacode,nadata,lc,error,flagm,flagp; int naot,nast,stptr,firstloc,flagst; void main() { int i,j,k,c,len,x; char str[8],str1[8],str2[30],ch; FILE *fp; clrscr(); fp=fopen("mot.txt","r"); if(fp==NULL) { printf("'mot.txt' File Does not exist!!"); exit(0); } else { i=0; while(!feof(fp)) { fscanf(fp,"%s %d %d %d",&m[i].mnemo,&m[i].opcode,&m[i].no_opnds,&m[i].loi); i++; } nmot=i; fclose(fp); } fp=fopen("pot.txt","r"); if(fp==NULL) { printf("'pot.txt'File does not exist!"); exit(0); } else { i=0; while(!feof(fp)) { fscanf(fp,"%s %d",&p[i].ps_opcode,&p[i].opnds); i++; } npot=i; fclose(fp); } fp=fopen("alp.txt","r"); if(fp==NULL) printf("'alp.txt'File does not exist\n"); else { i=0; do { fscanf(fp,"%s",str); flagm=0; flagp=0; len=strlen(str); if(str[len-1]==':') { for(j=0;j<len-1;j++) a[i].label[j]=str[j]; fscanf(fp,"%s",str); } else strcpy(a[i].label,NULL); flagm=searchmot(str); flagp=searchpot(str); if(flagm==1||flagp==1) { if(strcmp(str,"STOP")==0) { strcpy(a[i].mne,str); strcpy(a[i].opnd,NULL); } else if(strcmp(str,"ENDP")==0) { strcpy(a[i].mne,str); strcpy(a[i].opnd,NULL); endpos=i; break; } else { strcpy(a[i].mne,str); fscanf(fp,"%s",str); strcpy(a[i].opnd,str); } i++; } }while(!feof(fp)); nacode=endpos; i=endpos+1; while(!feof(fp)) { fscanf(fp,"%s %s %s",&a[i].label,&a[i].mne,&a[i].opnd); if(strcmp(a[i].mne,"END")==0) { strcpy(a[i].opnd,NULL); break; } i++; } nadata=i; } fclose(fp); i=0; while(i!=nadata) { if(strcmp(a[i].opnd,"?")!=0) { naot=i; i++; } else break; } pass1(); fp=fopen("SymT.txt","w+"); j=0; while(strcmp(s[j].sym,"END")!=0) { fputs(s[j].sym,fp); fputs(s[j].type,fp); fprintf(fp,"%d\n",s[j].sym_add); j++; } fclose(fp); if(error==0) pass2(); getch(); } int searchmot(char str1[]) { int i,x; for(i=0;i<nmot;i++) { x=strcmp(m[i].mnemo,str1); if(x==0) { motptr=i; return 1; } } return 0; } int searchpot(char str1[]) { int i,y; for(i=0;i<npot;i++) { y=strcmp(p[i].ps_opcode,str1); if(y==0) { poptr=i; return 1; } } return 0; } int searchst(char str1[]) { int i,y,z,len,j,x; char str[30],str2[30]; for(i=0;i<15;i++) { z=strcmp(s[i].sym,str1); if(z==0) { stptr=i; return 1; } } return 0; } void pass1() { int i,k,y,add,len,j,num=0; FILE *fp; char str2[30]; motptr=0; poptr=0; stptr=0; lc=0; error=0; i=0; k=0; add=0; while(i!=nadata) { if(strcmp(a[i].mne,"END")==0) { if(error==0) pass2(); else printf("\nUnsuccessful Assembly!!!"); } else if((strcmp(a[i].mne,"START")==0)||(strcmp(a[i].mne,"ORG")==0)) { flagp=searchpot(a[i].mne); if(flagp==1) { if(strcmp(a[i].opnd,"NULL")==0) lc=0; else { firstloc=atoi(a[i].opnd); lc=firstloc; } } } else if(strcmp(a[i].mne,"ENDP")==0) { flagp=searchpot(a[i].mne); if(flagp==1) { motptr=0; poptr=0; stptr=0; } } else if(strcmp(a[i].mne,"DB")==0) { flagp=searchpot(a[i].mne); if(flagp==1) { flagst=searchst(a[i].label); if(flagst==1) { s[stptr].sym_add=lc; if(strcmp(a[i].opnd,"?")==0) { strcpy(s[stptr].type,"VAR"); lc=lc+1; } } } } else if(strcmp(a[i].mne,"DW")==0) { flagp=searchpot(a[i].mne); if(flagp==1) { flagst=searchpot(a[i].label); if(flagst==1) s[stptr].sym_add=lc; if(flagp==1) { motptr=0; poptr=0; stptr=0; } } } else if(strcmp(a[i].mne,"DB")==0) { flagp=searchpot(a[i].mne); if(flagp==1) { flagst=searchst(a[i].label); if(flagst==1) { s[stptr].sym_add=lc; if(strcmp(a[i].opnd,"?")==0) { strcpy(s[stptr].type,"VAR"); lc=lc+1; } } } } else if(strcmp(a[i].mne,"DW")==0) { flagp=searchpot(a[i].mne); if(flagp==1) { flagst=searchpot(a[i].label); if(flagst==1) { s[stptr].sym_add=lc; if(strcmp(a[i].opnd,"?")==0) { strcpy(s[k].type,"VAR"); lc=lc+2; } else { num=atoi(a[i].opnd); s[stptr].sym_add=lc; add_const[add].addr=lc; add_const[add].value=num; strcpy(s[k].type,"CONST"); add++; lc+=2; } } } } else if(strcmp(a[i].mne,"CONST")==0) { flagp=searchpot(a[i].mne); if(flagp==1) { flagst=searchst(a[i].label); if(flagst==1) { s[stptr].sym_add=lc; strcpy(s[stptr].type,"CONST"); add_const[add].addr=lc; add_const[add].value=atoi(a[i].opnd); add++; lc+=1; } } } else if((strcmp(a[i].label,"NULL")!=0)&& (strcmp(a[i].mne,"NULL")==0)&& (strcmp(a[i].opnd,"NULL")==0)) { y=searchst(a[i].label); if(y==0) { strcpy(s[k].sym,a[i].label); strcpy(s[k].type,"LABEL"); s[k].sym_add=lc; k++; } else { printf("\nDuplicate Label!!"); error=1; } } else if((strcmp(a[i].label,"NULL")==0)&& (strcmp(a[i].mne,"NULL")!=0)&& (strcmp(a[i].opnd,"NULL")==0)) { flagm=searchmot(a[i].mne); lc=lc+m[motptr].loi; } else if((strcmp(a[i].label,"NULL")==0)&& (strcmp(a[i].mne,"NULL")!=0)&& (strcmp(a[i].opnd,"NULL")!=0)) { flagm=searchmot(a[i].mne); if(flagm==1) { flagst=searchst(a[i].opnd); if(flagst==0) { strcpy(s[k].sym,a[i].opnd); strcpy(s[k].type,"IDN"); s[k].sym_add=NULL; k++; } lc=lc+m[motptr].loi; } } else if((strcmp(a[i].label,"NULL")!=0)&& (strcmp(a[i].mne,"NULL")!=0)&& (strcmp(a[i].opnd,"NULL")==0)) { flagst=searchst(a[i].label); if(flagst==0) { strcpy(s[k].sym,a[i].label); strcpy(s[k].type,"LABEL"); s[k].sym_add=lc; } else { strcpy(str2,s[stptr].type); if(strcmp(str2,"IDN")==0) { strcpy(s[stptr].type,"LABEL"); s[stptr].sym_add=lc; } } flagm=searchmot(a[i].mne); if(flagm==1) lc+=m[motptr].loi; else error=1; } else if((strcmp(a[i].label,"NULL")!=0)&& (strcmp(a[i].mne,"NULL")!=0)&& (strcmp(a[i].opnd,"NULL")!=0)) { flagst=searchst(a[i].label); if(flagst==0) { strcpy(s[k].sym,a[i].label); strcpy(s[k].type,"LABEL"); s[k].sym_add=lc; k++; } else { if(strcmp(s[stptr].type,"LABEL")!=0) { strcpy(s[stptr].type,"LABEL"); s[k].sym_add=lc; } } flagm=searchmot(a[i].mne); if(flagm==1) { flagst=searchst(a[i].opnd); if(flagst==1) {} else { strcpy(s[k].sym,a[i].opnd); strcpy(s[k].type,"IDN"); s[k].sym_add=lc; k++; } lc+=m[motptr].loi; } } i++; } nast=k-1; strcmp(s[j].sym,""); strcmp(s[j].type," "); fclose(fp); } void pass2() { FILE *fp; int i,k; fp=fopen("OUTPUTNEW.txt","w+"); motptr=0; poptr=0; stptr=0; lc=0;error=0;k=0;i=0; while(i!=nadata) { if(strcmp(a[i].mne,"STOP")==0) { flagm=searchmot(a[i].mne); if(flagm==1) { o[k].lc=lc; o[k].mac_code=m[motptr].opcode; o[k].add=NULL; k++; printf("\nASSEMBLY COMPLETE!!\n"); } } else if((strcmp(a[i].mne,"START")==0)|| (strcmp(a[i].mne,"ORG")==0)) { flagp=searchpot(a[i].mne); if(flagp==1) { if(strcmp(a[i].opnd,"NULL")==0) lc=0; else { firstloc=atoi(a[i].opnd); lc=firstloc; } } } else if(strcmp(a[i].mne,"ENDP")==0) { flagp=searchpot(a[i].mne); if(flagp==1) { motptr=0; poptr=0; stptr=0; } } else if(strcmp(a[i].mne,"DB")==0) { flagp=searchpot(a[i].mne); if(flagp==1) { flagst=searchpot(a[i].label); if(flagst==1) { o[k].lc=lc; o[k].add=s[stptr].sym_add; lc+=1; k++; } } } else if(strcmp(a[i].mne,"DW")==0) { flagp=searchpot(a[i].mne); if(flagp==1) { flagst=searchst(a[i].label); if(flagst==1) { o[k].lc=lc; o[k].add=s[stptr].sym_add; lc+=2; k++; } } } else if(strcmp(a[i].mne,"CONST")==0) { flagp=searchpot(a[i].mne); if(flagp==1) { flagst=searchst(a[i].label); if(flagst==1) { o[k].lc=NULL; o[k].mac_code=getvalue(s[stptr].sym_add); o[k].add=s[stptr].sym_add; k++; } } } else if((strcmp(a[i].label,"NULL")==0)&& (strcmp(a[i].mne,"NULL")!=0)&& (strcmp(a[i].opnd,"NULL")!=0)) { flagm=searchmot(a[i].mne); if(flagm==1) { o[k].lc=lc; o[k].mac_code=m[motptr].opcode; flagst=searchst(a[i].opnd); if(flagst==0) printf("\nUndefined Sysmbol!!"); else { o[k].add=s[stptr].sym_add; k++; } } lc+=m[motptr].loi; } else if((strcmp(a[i].label,"NULL")!=0)&& (strcmp(a[i].mne,"NULL")!=0)&& (strcmp(a[i].opnd,"NULL")==0)) { flagm=searchmot(a[i].mne); if(flagm==1) { o[k].lc=lc; o[k].mac_code=m[motptr].opcode; k++; lc+=m[motptr].loi; } else error=1; } else if((strcmp(a[i].label,"NULL")!=0)&& (strcmp(a[i].mne,"NULL")!=0)&& (strcmp(a[i].opnd,"NULL")!=0)) { flagm=searchmot(a[i].mne); if(flagm==1) { o[k].lc=lc; o[k].mac_code=m[motptr].opcode; flagst=searchst(a[i].opnd); if(flagst==1) { o[k].add=s[stptr].sym_add; k++; } else printf("\n Undefined Symbol!!"); lc+=m[motptr].loi; } } i++; } for(i=0;i<naot-1;i++) fprintf(fp,"%d %d %d\n",o[i].lc,o[i].mac_code,o[i].add); } int getvalue(int add) { int i=0; while(i!=nast) { if(add_const[i].addr==add) return(add_const[i].value); i++; } return 0; }
Assembly Language Program provided as input (alp.txt)
START 2000 READ N LOAD ZERO STORE COUNT STORE SUM LOOP: READ X LOAD X ADD SUM STORE SUM LOAD COUNT ADD ONE STORE COUNT SUB N JZ OUTER JMP LOOP OUTER: WRITE SUM STOP ENDP ZERO CONST 0 ONE CONST 1 SUM DB ? COUNT DB ? N DB ? X DB ? END
MOT table (mot.txt)
ADD 1 1 2 SUB 2 1 2 MULT 3 1 2 JMP 4 1 2 JNEG 5 1 2 JPOS 6 1 2 JZ 7 1 2 LOAD 8 1 2 STORE 9 1 2 READ 10 1 2 WRITE 11 12 STOP 12 0 1 JNZ 13 1 2
POT Table (pot.txt)
DB 2 DW 2 EQU 2 CONST 2 START 1 ORG 1 LTORG 1 ENDP 0 END 0
Symbol Table (symt.txt)
NVAR2033 ZEROCONST2029 COUNTVAR2032 SUMVAR2031 LOOPLABEL2008 XVAR2034 ONECONST2030 OUTERLABEL2024
Output (outputne.txt)
2000 10 2033 2002 8 2029 2004 9 2032 2006 9 2031 2008 10 2034 2010 8 2034 2012 1 2031 2014 9 2031 2016 8 2032 2018 1 2030 2020 9 2032 2022 2 2033 2024 7 2024 2026 4 2008 2028 11 2031 2028 12 0 0 0 2029 0 1 2030
I got some more errors while am running this program.
Hey, can you explain the working of MOT, POT, and how this output came? I ran the same code with input files, but that isn’t working…, can you please help..