예제 #1
0
파일: Or.cpp 프로젝트: DarrenStahl/Libra
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;
}
예제 #2
0
파일: Adc.cpp 프로젝트: DarrenStahl/Libra
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;
}
예제 #3
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;
  }
예제 #4
0
  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;
  }
예제 #5
0
파일: In.cpp 프로젝트: DarrenStahl/Libra
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;
}
예제 #6
0
파일: Out.cpp 프로젝트: rdnelson/Libra
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;
}
예제 #7
0
파일: IDiv.cpp 프로젝트: DarrenStahl/Libra
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;
}
예제 #8
0
파일: Push.cpp 프로젝트: rdnelson/Libra
int Push::Execute(Processor* proc) {

	Operand* dst = mOperands[Operand::DST];
	if(!dst) {
		return -1;
	}

	proc->PushValue(dst->GetValue());
	return 0;
}
예제 #9
0
파일: Xor.cpp 프로젝트: rdnelson/Libra
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;
}
예제 #10
0
파일: Neg.cpp 프로젝트: DarrenStahl/Libra
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;
}
예제 #11
0
파일: Not.cpp 프로젝트: DarrenStahl/Libra
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;
}
예제 #12
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;
  }
예제 #13
0
파일: Push.cpp 프로젝트: DarrenStahl/Libra
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;
}
예제 #14
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;
}
예제 #15
0
  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;
  }