📄 decode.c
字号:
/* flag set: clc stc cli sti cld std */ case 0xF8: case 0xF9: case 0xFA: case 0xFB: case 0xFC: case 0xFD: Instruction.Opcode = *currentCode; switch (*currentCode&6) { case 0: cpu.flags&=0xFFFE; cpu.flags|=(*currentCode&1); case 2: cpu.flags&=0xFDFF; cpu.flags|=(*currentCode&2); case 4: cpu.flags&=0xFBFF; cpu.flags|=(*currentCode&4); } currentCode++; cpu.ip++; break; case 0xFE: /* inc dec */ Instruction.Opcode = *currentCode; Instruction.wFlag = *currentCode & 1; currentCode++; cpu.ip++; currentCode = ParseModRM(currentCode, &Instruction, &operand1); if((*currentCode >> 3) & 7) { handle_incdec(dec,operand1,Instruction.wFlag); } else { handle_incdec(inc,operand1,Instruction.wFlag); } break; case 0xFF: Instruction.Opcode = *currentCode; Instruction.wFlag = *currentCode & 1; currentCode++; cpu.ip++; op = (*currentCode >> 3) & 7; switch(op) { case 0: currentCode = ParseModRM(currentCode, &Instruction, &operand1); handle_incdec(inc,operand1,Instruction.wFlag); break; case 1: currentCode = ParseModRM(currentCode, &Instruction, &operand1); handle_incdec(dec,operand1,Instruction.wFlag); break; case 2: currentCode = ParseModRM(currentCode, &Instruction, &operand1); handle_push16(cpu.ip); cpu.ip=(Instruction.LinearAddress & 0xFFFF) + get_op_val(operand1) + currentCode - Code + 2 -(cpu.sreg.cs<<4); break; /* call */ case 4: currentCode = ParseModRM(currentCode, &Instruction, &operand1); cpu.ip=(Instruction.LinearAddress & 0xFFFF) + get_op_val(operand1) + currentCode - Code + 2 -(cpu.sreg.cs<<4); break; /* jmp */ case 6: currentCode = ParseModRM(currentCode, &Instruction, &operand1); if(Instruction.wFlag) { handle_push16(get_op_val(operand1)); } else { handle_push8(get_op_val(operand1)); } break; case 3 : case 5: ////sprintf(mnemonic, FFOpcodeMnemonic[(*currentCode >> 3) & 7]); currentCode = ParseModRM(currentCode, &Instruction, &operand1); ////sprintf(operand2, "far %s%s", Instruction.OperandPrefix >= 0 ? "dword " : "word ", // strstr(operand1, "ptr")); ////sprintf(operand1, "%s", operand2); //*operand2 = '\0'; break; default: ////sprintf(mnemonic, "???"); currentCode++; cpu.ip++; } break; /* 2-bytes instructions */ case 0x0F: Instruction.Opcode = *((int *)currentCode) & 0xFFFF; currentCode++; cpu.ip++; switch(*currentCode) { /* jxxx */ case 0x80: case 0x81: case 0x82: case 0x83: case 0x84: case 0x85: case 0x86: case 0x87: case 0x88: case 0x89: case 0x8A: case 0x8B: case 0x8C: case 0x8D: case 0x8E: case 0x8F: ////sprintf(mnemonic, "%s", *currentCode & 1 ? // JnxxMnemonic[(*currentCode >> 1) & 7] : // JxxxMnemonic[(*currentCode >> 1) & 7]); currentCode++; //sprintf(operand1, "%X", Instruction.OperandPrefix >= 0 ? // (Instruction.LinearAddress & 0xFFFF) + // (*((int*)currentCode) & 0xFFFF) // + currentCode - Code + 2 : // Instruction.LinearAddress + // *((int *)currentCode) + currentCode - Code + 4); Instruction.OperandPrefix >= 0 ? (currentCode += 2) : (currentCode += 4); break; /* setxxx */ case 0x90: case 0x91: case 0x92: case 0x93: case 0x94: case 0x95: case 0x96: case 0x97: case 0x98: case 0x99: case 0x9A: case 0x9B: case 0x9C: case 0x9D: case 0x9E: case 0x9F: Instruction.wFlag = 0; ////sprintf(mnemonic, "%s", *currentCode & 1 ? // SetnxxMnemonic[(*currentCode >> 1) & 7] : // SetxxxMnemonic[(*currentCode >> 1) & 7]); currentCode++; currentCode = ParseModRM(currentCode, &Instruction, &operand1); break; /* push pop fs gs*/ case 0xA0: case 0xA1: case 0xA8: case 0xA9: ////sprintf(mnemonic, "%s", *currentCode & 1 ? "pop" : "push"); ////sprintf(operand1, "%s", (*currentCode >> 3 & 1) ? "gs" : "fs"); currentCode++; break; /* bt bts btr btc bsf bsr */ case 0xA3: case 0xAB: case 0xB3: case 0xBB: Instruction.dFlag = (*currentCode >> 1) & 1; Instruction.wFlag = *currentCode & 1; ////sprintf(mnemonic, "%s", BTMnemonic[(*currentCode >> 3) & 3]); currentCode++; currentCode = ParseRegModRM(currentCode, &Instruction, &operand2, &operand1); break; case 0xBA: Instruction.wFlag = 1; Instruction.sFlag = 1; ////sprintf(mnemonic, "%s", BTMnemonic[(*(currentCode + 1) >> 3) & 3]); currentCode++; currentCode = ParseModRM(currentCode, &Instruction, &operand1); currentCode = ParseImmediate(currentCode, &Instruction, &immediate); break; case 0xBC: case 0xBD: Instruction.wFlag = 1; Instruction.dFlag = 1; ////sprintf(mnemonic, "%s", *currentCode & 1 ? "bsr" : "bsf"); currentCode++; currentCode = ParseRegModRM(currentCode, &Instruction, &operand1, &operand2); break; /* cpuid */ case 0xA2: ////sprintf(mnemonic, "cpuid"); currentCode++; break; /* shld, shrd */ case 0xA4: case 0xAC: Instruction.wFlag = 1; Instruction.dFlag = 1; Instruction.sFlag = 1; ////sprintf(mnemonic, "%s", (*currentCode >> 3) & 1 ? "shrd" : "shld"); currentCode++; currentCode = ParseRegModRM(currentCode, &Instruction, &operand2, &operand1); currentCode = ParseImmediate(currentCode, &Instruction, &immediate); break; case 0xA5: case 0xAD: Instruction.wFlag = 1; Instruction.dFlag = 1; ////sprintf(mnemonic, "%s", (*currentCode >> 3) & 1 ? "shrd" : "shld"); currentCode++; currentCode = ParseRegModRM(currentCode, &Instruction, &operand2, &operand1); ////sprintf(operand3, "cl"); break; /* imul */ case 0xAF: Instruction.wFlag = 1; Instruction.dFlag = 1; ////sprintf(mnemonic, "%s", "imul"); currentCode++; currentCode = ParseRegModRM(currentCode, &Instruction, &operand1, &operand2); break; /* cmpxchg */ case 0xB0: case 0xB1: Instruction.wFlag = *currentCode & 1; Instruction.dFlag = 1; ////sprintf(mnemonic, "cmpxchg"); currentCode++; currentCode = ParseRegModRM(currentCode, &Instruction, &operand2, &operand1); break; /* lss lfs lgs */ case 0xB2: case 0xB4: case 0xB5: Instruction.wFlag = 1; Instruction.dFlag = 1; ////sprintf(mnemonic, "l%s", SegmentRegisters[*currentCode & 7]); currentCode++; currentCode = ParseRegModRM(currentCode, &Instruction, &operand1, &operand2); ////sprintf(operand3, "%s%s", Instruction.OperandPrefix >= 0 ? "dword " : "fword ", // strstr(operand2, "ptr")); ////sprintf(operand2, "%s", operand3); //*operand3 = '\0'; break; /* movzx movsx */ case 0xB6: case 0xB7: case 0xBE: case 0xBF: Instruction.wFlag = *currentCode & 1; ////sprintf(mnemonic, "%s", (*currentCode >> 3) & 1 ? "movsx" : "movzx"); currentCode++; ////sprintf(operand1, "%s", !(Instruction.OperandPrefix >= 0)?Register16[(*currentCode >> 3) & 7] // : Register32[(*currentCode >> 3) & 7]); currentCode = ParseModRM(currentCode, &Instruction, &operand2); break; case 0xC0: case 0xC1: Instruction.wFlag = *currentCode & 1; Instruction.dFlag = 1; ////sprintf(mnemonic, "xadd"); currentCode++; currentCode = ParseRegModRM(currentCode, &Instruction, &operand2, &operand1); break; case 0xC8: case 0xC9: case 0xCA: case 0xCB: case 0xCC: case 0xCD: case 0xCE: case 0xCF: ////sprintf(mnemonic, "bswap"); ////sprintf(operand1, "%s", !(Instruction.OperandPrefix >= 0) ? Register16[*currentCode & 7] : // Register32[*currentCode & 7]); currentCode++; break; default: ////sprintf(mnemonic, "%s", "???"); currentCode++; } break; default : currentCode++; cpu.ip++; ////sprintf(mnemonic, "%s", "???"); } return hlt;}inline word IndirectAddr(struct INSTRUCTION* Instruction,char RM){ word addr; switch (RM) { case 0: addr=(Instruction->SegmentPrefix>=0)?(*sreg_addr(Instruction->SegmentPrefix)<<4):(cpu.sreg.ds<<4)+cpu.greg.bx+cpu.greg.si; break; case 1: addr=(Instruction->SegmentPrefix>=0)?(*sreg_addr(Instruction->SegmentPrefix)<<4):(cpu.sreg.ds<<4)+cpu.greg.bx+cpu.greg.di; break; case 2: addr=(Instruction->SegmentPrefix>=0)?(*sreg_addr(Instruction->SegmentPrefix)<<4):(cpu.sreg.ss<<4)+cpu.greg.bp+cpu.greg.si; break; case 3: addr=(Instruction->SegmentPrefix>=0)?(*sreg_addr(Instruction->SegmentPrefix)<<4):(cpu.sreg.ss<<4)+cpu.greg.bp+cpu.greg.di; break; case 4: addr=(Instruction->SegmentPrefix>=0)?(*sreg_addr(Instruction->SegmentPrefix)<<4):(cpu.sreg.ds<<4)+cpu.greg.si; break; case 5: addr=(Instruction->SegmentPrefix>=0)?(*sreg_addr(Instruction->SegmentPrefix)<<4):(cpu.sreg.ds<<4)+cpu.greg.di; break; case 6: addr=(Instruction->SegmentPrefix>=0)?(*sreg_addr(Instruction->SegmentPrefix)<<4):(cpu.sreg.ss<<4)+cpu.greg.bp; break; case 7: addr=(Instruction->SegmentPrefix>=0)?(*sreg_addr(Instruction->SegmentPrefix)<<4):(cpu.sreg.ds<<4)+cpu.greg.bx; break; } return addr;}unsigned char *ParseModRM(unsigned char *Code, struct INSTRUCTION* Instruction, struct Operand* OperandRM){ unsigned char *currentCode; char Mod, RM, RegRM; currentCode = Code; Instruction->ModRM = *currentCode; /* get mod, reg/code, rm */ Mod = (*currentCode >> 6) & 3; RM = (*currentCode) & 7; RegRM = (*currentCode >> 3) & 7; //sprintf(SegmentPrefixStr, "%s%s", Instruction->SegmentPrefix >= 0 ? SegmentRegisters[(int)Instruction->SegmentPrefix] : "", // Instruction->SegmentPrefix >= 0 ? ":" : ""); //sprintf(SizeStr, "%s", Instruction->wFlag ? (!(Instruction->OperandPrefix >= 0) ? "word ptr" : "dword ptr") : "byte ptr"); //sprintf(AddressStr, "%s", !(Instruction->AddressPrefix >=0) ? Address16[(int)RM] : Register32[(int)RM]); switch(Mod) { case 0 : if(RM != 6) { OperandRM->RM = Instruction->wFlag?MEM16:MEM8; OperandRM->value = IndirectAddr(Instruction,RM); currentCode++; cpu.ip++; } else { /* displacement 16 */ currentCode++; cpu.ip++; Instruction->Displacement = *((word*)currentCode); OperandRM->RM=MEM16; OperandRM->value=(*sreg_addr(Instruction->SegmentPrefix)<<4)+Instruction->Displacement; currentCode += 2; cpu.ip+=2; } break; case 1 : /* 01 */ OperandRM->RM=Instruction->wFlag?MEM16:MEM8; OperandRM->value = IndirectAddr(Instruction,RM); /* displacement 8 */ currentCode++; cpu.ip++; Instruction->Displacement = *currentCode; OperandRM->value += Instruction->Displacement; currentCode++; cpu.ip++; break; case 2 : /* 10 */ OperandRM->RM=Instruction->wFlag?MEM16:MEM8; OperandRM->value = IndirectAddr(Instruction,RM); /* displacement 16 */ currentCode++; Instruction->Displacement = *((word *)currentCode); OperandRM->value += Instruction->Displacement; currentCode += 2; cpu.ip+=2; break; case 3 : /* 11 */ if(Instruction->wFlag) { OperandRM->RM=REG16; OperandRM->value = (int)greg16_addr(RM); } else { OperandRM->RM=REG8; OperandRM->value = (int)greg8_addr(RM); } currentCode++; cpu.ip++; break; } return currentCode;}unsigned char *ParseRegModRM(unsigned char *Code, struct INSTRUCTION* Instruction, struct Operand* Operand1, struct Operand* Operand2){ unsigned char *currentCode; char RegOpcode; struct Operand op; currentCode = Code; RegOpcode = (*currentCode >> 3) & 7; currentCode = ParseModRM(currentCode, Instruction, Instruction->dFlag ? Operand2 : Operand1); //sprintf(Instruction->dFlag ? Operand1 : Operand2, "%s", Instruction->wFlag ? (!(Instruction->OperandPrefix >= 0) ? // Register16[(int)RegOpcode] : Register32[(int)RegOpcode]) : Register8[(int)RegOpcode]); //if(Instruction->wFlag) //{ if(Instruction->wFlag) { op.RM=REG16; op.value=(int)greg16_addr(RegOpcode); } else { op.RM=REG8; op.value=(int)greg8_addr(RegOpcode); } if(Instruction->dFlag) *Operand1=op; else *Operand2=op; return currentCode;}unsigned char *ParseImmediate(unsigned char *Code, struct INSTRUCTION* Instruction, word *OperandImmediate){ unsigned char *currentCode; currentCode = Code; if(!Instruction->sFlag) { Instruction->Immediate = *((word*)currentCode); *OperandImmediate = Instruction->Immediate; currentCode += 2; cpu.ip+=2; } else { /* 8 bits immediate value */ Instruction->Immediate = *currentCode; *OperandImmediate = Instruction->Immediate; currentCode++; cpu.ip++; } return currentCode;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -