⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 decode.c

📁 简单的虚拟机
💻 C
📖 第 1 页 / 共 4 页
字号:
				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 + -