// second iteration: // - insert correct addresses for variables and jump-addresses int Assembler::make_program() { if (debug > 0) printf("\n[FUNCTION: make_program]\n"); if (debug > 1) printf("\tinitialize %i bytes for program\n",length_of_code); // create byte-array for program: program = (uint8_t*)malloc(length_of_code); memset(program, 0, length_of_code); // initialize byte-counter: int c = 0; // iterate through preprogram: for (list<Precode>::iterator pc_iterator = preprogram.begin(); pc_iterator != preprogram.end(); pc_iterator++) { if (debug > 1) printf("STATUS: reading next precode\n"); // get current code: uint8_t code = pc_iterator->code; if (pc_iterator != preprogram.begin()) { program[pc_iterator->address + length_of_header] = code; c = pc_iterator->address + length_of_header + 1; } else { program[pc_iterator->address] = code; c = pc_iterator->address+ 1; } if (debug > 1) printf("VAR: code at byte %i: %i\n",pc_iterator->address,code); //check if current command is command with parameters and add them to program: int value, err = -1; // case jump-label: if (code == JMP || code == JGZ || code == JOF || code == JEZ || code == JNO) { if (debug > 1) printf("CASE: jump - get address\n"); err = find_label_address(pc_iterator->param1, &value); } // case var-name: if (code == LDA || code == LDB || code == STR || code == MOV) { if (debug > 1) printf("CASE: variable - get address\n"); err = find_var_address(pc_iterator->param1, &value); } // case constant value: if (code == LDC) { if (debug > 1) printf("Case: constant value\n"); value = pc_iterator->val; // set err to 0 to flag for parsing: err = 0; } // if no error occured: if (err == 0) { parse_int(value, &program[c]); c += WORDSIZE; } else if (err != -1) return 1; err = -1; // check if current command has second parameter, and add it to program: // case MOV: if (code == MOV) { if (debug > 1) printf("Case: move - get second address\n"); err = find_var_address(pc_iterator->param2, &value); } //if no error occured: if (err == 0) { parse_int(value, &program[c]); c += WORDSIZE; } else if (err != -1) return 1; } return 0; }
/*** process_file * This function is the main input file processing loop. It takes the instruction string in ASM and turns it into * machine code. First, the op-code and corresponding funct are determined and then the register names are read in and processed. * The offset and jsec values are determined using other functions. ***/ struct instruction* process_file(struct instruction *inst, FILE *input) { char string[BUFFER_SIZE]; //note that the current instruction address is tracked. this is for use with branching and jumps. int op, r1, r2, r3, funct, offset, jsec, address=0x4000; while(fscanf(input, "%s", string) != EOF) { if (check_for_label(string) == 1) { fscanf(input, "%s", string); } set_op_funct(&op, &funct, string); if (op == 0) //add, sub, and, or, slt, sltu { fscanf(input, "%s", string); r3 = get_reg(string); fscanf(input, "%s", string); r1 = get_reg(string); fscanf(input, "%s", string); r2 = get_reg(string); offset = 0; jsec = 0; } else if (op == 2) //j { r1 = 0; r2 = 0; r3 = 0; offset = 0; fscanf(input, "%s", string); jsec = find_label_address(inst, strcat(string,":")); } else if (op == 4) //beq { fscanf(input, "%s", string); r1 = get_reg(string); fscanf(input, "%s", string); r2 = get_reg(string); r3 = 0; fscanf(input, "%s", string); offset = calculate_offset(address, find_label_address(inst, strcat(string,":"))); jsec = 0; } else if (op == 8) //addi { fscanf(input, "%s", string); r1 = get_reg(string); fscanf(input, "%s", string); r2 = get_reg(string); r3 = 0; fscanf(input, "%d", &offset); jsec = 0; } else if (op == 10 || op == 11) //slti, sltiu { fscanf(input, "%s", string); r2 = get_reg(string); fscanf(input, "%s", string); r1 = get_reg(string); r3 = 0; fscanf(input, "%d", &offset); jsec = 0; } else if (op == 15) //lui { fscanf(input, "%s", string); r1 = 0; r2 = get_reg(string); r3 = 0; fscanf(input, "%d", &offset); jsec = 0; } else if (op == 35 || op == 43) //lw, sw { fscanf(input, "%s", string); r2 = get_reg(string); fscanf(input, "%s", string); int offset, reg; get_mem_offset_and_word_reg(string, &offset, ®); r1 = reg; r3 = 0; offset = offset; jsec = 0; } inst = modify_ll_node(inst, address, op, r1, r2, r3, funct, offset, jsec); address += 0x4; //the current address is incremented by 4 after every instruction is processed } return inst; }