int Or::Execute(Processor* proc) { Operand* dst = mOperands[Operand::DST]; Operand* src = mOperands[Operand::SRC]; if(!dst || !src) { return INVALID_ARGS; } unsigned int dstVal = dst->GetValue(); unsigned int srcVal = src->GetValue(); unsigned int newVal = dstVal | srcVal; unsigned int sign = (dst->GetBitmask() == 0xFF) ? 0x80 : 0x8000; proc->SetFlag(FLAGS_OF, 0); proc->SetFlag(FLAGS_CF, 0); proc->SetFlag(FLAGS_SF, newVal >= sign); proc->SetFlag(FLAGS_ZF, newVal == 0x00); proc->SetFlag(FLAGS_PF, Parity(newVal)); dst->SetValue(newVal); return 0; }
int Adc::Execute(Processor* proc) { Operand* dst = mOperands[Operand::DST]; Operand* src = mOperands[Operand::SRC]; if(!dst || !src) { return INVALID_ARGS; } unsigned int dstVal = dst->GetValue(); unsigned int srcVal = src->GetValue(); unsigned int sign = dst->GetBitmask() == 0xFF ? 0x80 : 0x8000; unsigned int newVal = dstVal + srcVal + (proc->GetFlag(FLAGS_CF) ? 1 : 0); proc->SetFlag(FLAGS_CF, newVal > dst->GetBitmask()); newVal &= dst->GetBitmask(); proc->SetFlag(FLAGS_OF, OverflowAdd(dstVal, srcVal, sign == 0x80 ? 1 : 2)); proc->SetFlag(FLAGS_SF, newVal >= sign); proc->SetFlag(FLAGS_ZF, newVal == 0x00); proc->SetFlag(FLAGS_AF, AdjustAdd(dstVal, srcVal)); proc->SetFlag(FLAGS_PF, Parity(newVal)); dst->SetValue(newVal); return 0; }
double CalculateSequence(const std::vector<ExpressionItem*> i_items, size_t i_startLoc, size_t i_endLoc) { std::vector<ExpressionItem*> currentPriorityResult = CopyItems(i_items, i_startLoc, i_endLoc); for (int priority = 0; priority < OperatorPrioritiesCount; ++priority) { std::vector<ExpressionItem*> newResult = CalculateSequenceForPriority(currentPriorityResult, static_cast<OperatorPriority>(priority)); ClearItems(currentPriorityResult); currentPriorityResult = newResult; } assert(currentPriorityResult.size() == 1); assert(currentPriorityResult[0]->Type() == ExpressionItemTypeOperand); Operand* operand = dynamic_cast<Operand*>(currentPriorityResult[0]); double result = operand->GetValue(); ClearItems(currentPriorityResult); return result; }
std::vector<ExpressionItem*> CopyItems(const std::vector<ExpressionItem*>& i_items, size_t i_from, size_t i_to) { std::vector<ExpressionItem*> result; result.reserve(i_items.size()); for (size_t i = i_from; i < i_to; ++i) { switch (i_items[i]->Type()) { case ExpressionItemTypeOperand: { Operand* operand = dynamic_cast<Operand*>(i_items[i]); result.push_back(new Operand(operand->GetValue(), operand->NestingLevel(), 0)); break; } case ExpressionItemTypeBinaryOperator: { BinaryOperator* bOperator = dynamic_cast<BinaryOperator*>(i_items[i]); result.push_back(BinaryOperator::Copy(bOperator)); break; } } } return result; }
int In::Execute(Processor* proc) { Operand* dst = mOperands[Operand::DST]; Operand* src = mOperands[Operand::SRC]; if(!dst || !src) { return INVALID_ARGS; } if(mOpcode == IN_AL_IMM8 || mOpcode == IN_AL_DX) { dst->SetValue(proc->Inb(src->GetValue())); return 0; } else if(mOpcode == IN_AX_IMM8 || mOpcode == IN_AX_DX) { dst->SetValue(proc->Inw(src->GetValue())); return 0; } return INVALID_ARGS; }
int Out::Execute(Processor* proc) { Operand* dst = mOperands[Operand::DST]; Operand* src = mOperands[Operand::SRC]; if(!dst || !src) { return -1; } if(mOpcode == OUT_IMM8_AL || mOpcode == OUT_DX_AL) { proc->Outb(dst->GetValue(), src->GetValue()); return 0; } else if(mOpcode == OUT_IMM8_AX || mOpcode == OUT_DX_AX) { proc->Outw(dst->GetValue(), src->GetValue()); return 0; } return -1; }
int IDiv::Execute(Processor* proc) { Operand* dst = mOperands[Operand::DST]; if(dst == 0) return INVALID_ARGS; if(dst->GetValue() == 0) { return IDIV_BY_ZERO; } unsigned int dividend = proc->GetRegister(REG_AX) + (mOpcode == IDIV_MOD8 ? 0 : proc->GetRegister(REG_DX) << 0x10); unsigned int divisor = dst->GetValue(); unsigned int divisorNeg = dst->GetBitmask() == 0xFF ? 0x80 : 0x8000; unsigned int dividendNeg = dst->GetBitmask() == 0xFF ? 0x8000 : 0x80000000; unsigned int dividendBm = dst->GetBitmask() == 0xFF ? 0xFFFF : 0xFFFFFFFF; int rem, val; bool neg = (((dividend & dividendNeg) >> 8) ^ (divisor & divisorNeg)) != 0; //positivize everything if(dividend & dividendNeg) { //if dividend is negative dividend = (~dividend + 1) & dividendBm; // +ve it and ensure within bitmask } if(divisor & divisorNeg) { divisor = (~divisor + 1) & dst->GetBitmask(); //all operands are positive rem = -(int)(dividend % divisor); //remainder is negative } else { rem = (dividend % divisor); //remainder is positive } //calc result val = dividend / divisor; // if((unsigned int)val >= divisorNeg) { //operands are positive, so anything this big is overflow return IDIV_DIV_ERR; } //invert if necessary if(neg) val = -val; val &= dst->GetBitmask(); proc->SetRegister(mOpcode == IDIV_MOD8 ? REG_AL : REG_AX, val); proc->SetRegister(mOpcode == IDIV_MOD8 ? REG_AH : REG_DX, rem); return 0; }
int Push::Execute(Processor* proc) { Operand* dst = mOperands[Operand::DST]; if(!dst) { return -1; } proc->PushValue(dst->GetValue()); return 0; }
int Xor::Execute(Processor* proc) { Operand* dst = mOperands[Operand::DST]; Operand* src = mOperands[Operand::SRC]; if(dst == 0 || src == 0) return -1; unsigned int val = dst->GetValue() ^ src->GetValue(); proc->SetFlag(FLAGS_OF, 0); proc->SetFlag(FLAGS_CF, 0); proc->SetFlag(FLAGS_ZF, val == 0); proc->SetFlag(FLAGS_PF, Parity(val)); proc->SetFlag(FLAGS_SF, val >= (dst->GetBitmask() == 0xFF ? 0x80 : 0x8000)); dst->SetValue(val); return 0; }
int Neg::Execute(Processor* proc) { Operand* dst = mOperands[Operand::DST]; if(!dst) { return INVALID_ARGS; } unsigned int dstVal = dst->GetValue(); unsigned int sign = dst->GetBitmask() == 0xFF ? 0x80 : 0x8000; proc->SetFlag(FLAGS_CF, dstVal != 0); proc->SetFlag(FLAGS_OF, dstVal == 0x80); //only overflow is -128 -> -128 dst->SetValue((~dstVal + 1) & dst->GetBitmask()); dstVal = dst->GetValue(); proc->SetFlag(FLAGS_SF, dstVal >= sign); proc->SetFlag(FLAGS_ZF, dstVal == 0x00); proc->SetFlag(FLAGS_PF, Parity(dstVal)); proc->SetFlag(FLAGS_AF, AdjustSub(dstVal, dstVal*2)); return 0; }
int Not::Execute(Processor*) { Operand* dst = mOperands[Operand::DST]; if(!dst) { return INVALID_ARGS; } unsigned int dstVal = dst->GetValue(); dst->SetValue((~dstVal) & dst->GetBitmask()); return 0; }
std::vector<ExpressionItem*> CalculateSequenceForPriority(const std::vector<ExpressionItem*> i_sequence, OperatorPriority i_priority) { assert(i_sequence.size() != 0); std::vector<ExpressionItem*> result; size_t currentLoc = 0; while (currentLoc < i_sequence.size()) { switch (i_sequence[currentLoc]->Type()) { case ExpressionItemTypeOperand: { Operand* operand = dynamic_cast<Operand*>(i_sequence[currentLoc]); result.push_back(new Operand(operand->GetValue(), operand->NestingLevel(), 0)); currentLoc++; break; } case ExpressionItemTypeBinaryOperator: { BinaryOperator* bOperator = dynamic_cast<BinaryOperator*>(i_sequence[currentLoc]); if (bOperator->Priority() == i_priority) { assert(result.size() != 0); assert(result.back()->Type() == ExpressionItemTypeOperand); assert(currentLoc < i_sequence.size() - 1); assert(i_sequence[currentLoc + 1]->Type() == ExpressionItemTypeOperand); Operand* left = dynamic_cast<Operand*>(result.back()); Operand* right = dynamic_cast<Operand*>(i_sequence[currentLoc + 1]); double value = bOperator->CalculateResultForOperands(*left, *right); delete left; result.back() = new Operand(value, right->NestingLevel(), 0); currentLoc += 2; } else { result.push_back(BinaryOperator::Copy(bOperator)); currentLoc++; } break; } default: assert(false); } } return result; }
int Push::Execute(Processor* proc) { if(mOpcode == PUSHA) { unsigned int sp = proc->GetRegister(REG_SP); proc->PushRegister(REG_AX); proc->PushRegister(REG_CX); proc->PushRegister(REG_DX); proc->PushRegister(REG_BX); proc->PushValue(sp); proc->PushRegister(REG_BP); proc->PushRegister(REG_SI); proc->PushRegister(REG_DI); } else { Operand* dst = mOperands[Operand::DST]; if(!dst) { return INVALID_ARGS; } proc->PushValue(dst->GetValue()); } return 0; }
bool Architecture::FormatOperand( Document const& rDoc, Address const& rAddr, Instruction const& rInsn, Operand const& rOprd, u8 OperandNo, PrintData & rPrintData) const { rPrintData.MarkOffset(); auto const& rBinStrm = rDoc.GetBinaryStream(); if (rOprd.GetType() == O_NONE) return true; u32 OprdType = rOprd.GetType(); auto const* pCpuInfo = GetCpuInformation(); std::string MemBegChar = "["; std::string MemEndChar = "]"; if (OprdType & O_MEM) rPrintData.AppendOperator("["); if (OprdType & O_REL || OprdType & O_ABS) { Address DstAddr; if (rInsn.GetOperandReference(rDoc, 0, rAddr, DstAddr)) { auto Lbl = rDoc.GetLabelFromAddress(DstAddr); if (Lbl.GetType() != Label::Unknown) rPrintData.AppendLabel(Lbl.GetLabel()); else rPrintData.AppendAddress(rAddr); } else rPrintData.AppendImmediate(rOprd.GetValue(), rAddr.GetOffsetSize()); } else if (OprdType & O_DISP || OprdType & O_IMM) { if (rOprd.GetType() & O_NO_REF) { rPrintData.AppendImmediate(rOprd.GetValue(), rAddr.GetOffsetSize()); return true; } Address OprdAddr = rDoc.MakeAddress(rOprd.GetSegValue(), rOprd.GetValue()); auto Lbl = rDoc.GetLabelFromAddress(OprdAddr); if (Lbl.GetType() != Label::Unknown) rPrintData.AppendLabel(Lbl.GetLabel()); else rPrintData.AppendAddress(OprdAddr); } else if (OprdType & O_REG) { if (pCpuInfo == nullptr) return false; auto pRegName = pCpuInfo->ConvertIdentifierToName(rOprd.GetReg()); if (pRegName == nullptr) return false; rPrintData.AppendRegister(pRegName); } if (OprdType & O_MEM) rPrintData.AppendOperator("]"); return true; }
double CalculateExpression(const std::string& i_string, size_t& o_errorPos) { std::vector<ExpressionItem*> items; size_t maxNestingLevel = 0; size_t parseResult = ParseExpression(i_string, items, maxNestingLevel); if (parseResult != kDefaultErrorPos) { o_errorPos = parseResult; return 0.0; } size_t validateResult = ValidateExpression(items); if (validateResult != kDefaultErrorPos) { o_errorPos = validateResult; return 0.0; } size_t nestingLevel = maxNestingLevel + 1; while (true) { nestingLevel--; size_t loc = 0; while (loc < items.size()) { while (loc < items.size() && (items[loc]->NestingLevel() != nestingLevel)) { loc++; } if (loc >= items.size()) { break; } size_t startLoc = loc; while (loc < items.size() && (items[loc]->NestingLevel() == nestingLevel)) { loc++; } size_t endLoc = loc; if (startLoc != endLoc) { double value = CalculateSequence(items, startLoc, endLoc); for (size_t i = startLoc; i < endLoc; ++i) { delete items[i]; } items.erase(items.begin() + startLoc, items.begin() + (endLoc - 1)); Operand* operand = new Operand(value, nestingLevel - 1, 0); items[startLoc] = operand; } } if (nestingLevel == 0) { break; } } assert(items.size() == 1); Operand* operand = dynamic_cast<Operand*>(items[0]); double result = operand->GetValue(); delete operand; return result; }