private void OR_rm32_imm8() // opcode: 83 /1 ib { ModRM_Byte ModRM = GetModRM(); uint result; uint imm8 = (uint)((sbyte)GetNextInstructionByte()); if (ModRM.RegMemType == RegMemTypeEnum.Memory) { result = GetDwordInEffectiveSegment(ModRM.DefaultSegment, ModRM.EffectiveAddress); result |= imm8; SetDwordInEffectiveSegment(ModRM.DefaultSegment, ModRM.EffectiveAddress, result); } else { result = GetReg32(ModRM.RegMemValue); result |= imm8; SetReg32(ModRM.RegMemValue, result); } ClearFlag(FlagsEnum.OF_OverflowFlag | FlagsEnum.CF_CarryFlag); SetSignFlagByDword(result); SetZeroFlagByDword(result); SetParityFlagByDword(result); }
private void XOR_rm16_imm8() // opcode: 83 /6 ib { ModRM_Byte ModRM = GetModRM(); ushort result; sbyte imm8 = (sbyte)GetNextInstructionByte(); if (ModRM.RegMemType == RegMemTypeEnum.Memory) { result = GetWordInEffectiveSegment(ModRM.DefaultSegment, ModRM.EffectiveAddress); result ^= (ushort)imm8; SetWordInEffectiveSegment(ModRM.DefaultSegment, ModRM.EffectiveAddress, result); } else { result = GetReg16(ModRM.RegMemValue); result ^= (ushort)imm8; SetReg16(ModRM.RegMemValue, result); } ClearFlag(FlagsEnum.OF_OverflowFlag | FlagsEnum.CF_CarryFlag); SetSignFlagByWord(result); SetZeroFlagByWord(result); SetParityFlagByWord(result); }
private void TEST_rm8_r8() // opcode: 84 /r { ModRM_Byte ModRM = GetModRM(); byte result; byte rm8; byte r8; if (ModRM.RegMemType == RegMemTypeEnum.Memory) { rm8 = GetByteInEffectiveSegment(ModRM.DefaultSegment, ModRM.EffectiveAddress); } else { rm8 = GetReg8(ModRM.RegMemValue); } r8 = GetReg8(ModRM.RegOpValue); result = (byte)(rm8 & r8); ClearFlag(FlagsEnum.OF_OverflowFlag | FlagsEnum.CF_CarryFlag); SetSignFlagByByte(result); SetZeroFlagByByte(result); SetParityFlagByByte(result); }
private void POP_rm16() // opcode: 8F /0 { ushort value = GetWord(SegmentEnum.SS, GetStackPointer()); // From INTEL manual: "If the ESP register is used as a base register for addressing a destination operande // in memory, the POP instruction computes the effective address of the operand after it increments the ESP // register. IncrementStackPointerByWord(); // Getting the ModRM byte with this function computes the effective address ModRM_Byte ModRM = GetModRM(); if (ModRM.RegMemType == RegMemTypeEnum.Memory) { SetWordInEffectiveSegment(ModRM.DefaultSegment, ModRM.EffectiveAddress, value); } else { SetReg16(ModRM.RegMemValue, value); } }
private void TEST_rm32_r32() // opcode: 85 /r { ModRM_Byte ModRM = GetModRM(); uint result; uint rm32; uint r32; if (ModRM.RegMemType == RegMemTypeEnum.Memory) { rm32 = GetDwordInEffectiveSegment(ModRM.DefaultSegment, ModRM.EffectiveAddress); } else { rm32 = GetReg32(ModRM.RegMemValue); } r32 = GetReg32(ModRM.RegOpValue); result = (rm32 & r32); ClearFlag(FlagsEnum.OF_OverflowFlag | FlagsEnum.CF_CarryFlag); SetSignFlagByDword(result); SetZeroFlagByDword(result); SetParityFlagByDword(result); }
private void TEST_rm16_r16() // opcode: 85 /r { ModRM_Byte ModRM = GetModRM(); ushort result; ushort rm16; ushort r16; if (ModRM.RegMemType == RegMemTypeEnum.Memory) { rm16 = GetWordInEffectiveSegment(ModRM.DefaultSegment, ModRM.EffectiveAddress); } else { rm16 = GetReg16(ModRM.RegMemValue); } r16 = GetReg16(ModRM.RegOpValue); result = (ushort)(rm16 & r16); ClearFlag(FlagsEnum.OF_OverflowFlag | FlagsEnum.CF_CarryFlag); SetSignFlagByWord(result); SetZeroFlagByWord(result); SetParityFlagByWord(result); }
private void AND_rm16_imm16() // opcode: 81 /4 iw { ModRM_Byte ModRM = GetModRM(); ushort result; ushort imm16 = GetNextInstructionWord(); if (ModRM.RegMemType == RegMemTypeEnum.Memory) { result = GetWordInEffectiveSegment(ModRM.DefaultSegment, ModRM.EffectiveAddress); result &= imm16; SetWordInEffectiveSegment(ModRM.DefaultSegment, ModRM.EffectiveAddress, result); } else { result = GetReg16(ModRM.RegMemValue); result &= imm16; SetReg16(ModRM.RegMemValue, result); } ClearFlag(FlagsEnum.OF_OverflowFlag | FlagsEnum.CF_CarryFlag); SetSignFlagByWord(result); SetZeroFlagByWord(result); SetParityFlagByWord(result); }
private void MOV_rm16_Sreg() // opcode: 0x8c /r { ModRM_Byte ModRM = GetModRM(); if (ModRM.RegMemType == RegMemTypeEnum.Memory) { SetWordInEffectiveSegment(ModRM.DefaultSegment, ModRM.EffectiveAddress, GetRegSeg(ModRM.RegOpValue)); } else { SetReg16(ModRM.RegMemValue, GetRegSeg(ModRM.RegOpValue)); } }
private void MOV_rm8_r8() // opcode: 0x88 /r { ModRM_Byte ModRM = GetModRM(); if (ModRM.RegMemType == RegMemTypeEnum.Memory) { SetByteInEffectiveSegment(ModRM.DefaultSegment, ModRM.EffectiveAddress, GetReg8(ModRM.RegOpValue)); } else { SetReg8(ModRM.RegMemValue, GetReg8(ModRM.RegOpValue)); } }
private void MOV_r32_rm32() // opcode: 0x8b /r { ModRM_Byte ModRM = GetModRM(); if (ModRM.RegMemType == RegMemTypeEnum.Memory) { SetReg32(ModRM.RegOpValue, GetDwordInEffectiveSegment(ModRM.DefaultSegment, ModRM.EffectiveAddress)); } else { SetReg32(ModRM.RegOpValue, GetReg32(ModRM.RegMemValue)); } }
private void MOV_rm8_imm8() // opcode: 0xc6 /0 { ModRM_Byte ModRM = GetModRM(); byte imm8 = GetNextInstructionByte(); if (ModRM.RegMemType == RegMemTypeEnum.Memory) { SetByteInEffectiveSegment(ModRM.DefaultSegment, ModRM.EffectiveAddress, imm8); } else { SetReg8(ModRM.RegMemValue, imm8); } }
private void MOV_rm16_imm16() // opcode: 0xc7 /0 { ModRM_Byte ModRM = GetModRM(); ushort imm16 = GetNextInstructionWord(); if (ModRM.RegMemType == RegMemTypeEnum.Memory) { SetWordInEffectiveSegment(ModRM.DefaultSegment, ModRM.EffectiveAddress, imm16); } else { SetReg16(ModRM.RegMemValue, imm16); } }
private void MOV_rm32_imm32() // opcode: 0xc7 /0 { ModRM_Byte ModRM = GetModRM(); uint imm32 = GetNextInstructionDword(); if (ModRM.RegMemType == RegMemTypeEnum.Memory) { SetDwordInEffectiveSegment(ModRM.DefaultSegment, ModRM.EffectiveAddress, imm32); } else { SetReg32(ModRM.RegMemValue, imm32); } }
private void CMP_rm16_imm16() // opcode: 81 /7 ib { ModRM_Byte ModRM = GetModRM(); ushort rm16; ushort imm16 = GetNextInstructionWord(); if (ModRM.RegMemType == RegMemTypeEnum.Memory) { rm16 = GetWordInEffectiveSegment(ModRM.DefaultSegment, ModRM.EffectiveAddress); } else { rm16 = GetReg16(ModRM.RegMemValue); } SubTwoWordsAndSetFlags(rm16, imm16); }
private void CMP_rm32_imm8() // opcode: 83 /7 ib { ModRM_Byte ModRM = GetModRM(); uint rm32; sbyte imm8 = (sbyte)GetNextInstructionByte(); if (ModRM.RegMemType == RegMemTypeEnum.Memory) { rm32 = GetDwordInEffectiveSegment(ModRM.DefaultSegment, ModRM.EffectiveAddress); } else { rm32 = GetReg32(ModRM.RegMemValue); } SubTwoDwordsAndSetFlags(rm32, (uint)imm8); }
private void JMP_rm16() // opcode: FF /4 { ModRM_Byte ModRM = GetModRM(); ushort new_ip; if (ModRM.RegMemType == RegMemTypeEnum.Memory) { new_ip = GetWordInEffectiveSegment(ModRM.DefaultSegment, ModRM.EffectiveAddress); } else { new_ip = GetReg16(ModRM.RegMemValue); } SetInstructionPointer(new_ip); jumpInstruction = true; }
private void CMP_r8_rm8() // opcode: 3A /r { ModRM_Byte ModRM = GetModRM(); byte rm8; byte r8 = GetReg8(ModRM.RegOpValue); if (ModRM.RegMemType == RegMemTypeEnum.Memory) { rm8 = GetByteInEffectiveSegment(ModRM.DefaultSegment, ModRM.EffectiveAddress); } else { rm8 = GetReg8(ModRM.RegMemValue); } SubTwoBytesAndSetFlags(r8, rm8); }
private void CMP_r32_rm32() // opcode: 3B /r { ModRM_Byte ModRM = GetModRM(); uint rm32; uint r32 = GetReg32(ModRM.RegOpValue); if (ModRM.RegMemType == RegMemTypeEnum.Memory) { rm32 = GetDwordInEffectiveSegment(ModRM.DefaultSegment, ModRM.EffectiveAddress); } else { rm32 = GetReg32(ModRM.RegMemValue); } SubTwoDwordsAndSetFlags(r32, rm32); }
private void JMP_m16_16() // opcode: FF /5 { ModRM_Byte ModRM = GetModRM(); if (ModRM.RegMemType == RegMemTypeEnum.Memory) { ushort new_ip = GetWordInEffectiveSegment(ModRM.DefaultSegment, ModRM.EffectiveAddress); ushort new_cs = GetWordInEffectiveSegment(ModRM.DefaultSegment, ModRM.EffectiveAddress + 2); cs = new_cs; SetInstructionPointer(new_ip); jumpInstruction = true; } else { RaiseException(ExceptionEnum.InvalidOpcode, ExceptionDetailEnum.InvalidModValueInModRM); } }
private void CMP_r16_rm16() // opcode: 3B /r { ModRM_Byte ModRM = GetModRM(); ushort rm16; ushort r16 = GetReg16(ModRM.RegOpValue); if (ModRM.RegMemType == RegMemTypeEnum.Memory) { rm16 = GetWordInEffectiveSegment(ModRM.DefaultSegment, ModRM.EffectiveAddress); } else { rm16 = GetReg16(ModRM.RegMemValue); } SubTwoWordsAndSetFlags(r16, rm16); }
private void CMP_rm8_imm8() // opcode: 80 /7 ib { ModRM_Byte ModRM = GetModRM(); byte rm8; byte imm8 = GetNextInstructionByte(); if (ModRM.RegMemType == RegMemTypeEnum.Memory) { rm8 = GetByteInEffectiveSegment(ModRM.DefaultSegment, ModRM.EffectiveAddress); } else { rm8 = GetReg8(ModRM.RegMemValue); } SubTwoBytesAndSetFlags(rm8, imm8); }
private void PUSH_rm16() // opcode: FF /6 { ModRM_Byte ModRM = GetModRM(); ushort value; if (ModRM.RegMemType == RegMemTypeEnum.Memory) { value = GetWordInEffectiveSegment(ModRM.DefaultSegment, ModRM.EffectiveAddress); } else { value = GetReg16(ModRM.RegMemValue); } DecrementStackPointerByWord(); SetWord(SegmentEnum.SS, GetStackPointer(), value); }
private void ADC_r16_rm16() // opcode: 13 /r { ushort result; ModRM_Byte ModRM = GetModRM(); if (ModRM.RegMemType == RegMemTypeEnum.Memory) { result = GetWordInEffectiveSegment(ModRM.DefaultSegment, ModRM.EffectiveAddress); result = AddTwoWordsWithCarryAndSetFlags(result, GetReg16(ModRM.RegOpValue)); SetReg16(ModRM.RegOpValue, result); } else { result = GetReg16(ModRM.RegMemValue); result = AddTwoWordsWithCarryAndSetFlags(result, GetReg16(ModRM.RegOpValue)); SetReg16(ModRM.RegOpValue, result); } }
private void NEG_rm8() // opcode: F6 /3 { ModRM_Byte ModRM = GetModRM(); byte result; if (ModRM.RegMemType == RegMemTypeEnum.Memory) { result = GetByteInEffectiveSegment(ModRM.DefaultSegment, ModRM.EffectiveAddress); result = NegByteAndSetFlags(result); SetByteInEffectiveSegment(ModRM.DefaultSegment, ModRM.EffectiveAddress, result); } else { result = GetReg8(ModRM.RegMemValue); result = NegByteAndSetFlags(result); SetReg8(ModRM.RegMemValue, result); } }
private void ADC_rm8_r8() // opcode: 10 /r { byte result; ModRM_Byte ModRM = GetModRM(); if (ModRM.RegMemType == RegMemTypeEnum.Memory) { result = GetByteInEffectiveSegment(ModRM.DefaultSegment, ModRM.EffectiveAddress); result = AddTwoBytesWithCarryAndSetFlags(result, GetReg8(ModRM.RegOpValue)); SetByteInEffectiveSegment(ModRM.DefaultSegment, ModRM.EffectiveAddress, result); } else { result = GetReg8(ModRM.RegMemValue); result = AddTwoBytesWithCarryAndSetFlags(result, GetReg8(ModRM.RegOpValue)); SetReg8(ModRM.RegMemValue, result); } }
private void ADC_rm32_r32() // opcode: 11 /r { uint result; ModRM_Byte ModRM = GetModRM(); if (ModRM.RegMemType == RegMemTypeEnum.Memory) { result = GetDwordInEffectiveSegment(ModRM.DefaultSegment, ModRM.EffectiveAddress); result = AddTwoDwordsWithCarryAndSetFlags(result, GetReg32(ModRM.RegOpValue)); SetDwordInEffectiveSegment(ModRM.DefaultSegment, ModRM.EffectiveAddress, result); } else { result = GetReg32(ModRM.RegMemValue); result = AddTwoDwordsWithCarryAndSetFlags(result, GetReg32(ModRM.RegOpValue)); SetReg32(ModRM.RegMemValue, result); } }
private void NEG_rm16() // opcode: F7 /3 { ModRM_Byte ModRM = GetModRM(); ushort result; if (ModRM.RegMemType == RegMemTypeEnum.Memory) { result = GetWordInEffectiveSegment(ModRM.DefaultSegment, ModRM.EffectiveAddress); result = NegWordAndSetFlags(result); SetWordInEffectiveSegment(ModRM.DefaultSegment, ModRM.EffectiveAddress, result); } else { result = GetReg16(ModRM.RegMemValue); result = NegWordAndSetFlags(result); SetReg16(ModRM.RegMemValue, result); } }
private void SBB_rm16_imm16() // opcode: 81 /3 iw { ModRM_Byte ModRM = GetModRM(); ushort result; ushort imm16 = GetNextInstructionWord(); if (ModRM.RegMemType == RegMemTypeEnum.Memory) { result = GetWordInEffectiveSegment(ModRM.DefaultSegment, ModRM.EffectiveAddress); result = SubTwoWordsWithBorrowAndSetFlags(result, imm16); SetWordInEffectiveSegment(ModRM.DefaultSegment, ModRM.EffectiveAddress, result); } else { result = GetReg16(ModRM.RegMemValue); result = SubTwoWordsWithBorrowAndSetFlags(result, imm16); SetReg16(ModRM.RegMemValue, result); } }
private void DEC_rm32() // opcode: FF /1 { ModRM_Byte ModRM = GetModRM(); uint result; if (ModRM.RegMemType == RegMemTypeEnum.Memory) { result = GetDwordInEffectiveSegment(ModRM.DefaultSegment, ModRM.EffectiveAddress); result = DecDwordAndSetFlags(result); SetDwordInEffectiveSegment(ModRM.DefaultSegment, ModRM.EffectiveAddress, result); } else { result = GetReg32(ModRM.RegMemValue); result = DecDwordAndSetFlags(result); SetReg32(ModRM.RegMemValue, result); } }
private void SBB_rm8_imm8() // opcode: 80 /3 ib { ModRM_Byte ModRM = GetModRM(); byte result; byte imm8 = GetNextInstructionByte(); if (ModRM.RegMemType == RegMemTypeEnum.Memory) { result = GetByteInEffectiveSegment(ModRM.DefaultSegment, ModRM.EffectiveAddress); result = SubTwoBytesWithBorrowAndSetFlags(result, imm8); SetByteInEffectiveSegment(ModRM.DefaultSegment, ModRM.EffectiveAddress, result); } else { result = GetReg8(ModRM.RegMemValue); result = SubTwoBytesWithBorrowAndSetFlags(result, imm8); SetReg8(ModRM.RegMemValue, result); } }