📄 decode.c
字号:
case 5:handle_arith_rm_imm(sub,operand1,immediate,Instruction.wFlag);break; case 6:handle_arith_rm_imm(xor,operand1,immediate,Instruction.wFlag);break; case 7:handle_arith_rm_imm(cmp,operand1,immediate,Instruction.wFlag);break; } break; /* push pop operations */ case 0x07 : case 0x17: case 0x1F: case 0x06: case 0x0E: case 0x16: case 0x1E: Instruction.Opcode = *currentCode; if(*currentCode & 1) /* pop es, ss, ds */ handle_pop16(*((word*)(&cpu.sreg)+((*currentCode>>3)&3))); else /* push es, cs, ss, ds */ handle_push16(*((word*)(&cpu.sreg)+((*currentCode>>3)&3))); currentCode++; cpu.ip++; break; case 0x50: case 0x51: case 0x52: case 0x53: case 0x54: case 0x55: case 0x56: case 0x57: case 0x58: case 0x59: case 0x5A: case 0x5B: case 0x5C: case 0x5D: case 0x5E: case 0x5F: Instruction.Opcode = *currentCode; if((*currentCode >> 3) & 1) /*pop general 16-bit register*/ handle_pop16(*((word*)(&cpu.greg)+(*currentCode & 7))); else /*push general 16-bit register*/ { handle_push16((*((word*)(&cpu.greg)+(*currentCode & 7)))); if((*currentCode&7)==4) *((word*)(cpu.ram+(cpu.sreg.ss<<4)+cpu.greg.sp))+=2; /* amend sp */ } currentCode++; cpu.ip++; break; case 0x60: case 0x61: case 0x9C: case 0x9D: Instruction.Opcode = *currentCode; if(*currentCode&1) { if((*currentCode>>7)&1) /* popf */ handle_pop16(cpu.flags); else /* popa */ for(i=0;i<8;i++) handle_pop16((*((word*)(&cpu.greg)+i))); } else { if((*currentCode>>7)&1) /* pushf */ handle_push16(cpu.flags); else /* pusha */ { for(i=0;i<8;i++) handle_push16((*((word*)(&cpu.greg)+i))); *((word*)(cpu.ram+(cpu.sreg.ss<<4)+cpu.greg.sp)-3)+=(5*2); /* amend sp to original value */ } } currentCode++; cpu.ip++; break; case 0x68: case 0x6A: /* push imm16/32; push imm8 */ Instruction.Opcode = *currentCode; Instruction.sFlag = (*currentCode >> 1) & 1; currentCode++; cpu.ip++; currentCode = ParseImmediate(currentCode, &Instruction, &immediate); if(Instruction.sFlag) /* push imm8 */ handle_push8(Instruction.Immediate); else /* push imm16 */ handle_push16(Instruction.Immediate); break; case 0x8F: /* pop imm16 */ Instruction.Opcode = *currentCode; Instruction.wFlag = (*currentCode) & 1; currentCode++; cpu.ip++; currentCode = ParseModRM(currentCode, &Instruction, &operand1); handle_pop16((*((word*)(cpu.ram+operand1.value)))); break; case 0x27: case 0x2F: case 0x37: case 0x3F: Instruction.Opcode = *currentCode; op=(*currentCode >> 3) & 3; switch(op) { case 0:handle_bcdadjust(daa);break; case 1:handle_bcdadjust(das);break; case 2:handle_bcdadjust(aaa);break; case 3:handle_bcdadjust(aas);break; } currentCode++; cpu.ip++; break; /* inc and dec: 16-bit general register */ case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47: case 0x48: case 0x49: case 0x4A: case 0x4B: case 0x4C: case 0x4D: case 0x4E: case 0x4F: Instruction.Opcode = *currentCode; Instruction.wFlag = 1; operand1.RM=REG16; operand1.value=(int)greg16_addr(*currentCode&7); if((*currentCode >> 3) & 1) { handle_incdec(dec,operand1,Instruction.wFlag);} else { handle_incdec(inc,operand1,Instruction.wFlag);} currentCode++; cpu.ip++; break; /* bound */ case 0x62: Instruction.Opcode = *currentCode; Instruction.wFlag = *currentCode & 1; Instruction.sFlag = (*currentCode >> 1) & 1; /*!(Instruction.OperandPrefix >= 0) ? Register16[(*(currentCode + 1) >> 3) & 7]:Register32[(*(currentCode + 1) >> 3) & 7]);*/ currentCode++; cpu.ip++; currentCode = ParseModRM(currentCode, &Instruction, &operand2); /* special case, the size of memory address must be twice the size of register */ break; /* arpl */ case 0x63: Instruction.Opcode = *currentCode; /* special case, the operand size of arpl must be 16-bits */ Instruction.OperandPrefix = 0; Instruction.wFlag = 1; Instruction.dFlag = 0; //sprintf(mnemonic, "%s", "arpl"); currentCode++; cpu.ip++; currentCode = ParseRegModRM(currentCode, &Instruction, &operand1, &operand2); break; /* imul */ case 0x69: case 0x6B: Instruction.Opcode = *currentCode; Instruction.wFlag = *currentCode & 1; Instruction.sFlag = (*currentCode >> 1) & 1; Instruction.dFlag = (*currentCode >> 1) & 1; //sprintf(mnemonic, "%s", "imul"); currentCode++; cpu.ip++; currentCode = ParseRegModRM(currentCode, &Instruction, &operand1, &operand2); currentCode = ParseImmediate(currentCode, &Instruction, &immediate); break; /* ins and outs */ case 0x6C: case 0x6D: case 0x6E: case 0x6F: Instruction.Opcode = *currentCode; Instruction.wFlag = *currentCode & 1; Instruction.dFlag = (*currentCode >> 1) & 1; //sprintf(prefix, "%s", Instruction.RepeatPrefix > 0 ? RepeatPrefixes[(int)Instruction.RepeatPrefix] : ""); //sprintf(mnemonic, "%s%c", Instruction.dFlag ? "outs" : "ins", Instruction.wFlag ? // (Instruction.OperandPrefix >= 0 ? 'w' : 'd') : 'b'); currentCode++; cpu.ip++; break; /* jmp instructions j(n)xx */ case 0x70: case 0x71: case 0x72: case 0x73: case 0x74: case 0x75: case 0x76: case 0x77: case 0x78: case 0x79: case 0x7A: case 0x7B: case 0x7C: case 0x7D: case 0x7E: case 0x7F: Instruction.Opcode = *currentCode; currentCode++; cpu.ip++; int address = Instruction.LinearAddress + *((char*)currentCode) + currentCode - Code + 1 - (cpu.sreg.cs<<4); switch((Instruction.Opcode>>1)&7) { case 0: /* jo jno */ if((Instruction.Opcode&1)&&((cpu.flags&FLAG_O)==0)) cpu.ip=address; else if(!(Instruction.Opcode&1) && (cpu.flags&FLAG_O)!=0) cpu.ip=address; else cpu.ip++; break; case 1: /*jb jnb*/ if((Instruction.Opcode&1)&&((cpu.flags&FLAG_C)==0)) cpu.ip=address; else if(!(Instruction.Opcode&1) && (cpu.flags&FLAG_C)!=0) cpu.ip=address; else cpu.ip++; break; case 2: /*jz jnz*/ if((Instruction.Opcode&1)&&((cpu.flags&FLAG_Z)==0)) cpu.ip=address; else if(!(Instruction.Opcode&1) && (cpu.flags&FLAG_Z)!=0) cpu.ip=address; else cpu.ip++; break; case 3: /*jbe ja*/ if((Instruction.Opcode&1)&&(((cpu.flags&FLAG_Z)==0)&&((cpu.flags&FLAG_C)==0))) cpu.ip=address; else if((Instruction.Opcode&1)&&(((cpu.flags&FLAG_Z)!=0)||((cpu.flags&FLAG_C)!=0))) cpu.ip=address; else cpu.ip++; break; case 4: /*js jns*/ if((Instruction.Opcode&1)&&((cpu.flags&FLAG_S)==0)) cpu.ip=address; else if(!(Instruction.Opcode&1) && (cpu.flags&FLAG_S)!=0) cpu.ip=address; else cpu.ip++; break; case 5: /*jp jnp*/ if((Instruction.Opcode&1)&&((cpu.flags&FLAG_P)==0)) cpu.ip=address; else if(!(Instruction.Opcode&1) && (cpu.flags&FLAG_P)!=0) cpu.ip=address; else cpu.ip++; break; case 6: /*jl jge*/ if((Instruction.Opcode&1)&&(((cpu.flags&FLAG_S)==0)&&((cpu.flags&FLAG_O)==0))) cpu.ip=address; else if((Instruction.Opcode&1)&&(((cpu.flags&FLAG_S)!=0)||((cpu.flags&FLAG_O)!=0))) cpu.ip=address; else cpu.ip++; break; case 7: /*jle jg*/ if((Instruction.Opcode&1)&&(((cpu.flags&FLAG_Z)==0)&&((cpu.flags&FLAG_S)==(cpu.flags&FLAG_O)))) cpu.ip=address; else if((Instruction.Opcode&1)&&(((cpu.flags&FLAG_Z)!=0)||((cpu.flags&FLAG_S)!=(cpu.flags&FLAG_O)))) cpu.ip=address; else cpu.ip++; break; } break; /* test */ case 0x84: case 0x85: Instruction.Opcode = *currentCode; Instruction.dFlag = (*currentCode >>1) & 1; Instruction.wFlag = (*currentCode) & 1; //sprintf(mnemonic, "%s", "test"); currentCode++; cpu.ip++; currentCode = ParseRegModRM(currentCode, &Instruction, &operand1, &operand2); break; /* xchg */ case 0x86: case 0x87: Instruction.Opcode = *currentCode; Instruction.dFlag = (*currentCode >>1) & 1; Instruction.wFlag = (*currentCode) & 1; //sprintf(mnemonic, "%s", "xchg"); currentCode++; cpu.ip++; currentCode = ParseRegModRM(currentCode, &Instruction, &operand1, &operand2); //struct Operand opTmp; opTmp.RM=operand2.RM; handle_move(opTmp,operand1); handle_move(operand2,opTmp); break; case 0x90: Instruction.Opcode = *currentCode; //sprintf(mnemonic, "%s", Instruction.RepeatPrefix == 1 ? "pause" : "nop"); cpu.ip++; currentCode++; break; case 0x91: case 0x92: case 0x93: case 0x94: case 0x95: case 0x96: case 0x97: Instruction.Opcode = *currentCode; operand1.RM=REG16; operand1.value = (int)greg16_addr((*currentCode)&7); operand2.RM=REG16; operand2.value= (int)greg16_addr(0); opTmp.RM=operand2.RM; handle_move(opTmp,operand1); handle_move(operand2,opTmp); currentCode++; cpu.ip++; break; /* mov */ case 0x88: case 0x89: case 0x8A: case 0x8B: Instruction.Opcode = *currentCode; Instruction.dFlag = (*currentCode >>1) & 1; Instruction.wFlag = (*currentCode) & 1; currentCode++; cpu.ip++; currentCode = ParseRegModRM(currentCode, &Instruction, &operand1, &operand2); handle_move(operand1,operand2); break; case 0x8C: case 0x8E: Instruction.Opcode = *currentCode; Instruction.dFlag = (*currentCode >> 1) & 1; /* special cases code segment registers are 16-bits long */ Instruction.OperandPrefix = -1; Instruction.wFlag = 1; currentCode++; cpu.ip++; opTmp.RM=REG16; opTmp.value=(int)sreg_addr((*currentCode>>3)&7); Instruction.dFlag?(operand1=opTmp):(operand2=opTmp); currentCode = ParseModRM(currentCode, &Instruction, Instruction.dFlag ? &operand2 : &operand1); handle_move(operand1,operand2); break; case 0xA0: case 0xA1: case 0xA2: case 0xA3: Instruction.Opcode = *currentCode; Instruction.wFlag = *currentCode & 1; Instruction.dFlag = (*currentCode >> 1) & 1; currentCode++; cpu.ip++; if(Instruction.dFlag) { operand1.RM=Instruction.wFlag?MEM16:MEM8; operand1.value= *((word*)currentCode); operand2.RM=Instruction.wFlag?REG16:REG8; operand2.value=(Instruction.wFlag?(int)greg16_addr(0):(int)greg8_addr(0)); } else { operand1.RM=Instruction.wFlag?REG16:REG8; operand1.value=(Instruction.wFlag?(int)greg16_addr(0):(int)greg8_addr(0)); operand2.RM=Instruction.wFlag?MEM16:MEM8; operand2.value= *((word*)currentCode); } handle_move(operand1,operand2); currentCode += 2; cpu.ip+=2; break; case 0xB0: case 0xB1: case 0xB2: case 0xB3: case 0xB4: case 0xB5: case 0xB6: case 0xB7: case 0xB8: case 0xB9: case 0xBA: case 0xBB: case 0xBC: case 0xBD: case 0xBE: case 0xBF: Instruction.Opcode = *currentCode; Instruction.wFlag = (*currentCode >>3) & 1; Instruction.sFlag = !(Instruction.wFlag); int index = *currentCode & 7; currentCode++; cpu.ip++; currentCode = ParseImmediate(currentCode, &Instruction, &immediate); if(Instruction.wFlag==0) *greg8_addr(index) = immediate; else *greg16_addr(index) = immediate; break; /* lea */ case 0x8D: Instruction.Opcode = *currentCode; Instruction.wFlag = (*currentCode) & 1; /*special cases */ Instruction.dFlag = 1; currentCode++; cpu.ip++; currentCode = ParseRegModRM(currentCode, &Instruction, &operand1, &operand2); handle_move(operand1,operand2); break; /* cbw, cwd, cwde, cdq*/ case 0x98: Instruction.Opcode = *currentCode; cpu.greg.ax|=(0xFFFF*(cpu.greg.ax&0x80)); currentCode++; cpu.ip++; break; case 0x99: Instruction.Opcode = *currentCode; cpu.greg.dx|=(0xFFFF*(cpu.greg.ax&0x8000)); currentCode++; cpu.ip++; break; /* call far ptr16 : 16 */ case 0x9A: Instruction.Opcode = *currentCode; Instruction.sFlag = 0; currentCode++; cpu.ip++; word immediate1; currentCode = ParseImmediate(currentCode, &Instruction, &immediate1); Instruction.OperandPrefix = 0; currentCode = ParseImmediate(currentCode, &Instruction, &immediate); /*push ip,cs*/ handle_push16(cpu.ip); handle_push16(cpu.sreg.cs); cpu.ip=immediate1; cpu.sreg.cs=immediate; break; /* wait */ case 0x9B: Instruction.Opcode = *currentCode; currentCode++; cpu.ip++; break; /* lahf and sahf */ case 0x9E: Instruction.Opcode = *currentCode; cpu.flags&=((cpu.greg.ax>>8)|0xFF00); currentCode++; cpu.ip++; break; case 0x9F: Instruction.Opcode = *currentCode; cpu.greg.ax&=(((cpu.flags&0xFF)<<8)|0xFF); currentCode++; cpu.ip++; break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -