diff --git a/InstructionSets/x86/Decoder.cpp b/InstructionSets/x86/Decoder.cpp index 1736c0d8b..bf46d5180 100644 --- a/InstructionSets/x86/Decoder.cpp +++ b/InstructionSets/x86/Decoder.cpp @@ -77,8 +77,8 @@ std::pair::InstructionT> Decoder::decode(con #define Far(op) \ operation_ = Operation::op; \ phase_ = Phase::DisplacementOrOperand; \ - operand_size_ = data_size_; \ - displacement_size_ = DataSize::Word + operand_size_ = DataSize::Word; \ + displacement_size_ = data_size(address_size_) /// Handles ENTER — a fixed three-byte operation. #define Displacement16Operand8(op) \ diff --git a/InstructionSets/x86/Instruction.hpp b/InstructionSets/x86/Instruction.hpp index d5afd1ec9..7eec36268 100644 --- a/InstructionSets/x86/Instruction.hpp +++ b/InstructionSets/x86/Instruction.hpp @@ -630,7 +630,7 @@ template class Instruction { // TODO: confirm whether far call for some reason makes these 32-bit in protected mode. uint16_t segment() const { return uint16_t(operand_); } - uint16_t offset() const { return uint16_t(displacement_); } + DisplacementT offset() const { return displacement_; } DisplacementT displacement() const { return displacement_; } ImmediateT operand() const { return operand_; } diff --git a/OSBindings/Mac/Clock SignalTests/x86DecoderTests.mm b/OSBindings/Mac/Clock SignalTests/x86DecoderTests.mm index 0438c0b20..297aaf3cf 100644 --- a/OSBindings/Mac/Clock SignalTests/x86DecoderTests.mm +++ b/OSBindings/Mac/Clock SignalTests/x86DecoderTests.mm @@ -52,7 +52,11 @@ template void test( if(displacement) XCTAssertEqual(instruction.displacement(), *displacement); } -template void test_far(const InstructionT &instruction, Operation operation, uint16_t segment, uint16_t offset) { +template void test_far( + const InstructionT &instruction, + Operation operation, + uint16_t segment, + typename InstructionT::DisplacementT offset) { XCTAssertEqual(instruction.operation, operation); XCTAssertEqual(instruction.segment(), segment); XCTAssertEqual(instruction.offset(), offset); @@ -487,17 +491,31 @@ std::vector::InstructionT> decode(c test(instructions[51], DataSize::Byte, Operation::MOV, Source::Immediate, Source::eCX, 0xb7); //cmp ecx,DWORD PTR [ebp+0x2c87445f] - //jecxz 0x00000084 + //jecxz 0x00000084 (from 0x82) //sahf - //je 0x000000f3 + //je 0x000000f3 (from 0x85) + test(instructions[52], DataSize::DWord, Operation::CMP, ScaleIndexBase(Source::eBP), Source::eCX, 0, 0x2c87445f); + test(instructions[53], Operation::JPCX, 0, 0x02); + test(instructions[54], Operation::SAHF); + test(instructions[55], Operation::JE, 0, 0x6e); + //sbb ecx,DWORD PTR [edi+0x433c54d] //lahf //lods al,BYTE PTR ds:[esi] //ror cl,0x60 + test(instructions[56], DataSize::DWord, Operation::SBB, ScaleIndexBase(Source::eDI), Source::eCX, 0, 0x433c54d); + test(instructions[57], Operation::LAHF); + test(instructions[58], Operation::LODS); + test(instructions[59], DataSize::Byte, Operation::ROR, Source::Immediate, Source::eCX, 0x60); + //call 0xe21b:0x97d0f58a //fs pusha //mov al,0xcf - //jecxz 0x000000d4 + //jecxz 0x000000d4 (from 0x9d) + test_far(instructions[60], Operation::CALLF, 0xe21b, 0x97d0f58a); + test(instructions[61], Operation::PUSHA); + test(instructions[62], DataSize::Byte, Operation::MOV, Source::Immediate, Source::eAX, 0xcf); + test(instructions[63], Operation::JPCX, 0, 0xd4 - 0x9d); } @end