/* Pass-1 assembly algorithm */ void pass1(FILE *src_file){ FILE *intr_file, *symtab; SIC_src_instr src_line; //Lines read from source file SIC_int_instr intr_line; //Lines written to intermediate file SIC_word bytes,inc,const_len; SIC_addr locctr; //Macros for writting structs in shortcut #define bytes (bytes.val) #define locctr (locctr.val) #define inc (inc.val) #define const_len (const_len.val) //Symbol table for the current source file. if((symtab = fopen(".symtab","w")) == NULL){ fprintf(stderr,"\nError: Could not open SYMTAB.\n"); exit(EXIT_FAILURE); } //Generating output(intermediate) filename if((intr_file=fopen(".intermediate","w")) == NULL){ fprintf(stderr,"Error: Could not open intermediate file\n"); exit(1); } read_line_src(src_file, &src_line); strcpy(program_info.prog_name, src_line.label); //Get program name(or procedure name) intr_line.instr = &src_line; //Partial intermediate line constructed #define start_addr start_addr.val /* opcode=="START" */ if(strcmp(src_line.opcode,"START")==0){ uint16_t temp; sscanf(src_line.operand, "%x", &temp); program_info.start_addr = temp; locctr = program_info.start_addr; intr_line.addr.val = temp; write_line_intr(intr_file, &intr_line); //Define these two functions read_line_src(src_file, &src_line); //Second line onwards } else locctr = 0; /* Read rest of the lines */ while(strcmp(src_line.opcode,"END")!=0){ if(strcmp(src_line.label,".") == 0){ //If comment line read_line_src(src_file, &src_line); continue; } inc = 0; //increment value for locctr if(strcmp(src_line.label,"-")!=0){//If there is something in the label field if(search_symtab(src_line.label) == FOUND){ //Symbol already defined fprintf(stderr,"(%s : %d)\n", __FILE__, __LINE__); fprintf(stderr,"\nError: Symbol '%s' is already defined.\n",src_line.label); } else{ //Insert the (symbol,locctr) pair into the SYMTAB fprintf(symtab, "%s\t%X\n", src_line.label, locctr); }//if search_symtab() fflush(symtab); }//if label is not empty(Not an error) //else fprintf(stderr,"\nEmpty label.\n"); /* Search OPTAB for opcode */ if(search_optab(src_line.opcode) == FOUND){//Search OPTAB for opcode inc += WORDSIZE; //printf("\nOpcode is valid.\n"); } /* Check the opcode field with various assembler directives */ else if(strcmp(src_line.opcode,"WORD")==0) inc = WORDSIZE; else if(strcmp(src_line.opcode,"RESW")==0) inc = (WORDSIZE * atoi(src_line.operand)); else if(strcmp(src_line.opcode,"RESB")==0) inc = atoi(src_line.operand); else if(strcmp(src_line.opcode,"BYTE")==0){ if(src_line.operand[0] == 'C')//For character constants const_len = strlen(index(src_line.operand,SINGLEQUOTE)) - 2; //Excluding ' from the string 'EOF' else if(src_line.operand[0] == 'X')//For hexadecimal constants const_len = 1; else{ //@ERR: invalid_const_f = 1; //Invalid constant type flag fprintf(stderr,"(%s : %d)\n", __FILE__, __LINE__); fprintf(stderr,"\nError: Invalid constant type '%s'\n", src_line.operand); } inc = const_len; } else{ //@ERR: invalid_op_f = 1; //Invalid opcode flag fprintf(stderr,"(%s : %d)\n", __FILE__, __LINE__); fprintf(stderr,"\nError: Invalid opcode.\tAt label: %s\n",src_line.label); exit(1); }//if(search OPTAB) //printf("-----------------------------------------------\n"); //Only change address member of intr_line. That's why I used the 2nd member as a pointer to src_line. intr_line.addr.val = locctr; write_line_intr(intr_file, &intr_line);//Write line to intermediate file locctr += inc; //Update locctr now read_line_src(src_file, &src_line); //Read next input line //reset_flags(); //Reset all flags }//while() intr_line.addr.val = locctr; write_line_intr(intr_file, &intr_line); //Write last line program_info.prog_len = (locctr - program_info.start_addr) + 1; //printf("\nLength of program = %d(DEC) or %X(HEX)\n",prog_len,prog_len); fclose(src_file); fclose(symtab); fclose(intr_file); }
/* Pass-2 assembly algorithm */ void pass2() { FILE *intr_file, *listing, *obj_prog, *src_file; char symval[10]="", obj_code[10]=""; char *objprog_name, text_rec[81]=""; //81bytes is enough to hold a text record. int txtrec_ctr; //Text record counter int reswb_f = 0; //RESW or RESB found flag. A special flag used during object program production by pass2 only SIC_addr hex_addr; //program length is just taken as fixed for now. SIC_reg index = 0x08; //X = 0000 1000(Just taken) SIC_src_instr src_line; //Part of intr_line SIC_int_instr intr_line; //Lines read from intermediate file SIC_list_instr list_line; //Lines written to listing file intr_line.instr = &src_line; //Associate src_line to intr_line for use list_line.instr = &intr_line; //Associate intr_line to list_line for use strcpy(list_line.obj_code,""); //Clear the objcode[] member #define hex_addr (hex_addr.val) //Input source file if((src_file = fopen(program_info.file_name,"r")) == NULL){ fprintf(stderr,"(%s : %d)\n", __FILE__, __LINE__); fprintf(stderr,"\nError: Could not open source file\n"); exit(1); } if((intr_file = fopen(".intermediate","r")) == NULL){ fprintf(stderr,"(%s : %d)\n", __FILE__, __LINE__); fprintf(stderr,"\nError: Could not load intermediate file\n"); exit(1); } if((listing = fopen(".listing","w")) == NULL){ //Assembly listing file fprintf(stderr,"(%s : %d)\n", __FILE__, __LINE__); fprintf(stderr,"Error: Cannot open listing file\n"); exit(1); } objprog_name = (char*)calloc(strlen(program_info.file_name),sizeof(char)); strncpy(objprog_name, program_info.file_name, strcspn(program_info.file_name, ".")); strcat(objprog_name,".o"); //Object program file if((obj_prog = fopen(objprog_name,"w")) == NULL){ fprintf(stderr,"(%s : %d)\n", __FILE__, __LINE__); fprintf(stderr,"\nError: Could not open object file\n"); exit(1); } //reset_flags(); //Reset all flags //Read first line of intermediate file read_line_intr(intr_file, &intr_line); //First startement of the source program if(strcmp(intr_line.instr->opcode,"START")==0){ write_line_list(listing, &list_line); //Write object program header record fprintf(obj_prog, "H^%-6s^%06X^%06X\n", program_info.prog_name, program_info.start_addr, program_info.prog_len); read_line_intr(intr_file, &intr_line); } //Initialize first text record fprintf(obj_prog,"T^%06X^",intr_line.addr.val); fflush(obj_prog); //Scan intermediate file till 'END' statement or End of file(EOF) while((strcmp(intr_line.instr->opcode,"END")!=0) && !feof(intr_file)){ //If comment line if(strcmp(intr_line.instr->label,".") == 0){ read_line_intr(intr_file, &intr_line); continue; } //Else parse line.... if(search_optab(intr_line.instr->opcode) == FOUND){ //Opcode found if(strcmp(intr_line.instr->operand,"-") != 0){//Not an empty label field if(search_symtab(intr_line.instr->operand) == FOUND){//Symbol found generate_objcode_addr(intr_line.instr->operand); } else if(strstr(intr_line.instr->operand,",X") != (char*)0){ //For indexed addressing, add value of X to address char temp_sym[10]=""; //uint16_t temp; SIC_addr temp_addr; //Extract the symbol(excluding ',X') from the operand field strncpy(temp_sym,intr_line.instr->operand,strcspn(intr_line.instr->operand,",X")); if(search_symtab(temp_sym) == NOTFOUND){ fprintf(stderr,"(%s : %d)\n", __FILE__, __LINE__); fprintf(stderr,"Error: Invalid symbol '%s'\n", temp_sym); exit(1); } generate_objcode_addr(temp_sym); //Address of label at temp_sym(not original operand) hex_addr += index; //Add hex_addr+index_register. Computed as integers } else{ //Invalid symbol hex_addr = 0; //@ERR: sym_f = 1; //Invalid symbol flag } }//operand "-" else hex_addr = 0; //@strcpy(symval,"0000"); //sscanf("0","%X",&hex_addr); //Make the complete object code sprintf(symval,"%04X",hex_addr); //printf("symval: %s\thex_addr: %d\n",symval,hex_addr); strcpy(obj_code,get_hexcode(intr_line.instr->opcode)); // 04 //@strcat(obj_code,symval); strcat(obj_code,symval); //04400C strcpy(list_line.obj_code, obj_code); //Copy it to list_line struct member for write_line_list() operation. }//end if opcode found else if(strcmp(intr_line.instr->opcode,"WORD")==0){ //uint16_t temp; //sscanf(intr_line.instr->operand,"%X",&temp); hex_addr = intr_line.addr.val; sprintf(obj_code,"%06X",hex_addr); strcpy(list_line.obj_code, obj_code); //Copy it to list_line struct member for write_line_list() operation. } else if(strcmp(intr_line.instr->opcode,"BYTE")==0){ char temp[10]=""; //Temp constant value variable if(intr_line.instr->operand[0] == 'C'){ //Eg: C'EOF' char *ptr; ptr = strstr(intr_line.instr->operand,"'") + 1; if(strcmp(ptr,"EOF'") == 0) strcpy(temp, "454F46"); //Any other character constants can be added here.....TODO else{ fprintf(stderr,"(%s : %d)\n", __FILE__, __LINE__); fprintf(stderr,"Error: Invalid constand type\tAt label: %s\n",intr_line.instr->label); exit(1); } } else if(intr_line.instr->operand[0] == 'X'){ //Eg: X'F1' char *ptr; short int i=0; ptr = strstr(intr_line.instr->operand,"'") + 1; while(*ptr != SINGLEQUOTE){ temp[i] = *ptr; ptr++; i++; } temp[i] = '\0'; } strcpy(symval, temp); strcpy(obj_code, symval); strcpy(list_line.obj_code, obj_code); //Copy it to list_line struct member for write_line_list() operation. } //For RESW and RESB else if((strcmp(intr_line.instr->opcode,"RESW")==0) || (strcmp(intr_line.instr->opcode,"RESB")==0)){ strcpy(obj_code,""); strcpy(list_line.obj_code, ""); //Copy it to list_line struct member for write_line_list() operation. //@txtrec_end_f = 1; } //else neither an opcode nor a directive //Text record production begins here... if((txtrec_ctr < MAXTRLEN) && (strcmp(intr_line.instr->opcode,"RESW") && strcmp(intr_line.instr->opcode,"RESB"))){ if(reswb_f){ //if RESW or RESB was last found then new text record should begin fprintf(obj_prog,"%02X",txtrec_ctr); fprintf(obj_prog,"%s\n",text_rec); //Reset text_rec string strcpy(text_rec,""); txtrec_ctr = 0x0; //uint16_t temp; //sscanf(intr_line.addr,"%X",&temp); //hex_addr = temp; fprintf(obj_prog,"T^%06X^",intr_line.addr); reswb_f = 0; } //Add obj_code to current text record.(Be careful from adding a '^' with a NULL obj_code) if(strcmp(obj_code,"") != 0){ strcat(text_rec,"^"); strcat(text_rec,obj_code); txtrec_ctr += 0x03; // (+ 03H) default for simple SIC } } else if(!strcmp(intr_line.instr->opcode,"RESW") || !strcmp(intr_line.instr->opcode,"RESB")) reswb_f = 1; //RESW,RESB was found flag else{ //no more place in the current text record.Create a new one //Time to flush the generated text_rec string and prepare for a new text record, if any //Insert the 'length' and 'object codes' fields of the currently ending text record fprintf(obj_prog,"%02X",txtrec_ctr); fprintf(obj_prog,"%s\n",text_rec); //Reset text_rec string strcpy(text_rec,""); txtrec_ctr = 0x0; //uint16_t temp; //sscanf(intr_line.addr,"%X",&temp); hex_addr = intr_line.addr.val; fprintf(obj_prog,"T^%06X^",hex_addr); if(strcmp(obj_code,"") != 0){ strcat(text_rec,"^"); strcat(text_rec,obj_code); txtrec_ctr += 0x03; } } //Write to assembly listing file write_line_list(listing, &list_line); //Read next line read_line_intr(intr_file, &intr_line); }//while(END) //Insert the left over text record, if any if(strcmp(text_rec,"") != 0){ //Insert the 'length' and 'object codes' fields of the currently ending text record fprintf(obj_prog,"%02X",txtrec_ctr); fprintf(obj_prog,"%s\n",text_rec); } //Write last line to assembly listing file write_line_list(listing, &list_line); //Write the END record fprintf(obj_prog,"E^%06X", program_info.start_addr); //Close all files fclose(listing); fclose(intr_file); fclose(obj_prog); }
int main(int argc,char *argv[]) { if(argc!=2) { printf("Usage: %s <input file>\n",argv[0]); exit(1); } /* Load Optab */ char ***optab=NULL; int num_ops; if( (optab=load_optab("opfile",&num_ops)) == NULL) { printf("Optab generation failed\n"); exit(2); } /* Now let us load and initialize the symtab */ sym_tab *symtab=NULL; if( (symtab=init_symtab())==NULL ) { printf("Failed to initiate symtab\n"); free_optab(optab,num_ops); exit(3); } FILE *inp_file=NULL; if( (inp_file=fopen(argv[1],"r")) == NULL ) { printf("Failed to open input file\n"); free_optab(optab,num_ops); free_symtab(symtab); exit(4); } FILE *out_file=NULL; char *int_filename=NULL; if( (int_filename=(char *)malloc(strlen(argv[1])+5)) == NULL ) { printf("Out of memory\n"); free_optab(optab,num_ops); free_symtab(symtab); exit(5); } strcpy(int_filename,argv[1]); strcat(int_filename,"_INT"); FILE *int_file=NULL; if( (int_file=fopen(int_filename,"w+")) == NULL ) { printf("Failed to open intermediate file\n"); free_optab(optab,num_ops); free_symtab(symtab); free(int_filename); fclose(inp_file); exit(6); } /* And Here We Go */ long int LOCCTR=0; long int start_addr; char *read_line=NULL; size_t to_read = 0; ssize_t read_len; char *work_string=NULL; char *work_string2=NULL; char *prog_name=NULL; char *search_space=NULL; int start_loop=0; while( (read_len=getline(&read_line,&to_read,inp_file)) != -1 ) { if( (search_space=(char *)malloc(read_len+1)) == NULL ) { printf("Out of memory\n"); fclose(inp_file); fclose(int_file); free(int_filename); free(read_line); free_optab(optab,num_ops); free_symtab(symtab); exit(10); } strcpy(search_space,""); sscanf(read_line,"%s",search_space); if(((*search_space)=='\0')||((*search_space)==';')) { free(search_space); search_space=NULL; free(read_line); read_line=NULL; continue; } free(search_space); search_space=NULL; if( (prog_name=malloc(read_len+1)) == NULL ) { printf("Out of memory\n"); fclose(inp_file); fclose(int_file); free(int_filename); free_optab(optab,num_ops); free_symtab(symtab); exit(7); } if( (work_string=malloc( (read_len-strlen(prog_name)) +1) ) == NULL) { printf("Out of memory\n"); fclose(inp_file); fclose(int_file); free(prog_name); free(int_filename); free_optab(optab,num_ops); free_symtab(symtab); exit(7); } sscanf(read_line,"%s%s",prog_name,work_string); if(!strcmp(work_string,"START")) { if( (work_string2=malloc((read_len-strlen(work_string))+1)) == NULL ) { free(work_string); free(prog_name); fclose(inp_file); fclose(int_file); free(int_filename); free_optab(optab,num_ops); free_symtab(symtab); printf("Out of memory\n"); exit(8); } char *searched=strstr(read_line,work_string); sscanf(searched+strlen(work_string),"%s",work_string2); if((*work_string2)=='\0') { printf("START directive requires an argument\n"); free(work_string); free(prog_name); free(work_string2); fclose(inp_file); fclose(int_file); free(int_filename); free_optab(optab,num_ops); free_symtab(symtab); exit(9); } char *waste; LOCCTR=strtol(work_string2,&waste,16); if(waste == work_string2) { printf("Bad Assembly coding...\n"); printf("No suitable value for operand for START directive\n"); free(work_string); free(prog_name); free(work_string2); fclose(inp_file); fclose(int_file); free(int_filename); free_optab(optab,num_ops); free_symtab(symtab); exit(9); } start_addr=LOCCTR; fprintf(int_file,"%lX\t%s\t%s\t%lX\n",LOCCTR,prog_name,work_string,start_addr); free(work_string2); free(prog_name); prog_name=NULL; free(work_string); work_string=NULL; free(read_line); read_line=NULL; to_read=0; while( (read_len=getline(&read_line,&to_read,inp_file)) != -1) { if( (search_space=(char *)malloc(read_len+1)) == NULL ) { printf("Out of memory\n"); fclose(inp_file); fclose(int_file); free(int_filename); free(read_line); free_optab(optab,num_ops); free_symtab(symtab); exit(10); } strcpy(search_space,""); sscanf(read_line,"%s",search_space); if(((*search_space)=='\0')||((*search_space)==';')) { free(search_space); search_space=NULL; free(read_line); read_line=NULL; continue; } free(search_space); search_space=NULL; break; } start_loop=1; } else { LOCCTR=start_addr=0; start_loop=1; } if(start_loop) break; } // Check if the loop exited becuase the EOF was reached. If so exit... if(read_len == -1) { if(read_line) free(read_line); fclose(inp_file); fclose(int_file); free(int_filename); free_optab(optab,num_ops); free_symtab(symtab); exit(0); } if( (work_string=malloc(read_len+1)) == NULL ) { printf("Out of memory\n"); fclose(inp_file); fclose(int_file); free(int_filename); free(read_line); free_optab(optab,num_ops); free_symtab(symtab); exit(11); } char *label=NULL; char *pneumonic=NULL; char *operand=NULL; decode(read_line,read_len,&label,&pneumonic,&operand,int_filename,inp_file,int_file,NULL,optab,num_ops,symtab,LOCCTR,NULL); if(label) label[strlen(label)-1]='\0'; while(strcmp(pneumonic,"END")) { if(label) fprintf(int_file,"%lX\t%s\t%s\t%s\n",LOCCTR,label,pneumonic,operand); else { if(operand) fprintf(int_file,"%lX\t%s\t%s\n",LOCCTR,pneumonic,operand); else fprintf(int_file,"%lX\t%s\n",LOCCTR,pneumonic); } if(label) { label[strlen(label)-1]='\0'; if(search_symtab(symtab,label)>0) { printf("Duplicate symbol at %lX\n",LOCCTR); fclose(inp_file); fclose(int_file); free(int_filename); free(read_line); if(label) free(label); if(operand) free(operand); if(pneumonic) free(pneumonic); free_optab(optab,num_ops); free_symtab(symtab); exit(12); } else { if(insert_symtab(label,symtab,LOCCTR)!=0) { printf("Failed to insert into symtab\n"); fclose(inp_file); fclose(int_file); free(int_filename); free(read_line); if(label) free(label); if(operand) free(operand); if(pneumonic) free(pneumonic); free_optab(optab,num_ops); free_symtab(symtab); exit(13); } } } char *opcode,*waste; if( (opcode=search_optab(optab,pneumonic,num_ops)) != NULL) { LOCCTR+=3; } else if(!strcmp(pneumonic,"WORD")) { LOCCTR+=3; } else if(!strcmp(pneumonic,"RESW")) { if(operand == NULL) { printf("Bad assembly coding...\n"); printf("No value given for operand near RESW directive at %lX\n",LOCCTR); fclose(inp_file); fclose(int_file); free(int_filename); free(read_line); if(label) free(label); if(operand) free(operand); if(pneumonic) free(pneumonic); free_optab(optab,num_ops); free_symtab(symtab); exit(23); } else { LOCCTR+=(3*strtol(operand,&waste,10)); if(waste == operand) { printf("Bad assembly coding...\n"); printf("No suitable value was found for allocating memory for RESW directive at %lX\n",LOCCTR); fclose(inp_file); fclose(int_file); free(int_filename); free(read_line); if(label) free(label); if(operand) free(operand); if(pneumonic) free(pneumonic); free_optab(optab,num_ops); free_symtab(symtab); exit(21); } } } else if(!strcmp(pneumonic,"RESB")) { if(operand == NULL) { printf("Bad assembly coding...\n"); printf("No value given for operand near RESB directive at %lX\n",LOCCTR); fclose(inp_file); fclose(int_file); free(int_filename); free(read_line); if(label) free(label); if(operand) free(operand); if(pneumonic) free(pneumonic); free_optab(optab,num_ops); free_symtab(symtab); exit(23); } else { LOCCTR+=(strtol(operand,&waste,10)); if(waste == operand) { printf("Bad assembly coding...\n"); printf("No suitable value was found for allocating memory for RESB directive at %lX\n",LOCCTR); fclose(inp_file); fclose(int_file); free(int_filename); free(read_line); if(label) free(label); if(operand) free(operand); if(pneumonic) free(pneumonic); free_optab(optab,num_ops); free_symtab(symtab); exit(22); } } } else if(!strcmp(pneumonic,"BYTE")) { long int old_locctr=LOCCTR; if(!operand) { printf("Bad assembly coding...\n"); printf("No operand corresponding to BYTE directive at %lX\n",LOCCTR); fclose(inp_file); fclose(int_file); free(int_filename); free(read_line); if(label) free(label); if(operand) free(operand); if(pneumonic) free(pneumonic); free_optab(optab,num_ops); free_symtab(symtab); exit(52); } if( ((*operand)=='c')|| ((*operand)=='C')) LOCCTR+=(strlen(operand)-3); else if( ((*operand)=='x')|| ((*operand)=='X')) { LOCCTR+=(strlen(operand)-3)/2; if( (strlen(operand)-3)%2) LOCCTR+=1; } else { printf("Bad assembly coding...\n"); printf("Wrong format for constant\n"); fclose(inp_file); fclose(int_file); free(int_filename); free(read_line); if(label) free(label); if(operand) free(operand); if(pneumonic) free(pneumonic); free_optab(optab,num_ops); free_symtab(symtab); exit(14); } if( (LOCCTR-old_locctr)>MC_SIZE ) { printf("Constant value too long...\n"); fclose(inp_file); fclose(int_file); free(int_filename); free(read_line); if(label) free(label); if(operand) free(operand); if(pneumonic) free(pneumonic); free_optab(optab,num_ops); free_symtab(symtab); exit(50); } if( !( (strlen(operand)>=4)&&(operand[1]=='\'')&&(operand[strlen(operand)-1]=='\'') ) ) { printf("Format for constant is convoluted at %lX...\n",old_locctr); fclose(inp_file); fclose(int_file); free(int_filename); free(read_line); if(label) free(label); if(operand) free(operand); if(pneumonic) free(pneumonic); free_optab(optab,num_ops); free_symtab(symtab); exit(51); } } else { printf("Opcode not found at %lX...\n",LOCCTR); fclose(inp_file); fclose(int_file); free(int_filename); free(read_line); if(label) free(label); if(operand) free(operand); if(pneumonic) free(pneumonic); free_optab(optab,num_ops); free_symtab(symtab); exit(15); } if(label) free(label); if(operand) free(operand); if(pneumonic) free(pneumonic); read_line=NULL; to_read=0; while( (read_len=getline(&read_line,&to_read,inp_file)) != -1) { if( (search_space=(char *)malloc(read_len+1)) == NULL ) { printf("Out of memory\n"); fclose(inp_file); fclose(int_file); free(int_filename); free(read_line); free_optab(optab,num_ops); free_symtab(symtab); exit(10); } strcpy(search_space,""); sscanf(read_line,"%s",search_space); if(((*search_space)=='\0')||((*search_space)==';')) { free(search_space); search_space=NULL; free(read_line); read_line=NULL; continue; } free(search_space); search_space=NULL; break; } if(read_len == -1) { printf("Bad assembly coding...\n"); printf("End of file was reached before END directive\n"); fclose(int_file); fclose(inp_file); free(int_filename); free_optab(optab,num_ops); free_symtab(symtab); exit(16); } label=NULL; pneumonic=NULL; operand=NULL; decode(read_line,read_len,&label,&pneumonic,&operand,int_filename,inp_file,int_file,NULL,optab,num_ops,symtab,LOCCTR,NULL); } //First Pass finished... Beginning second pass if(label) free(label); if(operand) free(operand); if(pneumonic) free(pneumonic); fprintf(int_file,"%lX\t%s",LOCCTR,read_line); free(read_line); label=NULL; operand=NULL; pneumonic=NULL; read_line=NULL; fclose(inp_file); out_file=fopen("a.out","w+"); if( out_file == NULL) { printf("Failed to open output file...\n"); fclose(int_file); free(int_filename); free_optab(optab,num_ops); free_symtab(symtab); exit(30); } //Write out the intermediate file and re-open it for second pass fclose(int_file); int_file=fopen(int_filename,"r"); if( int_file == NULL) { printf("Failed to open intermediate file...\n"); fclose(out_file); free(int_filename); free_optab(optab,num_ops); free_symtab(symtab); exit(31); } int_file=fopen(int_filename,"r"); if( int_file == NULL) { printf("Failed to open intermediate file...\n"); fclose(out_file); free(int_filename); free_optab(optab,num_ops); free_symtab(symtab); exit(31); } char *read_raw_line=NULL; char string_loc[35]; while( (read_len=getline(&read_raw_line,&to_read,int_file)) != -1) { read_raw_line[strlen(read_raw_line)-1]='\0'; fprintf(out_file,"%s",read_raw_line); read_raw_line[strlen(read_raw_line)]='\n'; memset(mc,0,MC_SIZE); //We dont have to worry about about newlines spaces etc sscanf(read_raw_line,"%s",string_loc); read_line=read_raw_line+strlen(string_loc)+1; decode(read_line,read_len,&label,&pneumonic,&operand,int_filename,NULL,int_file,out_file,optab,num_ops,symtab,LOCCTR,read_raw_line); if(!label) fprintf(out_file,"\t"); if(!operand) fprintf(out_file,"\t"); char *opcode; long int add; if( (opcode=search_optab(optab,pneumonic,num_ops)) != NULL ) { sprintf(mc,"%s",opcode); if(operand) { if( (add=search_symtab(symtab,operand)) > 0 ) { sprintf(mc+strlen(mc),"%lX",add); } else { printf("Operand not available in symbol table\n"); fclose(int_file); fclose(out_file); free(int_filename); free(read_raw_line); free_optab(optab,num_ops); free_symtab(symtab); exit(35); } } } else if(!strcmp(pneumonic,"BYTE")) { convert_const(&operand); } read_raw_line[strlen(read_raw_line)-1]='\0'; fprintf(out_file,"\t\t%s\n",mc); if(label) free(label); if(operand) free(operand); if(pneumonic) free(pneumonic); label=pneumonic=operand=NULL; free(read_raw_line); read_raw_line=NULL; } if(label) free(label); if(operand) free(operand); if(pneumonic) free(pneumonic); fclose(int_file); fclose(out_file); free(int_filename); free_optab(optab,num_ops); free_symtab(symtab); return 0; }