char C_CPU::Step(unsigned char* code, int offset) { char *segover; int rep, lock, asize, osize, i, slen, colon; int segsize = 1; insn ins; int works; struct itemplate **p; for (;;) { if (*code == 0xF3 || *code == 0xF2) { rep = *code++; } else if (*code == 0xF0) { lock = *code++; } else if (*code == 0x2E || *code == 0x36 || *code == 0x3E || *code == 0x26 || *code == 0x64 || *code == 0x65) { switch (*code++) { case 0x2E: segover = "cs"; break; case 0x36: segover = "ss"; break; case 0x3E: segover = "ds"; break; case 0x26: segover = "es"; break; case 0x64: segover = "fs"; break; case 0x65: segover = "gs"; break; } } else if (*code == 0x66) { osize = 48 - segsize, code++; } else if (*code == 0x67) { asize = 48 - segsize, code++; } else { break; } } ins.oprs[0].segment = ins.oprs[1].segment = ins.oprs[2].segment = ins.oprs[0].addr_size = ins.oprs[1].addr_size = ins.oprs[2].addr_size = (segsize == 16 ? 0 : SEG_32BIT); ins.condition = -1; works = true; for (p = itable[*data]; *p; p++) if ( (length = matches((unsigned char *)((*p)->code), data, asize, osize, segsize, &ins)) ) { works = TRUE; /* * Final check to make sure the types of r/m match up. */ for (i = 0; i < (*p)->operands; i++) if ( /* If it's a mem-only EA but we have a register, die. */ ((ins.oprs[i].segment & SEG_RMREG) && !(MEMORY & ~(*p)->opd[i])) || /* If it's a reg-only EA but we have a memory ref, die. */ (!(ins.oprs[i].segment & SEG_RMREG) && !(REGNORM & ~(*p)->opd[i]) && !((*p)->opd[i] & REG_SMASK)) || /* Register type mismatch (eg FS vs REG_DESS): die. */ ((((*p)->opd[i] & (REGISTER | FPUREG)) || (ins.oprs[i].segment & SEG_RMREG)) && !whichreg ((*p)->opd[i], ins.oprs[i].basereg))) works = FALSE; if (works) break; } if(*(code+offset) != 0x0F) { return Step1(code, offset); } else { return Step2(code,offset); } }