Exemple #1
0
  void
bx_cpu_c::RETnear32_Iw(BxInstruction_t *i)
{
  Bit16u imm16;
  Bit32u temp_ESP;
  Bit32u return_EIP;

#if BX_DEBUGGER
  bx_cpu. show_flag |= Flag_ret;
#endif

  if (bx_cpu. sregs[BX_SEG_REG_SS].cache.u.segment.d_b) /* 32bit stack */
    temp_ESP = ESP;
  else
    temp_ESP = SP;

  imm16 = i->Iw;

  invalidate_prefetch_q();


    if (protected_mode()) {
      if ( !can_pop(4) ) {
        BX_PANIC(("retnear_iw: can't pop EIP"));
        /* ??? #SS(0) -or #GP(0) */
        }

      access_linear(bx_cpu. sregs[BX_SEG_REG_SS].cache.u.segment.base + temp_ESP + 0,
        4, CPL==3, BX_READ, &return_EIP);

      if (protected_mode() &&
          (return_EIP > bx_cpu. sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled) ) {
        BX_DEBUG(("retnear_iw: EIP > limit"));
        exception(BX_GP_EXCEPTION, 0, 0);
        }

      /* Pentium book says imm16 is number of words ??? */
      if ( !can_pop(4 + imm16) ) {
        BX_PANIC(("retnear_iw: can't release bytes from stack"));
        /* #GP(0) -or #SS(0) ??? */
        }

      bx_cpu. eip = return_EIP;
      if (bx_cpu. sregs[BX_SEG_REG_SS].cache.u.segment.d_b) /* 32bit stack */
        ESP += 4 + imm16; /* ??? should it be 2*imm16 ? */
      else
        SP  += 4 + imm16;
      }
    else {
      pop_32(&return_EIP);
      bx_cpu. eip = return_EIP;
      if (bx_cpu. sregs[BX_SEG_REG_SS].cache.u.segment.d_b) /* 32bit stack */
        ESP += imm16; /* ??? should it be 2*imm16 ? */
      else
        SP  += imm16;
      }

  BX_INSTR_UCNEAR_BRANCH(BX_INSTR_IS_RET, bx_cpu. eip);
}
Exemple #2
0
  void
bx_cpu_c::pop_32(Bit32u *value32_ptr)
{
  Bit32u temp_ESP;

  /* 32 bit stack mode: use SS:ESP */
  if (bx_cpu. sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
    temp_ESP = ESP;
  else
    temp_ESP = SP;

  /* 16 bit stack mode: use SS:SP */
  if (protected_mode()) {
    if ( !can_pop(4) ) {
      BX_PANIC(("pop_32(): can't pop from stack"));
      exception(BX_SS_EXCEPTION, 0, 0);
      return;
      }
    }

  /* access within limits */
  read_virtual_dword(BX_SEG_REG_SS, temp_ESP, value32_ptr);

  if (bx_cpu. sregs[BX_SEG_REG_SS].cache.u.segment.d_b==1)
    ESP += 4;
  else
    SP += 4;
}
Exemple #3
0
  void
bx_cpu_c::pop_16(Bit16u *value16_ptr)
{
  Bit32u temp_ESP;

#if BX_CPU_LEVEL >= 3
  if (bx_cpu. sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
    temp_ESP = ESP;
  else
#endif
    temp_ESP = SP;

#if BX_CPU_LEVEL >= 2
  if (protected_mode()) {
    if ( !can_pop(2) ) {
      BX_INFO(("pop_16(): can't pop from stack"));
      exception(BX_SS_EXCEPTION, 0, 0);
      return;
      }
    }
#endif


  /* access within limits */
  read_virtual_word(BX_SEG_REG_SS, temp_ESP, value16_ptr);

  if (bx_cpu. sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
    ESP += 2;
  else
    SP += 2;
}
Exemple #4
0
bool MyDeque::pop_back(char &ch)
{
  if (ready() == false) 
    return false;

  bool ret = true;
  if (can_pop())
  {
    begin_ = ((begin_ - 1) % len_);
    ch = *(q_ + begin_);
  }
  else
  {
    ret = false;
  }
  return ret;
}
Exemple #5
0
bool MyDeque::pop_front(char &ch)
{
  if (ready() == false) 
    return false;
// return end point value, ++end
  bool ret = true;
  if (can_pop())
  {
    ch = *(q_ + end_);
    end_ = ((end_ + 1) % len_);
  }
  else
  {
    ret = false;
  }
  return ret;
}
Exemple #6
0
  void
bx_cpu_c::RETnear32(BxInstruction_t *i)
{
  Bit32u temp_ESP;
  Bit32u return_EIP;

#if BX_DEBUGGER
  bx_cpu. show_flag |= Flag_ret;
#endif

  invalidate_prefetch_q();

  if (bx_cpu. sregs[BX_SEG_REG_SS].cache.u.segment.d_b) /* 32bit stack */
    temp_ESP = ESP;
  else
    temp_ESP = SP;


    if (protected_mode()) {
      if ( !can_pop(4) ) {
        BX_PANIC(("retnear: can't pop EIP"));
        /* ??? #SS(0) -or #GP(0) */
        }

      access_linear(bx_cpu. sregs[BX_SEG_REG_SS].cache.u.segment.base + temp_ESP + 0,
        4, CPL==3, BX_READ, &return_EIP);

      if ( return_EIP > bx_cpu. sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled ) {
        BX_PANIC(("retnear: EIP > limit"));
        //exception(BX_GP_EXCEPTION, 0, 0);
        }
      bx_cpu. eip = return_EIP;
      if (bx_cpu. sregs[BX_SEG_REG_SS].cache.u.segment.d_b) /* 32bit stack */
        ESP += 4;
      else
        SP  += 4;
      }
    else {
      pop_32(&return_EIP);
      bx_cpu. eip = return_EIP;
      }

  BX_INSTR_UCNEAR_BRANCH(BX_INSTR_IS_RET, bx_cpu. eip);
}
Exemple #7
0
  void
bx_cpu_c::POPAD16(BxInstruction_t *i)
{
#if BX_CPU_LEVEL < 2
  BX_PANIC(("POPAD not supported on an 8086"));
#else /* 286+ */

    Bit16u di, si, bp, tmp, bx, dx, cx, ax;

    if (protected_mode()) {
      if ( !can_pop(16) ) {
        BX_PANIC(("pop_a: not enough bytes on stack"));
        exception(BX_SS_EXCEPTION, 0, 0);
        return;
        }
      }

    /* ??? optimize this */
    pop_16(&di);
    pop_16(&si);
    pop_16(&bp);
    pop_16(&tmp); /* value for SP discarded */
    pop_16(&bx);
    pop_16(&dx);
    pop_16(&cx);
    pop_16(&ax);

    DI = di;
    SI = si;
    BP = bp;
    BX = bx;
    DX = dx;
    CX = cx;
    AX = ax;
#endif
}