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

📄 decode.c

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