예제 #1
0
파일: TSTRSTCK.CPP 프로젝트: Execsl/usnap
DWord TStringStack::popdw(){
  DWord _RetDWord=0;
  if (!String) return (DWord)0;
  _RetDWord=(DWord)popw();
  _RetDWord+=(DWord)popw()<<16;
  return _RetDWord;
}
예제 #2
0
static void do_retf(struct RealModeCallStructure *rmreg, int rmask)
{
    unsigned int ssp, sp;

    ssp = SEGOFF2LINEAR(READ_RMREG(ss, rmask), 0);
    sp = READ_RMREG(sp, rmask);

    RMREG(ip) = popw(ssp, sp);
    RMREG(cs) = popw(ssp, sp);
    RMREG(sp) += 4;
}
예제 #3
0
파일: virt86.c 프로젝트: rickcaudill/Pyro
void handle_v86_fault( Virtual86Regs_s * regs, uint32 nErrorCode )
{
	unsigned char *csp, *ssp;
	unsigned long ip, sp;
	int nInst;

//  if ( 0xffff == (regs->eip & 0xffff) && 0xffff == regs->cs ) {
//    return_to_32bit( regs, 0 );
//    return;
//  }


	csp = ( unsigned char * )( regs->cs << 4 );
	ssp = ( unsigned char * )( regs->ss << 4 );

	sp = regs->esp & 0xffff;
	ip = regs->eip & 0xffff;

	nInst = popb( csp, ip );
	switch ( nInst )
	{
		/* Operand size override */
	case 0x66:
		printk( "WARNING : 32 bit code run in v86 mode! Flags are not handled properly!\n" );
		nInst = popb( csp, ip );
		switch ( nInst )
		{
			/* pushfd */
		case 0x9c:
			regs->esp = ( regs->esp - 4 ) & 0xffff;
			regs->eip = ( regs->eip + 2 ) & 0xffff;
			pushl( ssp, sp, regs->eflags );
			return;

			/* popfd */
		case 0x9d:
			regs->esp = ( regs->esp + 4 ) & 0xffff;
			regs->eip = ( regs->eip + 2 ) & 0xffff;
			regs->eflags = popl( ssp, sp );
			return;

			/* iretd */
		case 0xcf:
			regs->esp = ( regs->esp + 12 ) & 0xffff;
			regs->eip = ( uint16 )( popl( ssp, sp ) & 0xffff );
			regs->cs = ( uint16 )popl( ssp, sp );
			return;
			/* need this to avoid a fallthrough */
		default:
			printk( "ERROR : unknown v86 32 bit instruction %x\n", nInst );
			return_to_32bit( regs, -EFAULT );
		}

		/* pushf */
	case 0x9c:
		regs->esp = ( regs->esp - 2 ) & 0xffff;
		regs->eip = ( regs->eip + 1 ) & 0xffff;
		pushw( ssp, sp, regs->eflags & 0xffff );
		return;

		/* popf */
	case 0x9d:
		regs->esp = ( regs->esp + 2 ) & 0xffff;
		regs->eip = ( regs->eip + 1 ) & 0xffff;
		regs->eflags = ( regs->eflags & 0xffff0000 ) | ( popw( ssp, sp ) & 0xffff );
		return;

		/* int xx */
	case 0xcd:
		{
			int intno = popb( csp, ip );

			regs->eip = ( regs->eip + 2 ) & 0xffff;
			do_int( regs, intno, ssp, sp );
			return;
		}

		/* iret */
	case 0xcf:
		regs->esp = ( regs->esp + 6 ) & 0xffff;
		regs->eip = popw( ssp, sp ) & 0xffff;
		regs->cs = popw( ssp, sp );

		regs->eflags = ( regs->eflags & 0xffff0000 ) | ( popw( ssp, sp ) & 0xffff );

		if ( 0xffff == ( regs->eip & 0xffff ) && 0xffff == regs->cs )
		{
			return_to_32bit( regs, 0 );
		}

		return;

		/* cli */
	case 0xfa:
		regs->eip = ( regs->eip + 1 ) & 0xffff;
		regs->eflags &= ~EFLG_IF;
		return;

		/* sti */
	case 0xfb:
		/* The interrupts should actually be restored after the NEXT instruction!
		 * Hope this works. As long as no DOS/BIOS code swaps the stack,
		 * nothing bad should happen.
		 */
		regs->eip = ( regs->eip + 1 ) & 0xffff;
		regs->eflags |= EFLG_IF;
		return;
	default:
		printk( "ERROR : unknown v86 16 bit instruction %x\n", nInst );
		return_to_32bit( regs, -EFAULT );
	}
}