//Checks if the instruction is valid char* checkInstruction(char line[], int currentAddress) { static char command[50], opcode[6]; char data[16], function[6]; static int nRegisters, nConstants, nLabels; char type; int i = 0; strcpy(command, line); //Take the mnemonic features strcpy(data, findInstruction(getMnemonic(command))); data[16] = '\0'; //If the mnemonic not exists if(strcmp(data, "NULL") == 0) return "4"; //Take the instruction type, n of regs, n of consts and n of labels. type = data[0]; nRegisters = data[1] - 48; nConstants = data[2] - 48; nLabels = data[3] - 48; //Take the opcode for(i = 0; i<6; i++) opcode[i] = data[i+4]; opcode[i] ='\0'; if(type == 'R'){ //Take the function for(i = 0; i<6; i++) function[i] = data[i+10]; function[i] ='\0'; } return mountBinary(command, nRegisters, nConstants, nLabels, type, opcode, function, currentAddress); }
void linkInstructionBranches(Instructions &instructions) { /* Go through all instructions and link them according to the flow graph. * * In specifics, link each instruction's follower, the instruction that * naturally follows if no branches are taken. Also fill in the branches * array, which contains all branches an instruction can take. This * directly creates an address type for each instruction: does it start * a subroutine, is it a jump destination, is it a tail of a jump or none * of these? */ for (Instructions::iterator i = instructions.begin(); i != instructions.end(); ++i) { // If this is an instruction that has a natural follower, link it if ((i->opcode != kOpcodeJMP) && (i->opcode != kOpcodeRETN)) { Instructions::iterator follower = i + 1; i->follower = (follower != instructions.end()) ? &*follower : 0; if (follower != instructions.end()) follower->predecessors.push_back(&*i); } // Link destinations of unconditional branches if ((i->opcode == kOpcodeJMP) || (i->opcode == kOpcodeJSR) || (i->opcode == kOpcodeSTORESTATE)) { assert(((i->opcode == kOpcodeSTORESTATE) && (i->argCount == 3)) || (i->argCount == 1)); Instruction *branch = findInstruction(instructions, i->address + i->args[0]); if (!branch) throw Common::Exception("Can't find destination of unconditional branch"); i->branches.push_back(branch); if (i->opcode == kOpcodeJSR) setAddressType(branch, kAddressTypeSubRoutine); else if (i->opcode == kOpcodeSTORESTATE) setAddressType(branch, kAddressTypeStoreState); else { setAddressType(branch, kAddressTypeJumpLabel); branch->predecessors.push_back(&*i); } setAddressType(const_cast<Instruction *>(i->follower), kAddressTypeTail); } // Link destinations of conditional branches if ((i->opcode == kOpcodeJZ) || (i->opcode == kOpcodeJNZ)) { assert(i->argCount == 1); if (!i->follower) throw Common::Exception("Conditional branch has no false destination"); Instruction *branch = findInstruction(instructions, i->address + i->args[0]); if (!branch) throw Common::Exception("Can't find destination of conditional branch"); setAddressType(branch, kAddressTypeJumpLabel); setAddressType(const_cast<Instruction *>(i->follower), kAddressTypeTail); i->branches.push_back(branch); // True branch i->branches.push_back(i->follower); // False branch branch->predecessors.push_back(&*i); } } }