/* Disassembles an assembled instruction, including its operands. */ int disassembleInstruction(disassembledInstruction *dInstruction, const assembledInstruction *aInstruction, int instructionSetIndex) { int instructionIndex, i; if (dInstruction == NULL) return ERROR_INVALID_ARGUMENTS; if (instructionSetIndex != PIC_BASELINE && instructionSetIndex != PIC_MIDRANGE && instructionSetIndex != PIC_MIDRANGE_ENHANCED) return ERROR_INVALID_ARGUMENTS; /* Look up the instruction */ instructionIndex = lookupInstruction(aInstruction->opcode, 0, instructionSetIndex); /* Copy over the address, and reference to the instruction, set * the equivilant-encoded but different instruction to NULL for now. */ dInstruction->address = aInstruction->address; dInstruction->instruction = &(allInstructionSets[instructionSetIndex].instructionSet[instructionIndex]); dInstruction->alternateInstruction = NULL; /* Copy out each operand, extracting the operand data from the original * opcode using the operand mask. */ for (i = 0; i < allInstructionSets[instructionSetIndex].instructionSet[instructionIndex].numOperands; i++) dInstruction->operands[i] = extractDataFromMask(aInstruction->opcode, dInstruction->instruction->operandMasks[i]); /* Disassemble operands */ if (disassembleOperands(dInstruction) < 0) return ERROR_INVALID_ARGUMENTS; /* Only possible error for disassembleOperands() */ return 0; }
/* Disassembles an assembled instruction, including its operands. */ int disassembleInstruction(disassembledInstruction *dInstruction, const assembledInstruction aInstruction) { int insidx, i; if (dInstruction == NULL) return ERROR_INVALID_ARGUMENTS; /* Look up the instruction */ insidx = lookupInstruction(aInstruction.opcode, 0); if (insidx == AVR_TOTAL_INSTRUCTIONS) { // invalid instruction return 0; } /*** AVR SPECIFIC */ /* If a long instruction was found in the last instruction disassembly, * extract the rest of the address, and indicate that it is to be printed */ if (AVR_Long_Instruction == AVR_LONG_INSTRUCTION_FOUND) { AVR_Long_Instruction = AVR_LONG_INSTRUCTION_PRINT; AVR_Long_Address |= aInstruction.opcode; /* We must multiply by two, because every instruction is 2 bytes, * so in order to jump/call to the right address (which increments by * two for every instruction), we must multiply this distance by two. */ //printf ("ii=%d\n", insidx); if (insidx==86) AVR_Long_Address *= 2; *dInstruction = longInstruction; return 0; /* If a long instruction was printed in the last instruction disassembly, * reset the AVR_Call_Instruction variable back to zero. */ } else if (AVR_Long_Instruction == AVR_LONG_INSTRUCTION_PRINT) { AVR_Long_Instruction = 0; } /* Copy over the address, and reference to the instruction, set * the equivilant-encoded but different instruction to NULL for now. */ dInstruction->address = aInstruction.address; dInstruction->instruction = &instructionSet[insidx]; dInstruction->alternateInstruction = NULL; /* Copy out each operand, extracting the operand data from the original * opcode using the operand mask. */ for (i = 0; i < instructionSet[insidx].numOperands; i++) { dInstruction->operands[i] = extractDataFromMask(aInstruction.opcode, dInstruction->instruction->operandMasks[i]); /*** AVR SPECIFIC */ /* If this is an instruction with a long absolute operand, indicate that a long instruction has been found, * and extract the first part of the long address. */ if (dInstruction->instruction->operandTypes[i] == OPERAND_LONG_ABSOLUTE_ADDRESS) { AVR_Long_Instruction = AVR_LONG_INSTRUCTION_FOUND; AVR_Long_Address = dInstruction->operands[i] << 16; longInstruction = *dInstruction; } } /* Disassemble operands */ if (disassembleOperands(dInstruction) < 0) return ERROR_INVALID_ARGUMENTS; /* Only possible error for disassembleOperands() */ if (AVR_Long_Instruction == AVR_LONG_INSTRUCTION_FOUND) { /* If we found a long instruction (32-bit one), * Copy this instruction over to our special longInstruction variable, that * will exist even after we move onto the next 16-bits */ longInstruction = *dInstruction; } return 0; }