Beispiel #1
0
//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);
}
Beispiel #2
0
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);
		}
	}
}