//----------------------------------------------------------
// Title : Implement pass-II of a two-pass assembler for
// 8-bit microprocessor/ pseudo-machine. The
// output of PASS-1 (intermediate file and
// symbol table) should be input for this assignment.
//----------------------------------------------------------
//header file declaration
#include<stdio.h>
#include<conio.h>
#include<string.h>
// global declaration of variables
char line[100]; // line ( intermediate file )
int oindex=0; // index for object code
// struct for object code table
struct objcode
{
int add; // address field
char hexcode[20]; // hexcode field
int op1, op2; // op1 = operand1, operand2
}o[50]; // array for opject code file
// functions declatations
void opid(char aaa1[50],char aaa2[50]); // aaa1 = for op1, and aaa2 = for op2
void opcproc(char aa[50]);
void symopen(char sym[20]);
void litopen(char lit[20]);
// function for inserting the value of op1 & op2 in object code struct
void opid(char aaa1[50],char aaa2[50])
{
int i;
if(strcmp(aaa1,"AREG")==0) // if op1 = AREG then insert \'1\' in struct of obj table
{
o[oindex].op1=1;
}
else if(strcmp(aaa1,"BREG")==0) // if op1 = BREG then insert \'2\' in struct of obj table
{
o[oindex].op1=2;
}
else if(strcmp(aaa1,"CREG")==0) // if op1 = CREG then insert \'3\' in struct of obj table
{
o[oindex].op1=3;
}
else if(strcmp(aaa1,"DREG")==0) // if op1 = DREG then insert \'4\' in struct of obj table
{
o[oindex].op1=4;
}
else
{
symopen(aaa1); // if op1 is not regi. then call to fn for symbol check processing
}
if(strcmp(aaa2,"AREG")==0) // if op2 = AREG then insert \'1\' in struct of obj table
{
o[oindex].op2=1;
}
else if(strcmp(aaa2,"BREG")==0) // if op2 = BREG then insert \'2\' in struct of obj table
{
o[oindex].op2=2;
}
else if(strcmp(aaa2,"CREG")==0) // if op2 = CREG then insert \'3\' in struct of obj table
{
o[oindex].op2=3;
}
else if(strcmp(aaa2,"DREG")==0) // if op2 = DREG then insert \'4\' in struct of obj table
{
o[oindex].op2=4;
}
else if(aaa2[0]==\'=\') // IF OP2 IS LITERAL, then call to fn for literal check processing
{
litopen(aaa2);
}
else
{
symopen(aaa2); // if op2 is not regi. then call to fn for symbol check processing
}
}
// function for literal check processing
void litopen(char lit[20])
{
int i, j;
char tmp2[50];
char line1[200]; // line1 = each line of literal file
char s1[100], s2[100]; // s1=first string of literal file
// s2=second string of literal file
static const char filename1[] = "l2.txt";
FILE *file1 = fopen ( filename1, "r" ); // open literal file
if(file1!=NULL) // check every line of LITERAL file still EOF
{
while(fgets(line1,sizeof line1,file1)!=NULL) // fetching first line ( if we use while loop ,then fetching each line upto EOF)
{
sscanf(line1,"%s%s",s1,s2); // separate first & second string from line and insert into s1 & s2
i=0; // initialize i=0 to maintain of tmp2
for(j=2; j<(strlen(lit)-1); j++) // execute this loop from position 2 to string lengh minus 1 ( to avoid last char)
{
tmp2[i]=lit[j]; // copy the literal value to tmp2
i++;
}
tmp2[i]=\'\\0\'; // to avoid garbage value , insert null char
if(strcmp(s1,tmp2)==0) // if first string of literal file and literal of IC file is equal
{
o[oindex].op2=atoi(s2); // convert address of resp. literal and store in struct of obj file
}
}
}
fclose(file1); // close the above file that is literal file
}
// function for symbol check processing
void symopen(char sym[20])
{
char line2[200];
char s1[100], s2[100], s3[100];// s1=first string of symbol file
// s2=second string of symbol file, s3=third string of symbol file
static const char filename2[] = "s2.txt";
FILE *file2 = fopen ( filename2, "r" ); // open symbol file
if(file2!=NULL) // check every line of IC file still EOF
{
while(fgets(line2,sizeof line2,file2)!=NULL) // fetching first line ( if we use while loop ,then fetching each line upto EOF)
{
sscanf(line2,"%s%s%s",s1,s2,s3); // separate first, second and third string from line and insert into s1 ,s2 and s3
if(strcmp(s1,sym)==0) // is first string of symbol table and symbol of IC file is equal
{
if(strcmp(sym,"AGAIN")==0) // if symbol is \'AGAIN\' then to avoid NULL values insert its value to op1
{
o[oindex].op1=atoi(s3); // conversion of string to int.
}
else // if symbol is NOT \'AGAIN\' then insert its value to op2
{
o[oindex].op2=atoi(s3); // conversion of string to int.
}
}
}
}
fclose(file2); // close the above file that is SYMBOL file
}
// this function is to separate the third string (operands) into op1 and op2
void opcproc(char aa[50])
{
char op1[20], op2[20]; // op1= operand1 and op2=operand2
int flag3=0; // to maintain the index of op1 we intialize it to \'zero\'
int i,j=0;
for(i=0; i<strlen(aa); i++) // execute upto the length of array \'aa\' (operand)
{
if(aa[i] == \',\') // if separator found then copy the remaining string to string2 i.e. op2 with the help of while loop
{
i++; // pre-increment to skip the separator
while(i<strlen(aa))
{
op2[j]=aa[i];
i++;
j++;
}
op2[j]=\'\\0\'; // to avoid garbage value , insert null char
break; // use for checking the all characher in op2
}
else if(aa[i] == \' \') // if space is found then copy string to string1 i.e. op1 with the help of while loop
{
while(i<strlen(aa))
{
op1[i]=aa[i];
i++;
}
op1[i]=\'\\0\'; // to avoid garbage value , insert null char
break; // use for checking the all characher in op2
}
else
{
op1[i]=aa[i]; // copy the whole string \'aa\' in op1
flag3++;
}
}
op1[flag3]=\'\\0\'; // use for checking the all characher in op1
opid(op1,op2); // pass the op1 and op2 to fn \'opid\' to inserting particular value
}
// main function
int main()
{
int i, ij;
char s1[100], s2[100], s3[100]; // s1=first string of IC file
// s2=second string of IC file, s3=third string of IC file
static const char filename[] = "i2.txt";
FILE *file = fopen ( filename, "r" ); // open intermediate file
clrscr();
if(file!=NULL) // check every line of IC file still EOF
{
while(fgets(line,sizeof line,file)!=NULL) // fetching first line ( if we use while loop ,then fetching each line upto EOF)
{
sscanf(line,"%s%s%s",s1,s2,s3); // separate first, second and third string from line and insert into s1 ,s2 and s3
oindex++; // pre-increment the index of the object table
o[oindex].add=atoi(s1); // insert address of IC file into address field of obj file
strcpy(o[oindex].hexcode,s2); // insert hexcode of IC file into hexcode code field of obj file
opcproc(s3); // call this fn to separate the operands
}
}
// print the Object Table
printf("\\n---------------------------------------------------------");
printf("\\n\\t\\t OBJECT TABLE");
printf("\\n---------------------------------------------------------");
printf("\\nADDRESS\\t\\tHEXCODE\\t\\tOPERAND1\\tOPERAND2");
for(ij=1;ij<=oindex;ij++) // execute \'for loop\' upto index of object table
{
printf("\\n%d\\t\\t%s\\t\\t%d\\t\\t%d\\t",o[ij].add,o[ij].hexcode,o[ij].op1,o[ij].op2);
}
printf("\\n---------------------------------------------------------");
fclose(file); // close the above file that is IC file
getch();
return 0;
}
// end of the program