int relative_mode(int *disp){ int PC; char *temp; /* Clean '@' or '#' */ if((OPERAND1[0] == '@') || (OPERAND1[0] == '#')){ temp = &OPERAND1[1]; strcpy(OPERAND1, temp); } if(!search_SYMTAB(OPERAND1)){ printf("ERROR. %s is not found. It's an undeclared SYMBOL\n", OPERAND1); exit(0); } PC = (int)strtol(LOC, NULL, 16) + OPCODE_format; // PC point to next instruction. /* try PC relative first */ *disp = SYMBOL_ADDR - PC; if((*disp >= -2048) && (*disp < 2048)){ return 1; } /* try Base relative */ *disp = SYMBOL_ADDR - BASE; if(*disp < 4096){ return 0; } /* else (invalid addressing mode) */ else{ printf("ERROR! Invalid Addressing Mode.\n"); exit(1); } }
//Pass 1 void PASS_ONE() { FILE * fp1,*fp2; //file pointers char line[100], s1[100], s2[100], s3[100], s4[100],startingADDRESS[5], saveLOCCTR[5]; int t,flag_SYMTAB, flag_OPTAB; printf("Enter the input file name :"); scanf("%s",in_file); //input file name fp1 = fopen(in_file, "r"); //corresponding file opened if(fp1 == NULL) //if '.txt' not in entered file name { strcat(in_file, ".txt"); //concatenating '.txt' fp1 = fopen(in_file, "r"); if(fp1 == NULL) { printf("Could not open source file!!\n"); exit(0); } } strcpy(out_file, in_file); out_file[strlen(out_file)-4] = '\0'; strcat(out_file, "-intermediate.txt"); //to get intermediate file name fp2 = fopen(out_file, "w"); if(fp2 == NULL) { printf("Could not open Intermediate file!!\n"); exit(0); } //fgets(line, 100, fp1);//For column headers //Read first line fgets(line, 100 ,fp1); //reading a line of the input t = sscanf(line,"%s %s %s %s",s1,s2,s3,s4); //t stores the number of words read if(t==2) //two words read { strcpy(s3, s2); //shifting the words read strcpy(s2, s1); strcpy(s1, ""); } char temp[10]; if(strcmp(s2,"START")==0) //start line { strcpy(LOCCTR,s3); make_length(LOCCTR,temp,4); line[strlen(line)-1] = '\0'; if(t==1) fprintf(fp2, "%s %s %s",temp,line," Syntax error : less arguments"); else if(t>3) fprintf(fp2, "%s %s %s",temp,line," Syntax error : more arguments"); else fprintf(fp2, "%s %s",temp,line);//Write to Intermediate file fprintf(fp2,"\n"); fgets(line, 100 ,fp1);//Read next line t = sscanf(line,"%s %s %s %s",s1,s2,s3,s4); if(t==2) { strcpy(s3, s2); strcpy(s2, s1); strcpy(s1, ""); } } else //if START was not found { strcpy(LOCCTR, "0000"); printf("Syntax Error : NO START found!!\n"); } strcpy(startingADDRESS, LOCCTR); while(!feof(fp1) && (strcmp(s2, "END")!=0)) { flag_SYMTAB = 0;flag_OPTAB = 0; strcpy(saveLOCCTR, LOCCTR); if(line[0] != '#')//Not a comment line { if(t==3)//Symbol exists in Label Field { if(search_SYMTAB(s1))//Label exists in SYMTAB flag_SYMTAB = 1; else insert_SYMTAB(s1,LOCCTR); } strcpy(saveLOCCTR, LOCCTR); char * OPCODE = search_OPTAB(s2); if(OPCODE != NULL) increment_LOCCTR(3); else if(strcmp(s2, "WORD") == 0) //WORD detected increment_LOCCTR(3); else if(strcmp(s2, "RESW") == 0) //RESW detected increment_LOCCTR(3 * atoi(s3)); else if(strcmp(s2, "RESB") == 0) //RESB detected increment_LOCCTR(atoi(s3)); else if(strcmp(s2, "BYTE") == 0) //BYTE detected increment_LOCCTR(find_length_BYTE(s3)); else { increment_LOCCTR(3); flag_OPTAB = 1;//OPCODE not found and is not an assembler directive } } make_length(saveLOCCTR,temp,4); strcpy(saveLOCCTR,temp); char write[100];//Line to write in Intermediate file line[strlen(line)-1] = '\0';//Remove newline character from line read so taht it writes error on same line if(flag_OPTAB == 0 ) { if(flag_SYMTAB == 0) sprintf(write, "%s %s",saveLOCCTR, line); else sprintf(write,"%s %s %s",saveLOCCTR, line, "Duplicate Symbol"); } else { if(flag_SYMTAB == 0) sprintf(write,"%s %s %s",saveLOCCTR, line, "Invalid Operation Code"); else sprintf(write,"%s %s %s %s",saveLOCCTR, line, "Duplicate Symbol", "Invalid Operation Code"); } if(t==1) fprintf(fp2, "%s %s",write," Syntax error : less arguments"); else if(t>3) fprintf(fp2, "%s %s",write," Syntax error : more arguments"); else fprintf(fp2, "%s",write);//Write to Intermediate file fprintf(fp2,"\n"); //Read next line fgets(line, 100, fp1); t = sscanf(line,"%s %s %s %s",s1,s2,s3,s4); if(t==2) { strcpy(s3, s2); strcpy(s2, s1); strcpy(s1, ""); } } make_length(LOCCTR,temp,4); //Write last line to Intermediate file fprintf(fp2, "%s %s",temp, line); fclose(fp1); fclose(fp2); //Computing Program Length int start, location,l; char length[5]; sscanf(startingADDRESS, "%x", &start); sscanf(LOCCTR, "%x", &location); l = location - start; itoa(l, length, 16); //getting the length of the code in a string strcpy(out_file, in_file); out_file[strlen(out_file)-4] = '\0'; strcat(out_file, "-length.txt"); fp2 = fopen(out_file, "w"); if(fp2 != NULL) fprintf(fp2, "%s", length); fclose(fp2); //closing file pointer }
//pass II void PASS_TWO() { FILE * fp1,*fp2,*fp3; char line[100], s1[100], s2[100], s3[100], s4[100], startADDRESS[5], length[5], name[100]; //s1 is Location, s2 is Label, s3 is Opcode, s4 is Operand char * symbolADDRESS; char OBJECTCODE[100] ; int t,flag_SYMTAB,main_flag = 0,linecounter = 0; printf("Enter the intermediate file name :"); scanf("%s",im_file); fp1 = fopen(im_file, "r"); //opening intermediate file if(fp1 == NULL) { strcat(im_file, ".txt"); fp1 = fopen(im_file, "r"); if(fp1 == NULL) { printf("Could not open Intermediate file!!\n"); exit(0); } } loadSYMTAB_from_file(); //loading symbol table strcpy(obj_file, im_file); obj_file[strlen(obj_file)-17] = '\0'; strcat(obj_file, "-object.txt"); fp2 = fopen(obj_file, "w"); if(fp2 == NULL) { printf("Could not open Object file!!\n"); exit(0); } //Read first line fgets(line, 100 ,fp1); linecounter++; t = sscanf(line,"%s %s %s %s",s1,s2,s3,s4); if(t==3) { strcpy(s4, s3); strcpy(s3, s2); } if(strcmp(s3,"START")==0) { strcpy(startADDRESS, s1); strcpy(name, s2);//s2 != s3 fgets(line, 100 ,fp1);//Read next line linecounter++; t = sscanf(line,"%s %s %s %s",s1,s2,s3,s4); if(t==3) { strcpy(s4, s3); strcpy(s3, s2); } } else { strcpy(startADDRESS, "0000"); strcpy(name, "UNNAMED"); } //Getting Program Length char S[100]; strcpy(S, im_file); S[strlen(S)-17] = '\0'; strcat(S, "-length.txt"); fp3 = fopen(S, "r"); fscanf(fp3, "%s",length); fclose(fp3); //Writing Header Record char temp1[7], temp2[7]; make_length(startADDRESS, temp1, 6); make_length(length, temp2, 6); fprintf(fp2,"H|%s|%s|%s",name,temp1,temp2); fprintf(fp2,"\n"); //Initialse text record fprintf(fp2, "T|%s|%s",temp1,length); while(!feof(fp1) && (strcmp(s3, "END")!=0)) { flag_SYMTAB = 0; if(s2[0] != '#')//Not a comment line { char * OPCODE = search_OPTAB(s3); if(OPCODE != NULL)//OPCODE found in OPTAB { if(s4!=NULL)//There is a symbol in operand field { symbolADDRESS = search_SYMTAB(s4); if(symbolADDRESS != NULL) make_length(symbolADDRESS, temp1, 4); if(symbolADDRESS == NULL)//Operand does not exist in SYMTAB { printf("Line %d : Error : Symbol is not defined\n",linecounter); main_flag = 1; flag_SYMTAB = 1; } } else//No symbol in operand field strcpy(symbolADDRESS,"0000"); //Assemble object code instruction strcpy(OBJECTCODE, OPCODE); if(symbolADDRESS != NULL) strcat(OBJECTCODE, temp1); } else if(OPCODE==NULL && (strcmp(s3, "BYTE") == 0)) convert_BYTE(s4,OBJECTCODE); else if(OPCODE==NULL && (strcmp(s3, "WORD") == 0)) convert_WORD(s4,OBJECTCODE); else//OPCODE is RESW or RESB strcpy(OBJECTCODE, ""); if(strcmp(OBJECTCODE,"") != 0) fprintf(fp2, "|%s",OBJECTCODE);//Add object code to text } //Read next line fgets(line, 100, fp1); linecounter++; t = sscanf(line,"%s %s %s %s",s1,s2,s3,s4); if(t==3) { strcpy(s4, s3); strcpy(s3, s2); } } //Write End Record fprintf(fp2,"\n"); make_length(startADDRESS, temp1, 6); fprintf(fp2,"E|%s",temp1); fclose(fp1); fclose(fp2); strcpy(obj_file, im_file); obj_file[strlen(obj_file)-17] = '\0'; strcat(obj_file, "-object.txt"); if(main_flag == 1) //error in file remove(obj_file); //removing the object file as error has been detected }
void convert_Object(void){ char *temp; int n, i, x, b, p, e; int disp = 0; int j; char str[3]; get_OPformat(); /* if is format 1 */ if(OPCODE_format == 1){ OBJECT_CODE = instPtr->Opcode; OBJECT_ox = 1; // need to generate OBJECT CODE convert_ObToString(); // convert int object code to string. } /* else if is format 2 */ else if(OPCODE_format == 2){ OBJECT_CODE = (instPtr->Opcode) << 8; // shit left 1 Byte if(OPERAND_ox == 2){ OBJECT_CODE += ((reg_value(OPERAND1) << 4) | reg_value(OPERAND2)); // 2 registers } else{ OBJECT_CODE += (reg_value(OPERAND1) << 4); // 1 register } OBJECT_ox = 1; // need to generate OBJECT CODE convert_ObToString(); // convert int object code to string. } /* else (format 3) */ else if(OPCODE_format == 3){ /* if is Immediate addressing */ if(OPERAND1[0] == '#'){ n = 0; i = 1; } /* else if is Indirect addressing */ else if(OPERAND1[0] == '@'){ n = 1; i = 0; } /* else (simple) */ else{ i = 1; n = 1; } /* Calculate displacement, if OPERAND1 is immediate address constant */ if((OPERAND1[0] == '#') && (OPERAND1[1] >= '0') && (OPERAND1[1] <= '9')){ disp = atoi(&OPERAND1[1]); // we don't need # b = 0; p = 0; } /* else if PC relative */ else if(relative_mode(&disp)){ b = 0; p = 1; } /* else (BASE relative) */ else{ b = 1; p = 0; } /* if is index address */ if((OPERAND_ox == 2) && (OPERAND2[0] == 'X')){ x = 1; } /* else (not index address) */ else{ x = 0; } e = 0; // format 3 /* exception RSUB <-- L */ if(!strcmp(OPCODE, "RSUB")){ n = 1; i = 1; x = 0; b = 0; p = 0; e = 0; disp = reg_L; } /* generate object code */ OBJECT_CODE = (instPtr->Opcode) << 16; // shift left 16 bits OBJECT_CODE += ((n << 17) + (i << 16) + (x << 15) + (b << 14) + (p << 13) + (e << 12)); OBJECT_CODE |= (disp & 0x00000FFF) ; OBJECT_ox = 1; // need to generate OBJECT CODE convert_ObToString(); // convert int object code to string. } /* else if is format 4 */ else if(OPCODE_format == 4){ /* if is Immediate addressing */ if(OPERAND1[0] == '#'){ n = 0; i = 1; } /* else if is Indirect addressing */ else if(OPERAND1[0] == '@'){ n = 1; i = 0; } /* else (simple) */ else{ i = 1; n = 1; } /* Calculate address, if OPERAND1 is immediate address constant */ if((OPERAND1[0] == '#') && (OPERAND1[1] >= '0') && (OPERAND1[1] <= '9')){ disp = atoi(&OPERAND1[1]); // we don't need # b = 0; p = 0; } /* else (direct addressing) */ else{ /* Clean '@' or '#' */ if((OPERAND1[0] == '@') || (OPERAND1[0] == '#')){ temp = &OPERAND1[1]; strcpy(OPERAND1, temp); } /* search SYMTAB */ if(search_SYMTAB(OPERAND1) == 0){ printf("ERROR! %s is not found. It's an invalid SYMBOL\n", OPERAND1); exit(0); } b = 0; p = 0; disp = SYMBOL_ADDR; /* Relocation */ relocate(0); // store address } /* if is index address */ if((OPERAND_ox == 2) && (OPERAND2[0] == 'X')){ x = 1; } /* else (not index address) */ else{ x = 0; } e = 1; // format 4 /* generate object code */ OBJECT_CODE = (instPtr->Opcode) << 24; // shift left 16 bits OBJECT_CODE += ((n << 25) + (i << 24) + (x << 23) + (b << 22) + (p << 21) + (e << 20)); OBJECT_CODE += disp; OBJECT_ox = 1; // need to generate OBJECT CODE convert_ObToString(); // convert int object code to string. } /* else if OPCODE = 'BYTE', then */ else if(!strcmp(OPCODE, "BYTE")){ /* if string */ if(OPERAND1[0] == 'C'){ OBJECT_CODE = (int)OPERAND1[2]; for(j = 3, S_L = 1; OPERAND1[j] != '\''; j++, S_L++){ OBJECT_CODE = (int)OPERAND1[j] + (OBJECT_CODE << 8); } } /* else (char) */ else{ str[0] = OPERAND1[2]; str[1] = OPERAND1[3]; str[2] = '\0'; OBJECT_CODE = (int)strtol(str, NULL, 16); S_L = 1; } OBJECT_ox = 1; convert_ObToString(); } /* else if OPCODE = 'WORD', then */ else if(!strcmp(OPCODE, "BYTE")){ OBJECT_CODE = atoi(OPERAND1); OBJECT_ox = 1; S_L = 1; convert_ObToString(); } /* else if OPCODE = 'BASE', then */ else if(OPCODE_format == 7){ /* search SYMTAB */ if(search_SYMTAB(OPERAND1) == 0){ printf("ERROR! %s is not found. It's an invalid SYMBOL\n", OPERAND1); exit(0); } BASE = SYMBOL_ADDR; OBJECT_ox = 0; } else if(OPCODE_format == 0){ OBJECT_ox = 0; } else{ /* Set ERROR Flag */ printf("ERROR.\n"); exit(0); } // printf("x = %d, b = %d, p = %d, e = %d, disp = %X\n", x, b, p, e, disp); // for testing return ; }