📄 i86.c
字号:
OverVal = (tmp ^ (tmp << 1)) & 0x8000;
PutbackRMWord(ModRM,tmp2);
break;
case 0x18: /* RCR ew,1 */
tmp2 = (tmp >> 1) + ((unsigned)CF << 15);
OverVal = !(!(tmp & 0x8000)) != CF;
CarryVal = tmp & 0x01;
PutbackRMWord(ModRM,tmp2);
break;
case 0x20: /* SHL ew,1 */
case 0x30:
tmp <<= 1;
SetCFW(tmp);
SetOFW_Add(tmp,tmp2,tmp2);
AuxVal = 1;
SetSZPF_Word(tmp);
PutbackRMWord(ModRM,tmp);
break;
case 0x28: /* SHR ew,1 */
CarryVal = tmp & 0x01;
OverVal = tmp & 0x8000;
tmp2 = tmp >> 1;
SetSZPF_Word(tmp2);
AuxVal = 1;
PutbackRMWord(ModRM,tmp2);
break;
case 0x38: /* SAR ew,1 */
CarryVal = tmp & 0x01;
OverVal = 0;
tmp2 = (tmp >> 1) | (tmp & 0x8000);
SetSZPF_Word(tmp2);
AuxVal = 1;
PutbackRMWord(ModRM,tmp2);
break;
#else
case 0x00: /* ROL ew,1 */
CarryVal = src & 0x8000;
dst=(src<<1)+CF;
PutbackRMWord(ModRM,dst);
OverVal = (src^dst)&0x8000;
break;
case 0x08: /* ROR ew,1 */
CarryVal = src & 0x01;
dst = ((CF<<16)+src) >> 1;
PutbackRMWord(ModRM,dst);
OverVal = (src^dst)&0x8000;
break;
case 0x10: /* RCL ew,1 */
dst=(src<<1)+CF;
PutbackRMWord(ModRM,dst);
SetCFW(dst);
OverVal = (src^dst)&0x8000;
break;
case 0x18: /* RCR ew,1 */
dst = ((CF<<16)+src) >> 1;
PutbackRMWord(ModRM,dst);
CarryVal = src & 0x01;
OverVal = (src^dst)&0x8000;
break;
case 0x20: /* SHL ew,1 */
case 0x30:
dst = src << 1;
PutbackRMWord(ModRM,dst);
SetCFW(dst);
OverVal = (src^dst)&0x8000;
AuxVal = 1;
SetSZPF_Word(dst);
break;
case 0x28: /* SHR ew,1 */
dst = src >> 1;
PutbackRMWord(ModRM,dst);
CarryVal = src & 0x01;
OverVal = src & 0x8000;
AuxVal = 1;
SetSZPF_Word(dst);
break;
case 0x38: /* SAR ew,1 */
dst = ((INT16)src) >> 1;
PutbackRMWord(ModRM,dst);
CarryVal = src & 0x01;
OverVal = 0;
AuxVal = 1;
SetSZPF_Word(dst);
break;
#endif
}
}
else
{
cycle_count-=8+4*count; /* or 7+4*count if dest is in memory */
switch (ModRM & 0x38)
{
case 0x00: /* ROL ew,count */
for (; count > 0; count--)
{
CarryVal = dst & 0x8000;
dst = (dst << 1) + CF;
}
PutbackRMWord(ModRM,dst);
break;
case 0x08: /* ROR ew,count */
for (; count > 0; count--)
{
CarryVal = dst & 0x01;
dst = (dst >> 1) + (CF << 15);
}
PutbackRMWord(ModRM,dst);
break;
case 0x10: /* RCL ew,count */
for (; count > 0; count--)
{
dst = (dst << 1) + CF;
SetCFW(dst);
}
PutbackRMWord(ModRM,dst);
break;
case 0x18: /* RCR ew,count */
for (; count > 0; count--)
{
dst = dst + (CF << 16);
CarryVal = dst & 0x01;
dst >>= 1;
}
PutbackRMWord(ModRM,dst);
break;
case 0x20:
case 0x30: /* SHL ew,count */
dst <<= count;
SetCFW(dst);
AuxVal = 1;
SetSZPF_Word(dst);
PutbackRMWord(ModRM,dst);
break;
case 0x28: /* SHR ew,count */
dst >>= count-1;
CarryVal = dst & 0x1;
dst >>= 1;
SetSZPF_Word(dst);
AuxVal = 1;
PutbackRMWord(ModRM,dst);
break;
case 0x38: /* SAR ew,count */
dst = ((INT16)dst) >> (count-1);
CarryVal = dst & 0x01;
dst = ((INT16)((WORD)dst)) >> 1;
SetSZPF_Word(dst);
AuxVal = 1;
PutbackRMWord(ModRM,dst);
break;
}
}
}
static void i_rotshft_bd8(void) /* Opcode 0xc0 */
{
unsigned ModRM=FETCH;
unsigned count=FETCH;
rotate_shift_Byte(ModRM,count);
}
static void i_rotshft_wd8(void) /* Opcode 0xc1 */
{
unsigned ModRM=FETCH;
unsigned count=FETCH;
rotate_shift_Word(ModRM,count);
}
static void i_ret_d16(void) /* Opcode 0xc2 */
{
unsigned count = FETCH;
count += FETCH << 8;
POP(ip);
regs.w[SP]+=count;
cycle_count-=14;
}
static void i_ret(void) /* Opcode 0xc3 */
{
POP(ip);
cycle_count-=10;
}
static void i_les_dw(void) /* Opcode 0xc4 */
{
unsigned ModRM = FETCH;
WORD tmp = GetRMWord(ModRM);
RegWord(ModRM)= tmp;
sregs[ES] = GetnextRMWord;
base[ES] = SegBase(ES);
cycle_count-=4;
}
static void i_lds_dw(void) /* Opcode 0xc5 */
{
unsigned ModRM = FETCH;
WORD tmp = GetRMWord(ModRM);
RegWord(ModRM)=tmp;
sregs[DS] = GetnextRMWord;
base[DS] = SegBase(DS);
cycle_count-=4;
}
static void i_mov_bd8(void) /* Opcode 0xc6 */
{
unsigned ModRM = FETCH;
cycle_count-=4;
PutImmRMByte(ModRM);
}
static void i_mov_wd16(void) /* Opcode 0xc7 */
{
unsigned ModRM = FETCH;
cycle_count-=4;
PutImmRMWord(ModRM);
}
static void i_enter(void) /* Opcode 0xc8 */
{
unsigned nb = FETCH;
unsigned i,level;
cycle_count-=11;
nb += FETCH << 8;
level=FETCH;
PUSH(regs.w[BP]);
regs.w[BP]=regs.w[SP];
regs.w[SP] -= nb;
for (i=1;i<level;i++) {
PUSH(GetMemW(SS,regs.w[BP]-i*2));
cycle_count-=4;
}
if (level) PUSH(regs.w[BP]);
}
static void i_leave(void) /* Opcode 0xc9 */
{
cycle_count-=5;
regs.w[SP]=regs.w[BP];
POP(regs.w[BP]);
}
static void i_retf_d16(void) /* Opcode 0xca */
{
unsigned count = FETCH;
count += FETCH << 8;
POP(ip);
POP(sregs[CS]);
base[CS] = SegBase(CS);
regs.w[SP]+=count;
cycle_count-=13;
}
static void i_retf(void) /* Opcode 0xcb */
{
POP(ip);
POP(sregs[CS]);
base[CS] = SegBase(CS);
cycle_count-=14;
}
static void i_int3(void) /* Opcode 0xcc */
{
cycle_count-=16;
I86_interrupt(3);
}
static void i_int(void) /* Opcode 0xcd */
{
unsigned int_num = FETCH;
cycle_count-=15;
I86_interrupt(int_num);
}
static void i_into(void) /* Opcode 0xce */
{
if (OF) {
cycle_count-=17;
I86_interrupt(4);
} else cycle_count-=4;
}
static void i_iret(void) /* Opcode 0xcf */
{
cycle_count-=12;
POP(ip);
POP(sregs[CS]);
base[CS] = SegBase(CS);
i_popf();
}
static void i_rotshft_b(void) /* Opcode 0xd0 */
{
rotate_shift_Byte(FETCH,1);
}
static void i_rotshft_w(void) /* Opcode 0xd1 */
{
rotate_shift_Word(FETCH,1);
}
static void i_rotshft_bcl(void) /* Opcode 0xd2 */
{
rotate_shift_Byte(FETCH,regs.b[CL]);
}
static void i_rotshft_wcl(void) /* Opcode 0xd3 */
{
rotate_shift_Word(FETCH,regs.b[CL]);
}
static void i_aam(void) /* Opcode 0xd4 */
{
unsigned mult = FETCH;
cycle_count-=83;
if (mult == 0)
I86_interrupt(0);
else
{
regs.b[AH] = regs.b[AL] / mult;
regs.b[AL] %= mult;
SetSZPF_Word(regs.w[AX]);
}
}
static void i_aad(void) /* Opcode 0xd5 */
{
unsigned mult = FETCH;
cycle_count-=60;
regs.b[AL] = regs.b[AH] * mult + regs.b[AL];
regs.b[AH] = 0;
SetZF(regs.b[AL]);
SetPF(regs.b[AL]);
SignVal = 0;
}
static void i_xlat(void) /* Opcode 0xd7 */
{
unsigned dest = regs.w[BX]+regs.b[AL];
cycle_count-=5;
regs.b[AL] = GetMemB(DS, dest);
}
static void i_escape(void) /* Opcodes 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde and 0xdf */
{
unsigned ModRM = FETCH;
cycle_count-=2;
GetRMByte(ModRM);
}
static void i_loopne(void) /* Opcode 0xe0 */
{
int disp = (int)((INT8)FETCH);
unsigned tmp = regs.w[CX]-1;
regs.w[CX]=tmp;
if (!ZF && tmp) {
cycle_count-=19;
ip = (WORD)(ip+disp);
} else cycle_count-=5;
}
static void i_loope(void) /* Opcode 0xe1 */
{
int disp = (int)((INT8)FETCH);
unsigned tmp = regs.w[CX]-1;
regs.w[CX]=tmp;
if (ZF && tmp) {
cycle_count-=18;
ip = (WORD)(ip+disp);
} else cycle_count-=6;
}
static void i_loop(void) /* Opcode 0xe2 */
{
int disp = (int)((INT8)FETCH);
unsigned tmp = regs.w[CX]-1;
regs.w[CX]=tmp;
if (tmp) {
cycle_count-=17;
ip = (WORD)(ip+disp);
} else cycle_count-=5;
}
static void i_jcxz(void) /* Opcode 0xe3 */
{
int disp = (int)((INT8)FETCH);
if (regs.w[CX] == 0) {
cycle_count-=18;
ip = (WORD)(ip+disp);
} else cycle_count-=6;
}
static void i_inal(void) /* Opcode 0xe4 */
{
unsigned port = FETCH;
cycle_count-=10;
regs.b[AL] = read_port(port);
}
static void i_inax(void) /* Opcode 0xe5 */
{
unsigned port = FETCH;
cycle_count-=14;
regs.b[AL] = read_port(port);
regs.b[AH] = read_port(port+1);
}
static void i_outal(void) /* Opcode 0xe6 */
{
unsigned port = FETCH;
cycle_count-=10;
write_port(port, regs.b[AL]);
}
static void i_outax(void) /* Opcode 0xe7 */
{
unsigned port = FETCH;
cycle_count-=14;
write_port(port, regs.b[AL]);
write_port(port+1, regs.b[AH]);
}
static void i_call_d16(void) /* Opcode 0xe8 */
{
unsigned tmp = FETCH;
tmp += FETCH << 8;
PUSH(ip);
ip = (WORD)(ip+(INT16)tmp);
cycle_count-=12;
}
static void i_jmp_d16(void) /* Opcode 0xe9 */
{
int tmp = FETCH;
tmp += FETCH << 8;
ip = (WORD)(ip+(INT16)tmp);
cycle_count-=15;
}
static void i_jmp_far(void) /* Opcode 0xea */
{
unsigned tmp,tmp1;
tmp = FETCH;
tmp += FETCH << 8;
tmp1 = FETCH;
tmp1 += FETCH << 8;
sregs[CS] = (WORD)tmp1;
base[CS] = SegBase(CS);
ip = (WORD)tmp;
cycle_count-=15;
}
static void i_jmp_d8(void) /* Opcode 0xeb */
{
int tmp = (int)((INT8)FETCH);
ip = (WORD)(ip+tmp);
cycle_count-=15;
}
static void i_inaldx(void) /* Opcode 0xec */
{
cycle_count-=8;
regs.b[AL] = read_port(regs.w[DX]);
}
static void i_inaxdx(void) /* Opcode 0xed */
{
unsigned port = regs.w[DX];
cycle_count-=12;
regs.b[AL] = read_port(port);
regs.b[AH] = read_port(port+1);
}
static void i_outdxal(void) /* Opcode 0xee */
{
cycle_count-=8;
write_port(regs.w[DX], regs.b[AL]);
}
static void i_outdxax(void) /* Opcode 0xef */
{
unsigned port = regs.w[DX];
cycle_count-=12;
write_port(port, regs.b[AL]);
write_port(port+1, regs.b[AH]);
}
static void i_lock(void) /* Opcode 0xf0 */
{
cycle_count-=2;
instruction[FETCH](); /* un-interruptible */
}
static void rep(int flagval)
{
/* Handles rep- and repnz- prefixes. flagval is the value of ZF for the
loop to continue for CMPS and SCAS instructions. */
unsigned next = FETCH;
unsigned count = regs.w[CX];
switch(next)
{
case 0x26: /* ES: */
seg_prefix=TRUE;
prefix_base=base[ES];
cycle_count-=2;
rep(flagval);
break;
case 0x2e: /* CS: */
seg_prefix=TRUE;
prefix_base=base[CS];
cycle_count-=2;
rep(flagval);
break;
case 0x36: /* SS: */
seg_prefix=TRUE;
prefix_base=base[SS];
cycle_count-=2;
rep(flagval);
break;
case 0x3e: /* DS: */
seg_prefix=TRUE;
prefix_base=base[DS];
cycle_count-=2;
rep(flagval);
break;
case 0x6c: /* REP INSB */
cycle_count-=9-count;
for (; count > 0; count--)
i_insb();
regs.w[CX]=count;
break;
case 0x6d: /* REP INSW */
cycle_count-=9-count;
for (; count > 0; count--)
i_insw();
regs.w[CX]=count;
break;
case 0x6e: /* REP OUTSB */
cycle_count-=9-count;
for (; count > 0; count--)
i_outsb();
regs.w[CX]=count;
break;
case 0x6f: /* REP OUTSW */
cycle_count-=9-count;
for (; count > 0; count--)
i_outsw();
regs.w[CX]=count;
break;
case 0xa4: /* REP MOVSB */
cycle_count-=9-count;
for (; count > 0; count--)
i_movsb();
regs.w[CX]=count;
break;
case 0xa5: /* REP MOVSW */
cycle_count-=9-count;
for (; count > 0; count--)
i_movsw();
regs.w[CX]=count;
break;
case 0xa6: /* REP(N)E CMPSB */
cycle_count-=9;
for (ZeroVal = !flagval; (ZF == flagval) && (count > 0); count--)
i_cmpsb();
regs.w[CX]=count;
break;
case 0xa7: /* REP(N)E CMPSW */
cycle_count-=9;
for (ZeroVal = !flagval; (ZF == flagval) && (count > 0); count--)
i_cmpsw();
regs.w[CX]=count;
break;
case 0xaa: /* REP STOSB */
cycle_count-=9-count;
for (; count > 0; count--)
i_stosb();
regs.w[CX]=count;
break;
case 0xab: /* REP STOSW */
cycle_count-=9-count;
for (; count > 0; count--)
i_stosw();
regs.w[CX]=count;
break;
case 0xac: /* REP LODSB */
cycle_count-=9;
for (; count > 0; count--)
i_lodsb();
regs.w[CX]=count;
break;
case 0xad: /* REP LODSW */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -