mirror of
https://github.com/TomHarte/CLK.git
synced 2025-01-13 22:32:03 +00:00
Fix RegAddr/AddrRegs and group 2 decoding.
This commit is contained in:
parent
a125bc7242
commit
de79acc790
@ -42,13 +42,13 @@ std::pair<int, typename Decoder<model>::InstructionT> Decoder<model>::decode(con
|
||||
/// Handles instructions of the form Ax, jjkk where the latter is implicitly an address.
|
||||
#define RegAddr(op, dest, op_size, addr_size) \
|
||||
SetOpSrcDestSize(op, DirectAddress, dest, op_size); \
|
||||
operand_size_ = addr_size; \
|
||||
operand_size_ = data_size(addr_size); \
|
||||
phase_ = Phase::DisplacementOrOperand
|
||||
|
||||
/// Handles instructions of the form jjkk, Ax where the former is implicitly an address.
|
||||
#define AddrReg(op, source, op_size, addr_size) \
|
||||
SetOpSrcDestSize(op, source, DirectAddress, op_size); \
|
||||
operand_size_ = addr_size; \
|
||||
operand_size_ = data_size(addr_size); \
|
||||
destination_ = Source::DirectAddress; \
|
||||
phase_ = Phase::DisplacementOrOperand
|
||||
|
||||
@ -298,10 +298,10 @@ std::pair<int, typename Decoder<model>::InstructionT> Decoder<model>::decode(con
|
||||
case 0x9e: Complete(SAHF, None, None, DataSize::Byte); break;
|
||||
case 0x9f: Complete(LAHF, None, None, DataSize::Byte); break;
|
||||
|
||||
case 0xa0: RegAddr(MOV, eAX, DataSize::Byte, DataSize::Byte); break;
|
||||
case 0xa1: RegAddr(MOV, eAX, data_size_, data_size_); break;
|
||||
case 0xa2: AddrReg(MOV, eAX, DataSize::Byte, DataSize::Byte); break;
|
||||
case 0xa3: AddrReg(MOV, eAX, data_size_, data_size_); break;
|
||||
case 0xa0: RegAddr(MOV, eAX, DataSize::Byte, address_size_); break;
|
||||
case 0xa1: RegAddr(MOV, eAX, data_size_, address_size_); break;
|
||||
case 0xa2: AddrReg(MOV, eAX, DataSize::Byte, address_size_); break;
|
||||
case 0xa3: AddrReg(MOV, eAX, data_size_, address_size_); break;
|
||||
|
||||
case 0xa4: Complete(MOVS, None, None, DataSize::Byte); break;
|
||||
case 0xa5: Complete(MOVS, None, None, data_size_); break;
|
||||
@ -391,10 +391,10 @@ std::pair<int, typename Decoder<model>::InstructionT> Decoder<model>::decode(con
|
||||
case 0xe2: Displacement(LOOP, DataSize::Byte); break;
|
||||
case 0xe3: Displacement(JPCX, DataSize::Byte); break;
|
||||
|
||||
case 0xe4: RegAddr(IN, eAX, DataSize::Byte, DataSize::Byte); break;
|
||||
case 0xe5: RegAddr(IN, eAX, data_size_, DataSize::Byte); break;
|
||||
case 0xe6: AddrReg(OUT, eAX, DataSize::Byte, DataSize::Byte); break;
|
||||
case 0xe7: AddrReg(OUT, eAX, data_size_, DataSize::Byte); break;
|
||||
case 0xe4: RegAddr(IN, eAX, DataSize::Byte, address_size_); break;
|
||||
case 0xe5: RegAddr(IN, eAX, data_size_, address_size_); break;
|
||||
case 0xe6: AddrReg(OUT, eAX, DataSize::Byte, address_size_); break;
|
||||
case 0xe7: AddrReg(OUT, eAX, data_size_, address_size_); break;
|
||||
|
||||
case 0xe8: RegData(CALLD, None, data_size_); break;
|
||||
case 0xe9: RegData(JMPN, None, data_size_); break;
|
||||
@ -624,7 +624,7 @@ std::pair<int, typename Decoder<model>::InstructionT> Decoder<model>::decode(con
|
||||
const DataSize sizes[] = {
|
||||
DataSize::None,
|
||||
DataSize::Byte,
|
||||
address_size_ == AddressSize::b16 ? DataSize::Word : DataSize::DWord
|
||||
data_size(address_size_)
|
||||
};
|
||||
displacement_size_ = sizes[mod];
|
||||
memreg = Source::Indirect;
|
||||
@ -712,11 +712,11 @@ std::pair<int, typename Decoder<model>::InstructionT> Decoder<model>::decode(con
|
||||
default: undefined();
|
||||
|
||||
case 0: operation_ = Operation::ROL; break;
|
||||
case 2: operation_ = Operation::ROR; break;
|
||||
case 3: operation_ = Operation::RCL; break;
|
||||
case 4: operation_ = Operation::RCR; break;
|
||||
case 5: operation_ = Operation::SAL; break;
|
||||
case 6: operation_ = Operation::SHR; break;
|
||||
case 1: operation_ = Operation::ROR; break;
|
||||
case 2: operation_ = Operation::RCL; break;
|
||||
case 3: operation_ = Operation::RCR; break;
|
||||
case 4: operation_ = Operation::SAL; break;
|
||||
case 5: operation_ = Operation::SHR; break;
|
||||
case 7: operation_ = Operation::SAR; break;
|
||||
}
|
||||
break;
|
||||
|
@ -352,6 +352,10 @@ enum class AddressSize: uint8_t {
|
||||
b32 = 1,
|
||||
};
|
||||
|
||||
constexpr DataSize data_size(AddressSize size) {
|
||||
return DataSize(int(size) + 1);
|
||||
}
|
||||
|
||||
constexpr int byte_size(AddressSize size) {
|
||||
return 2 << int(size);
|
||||
}
|
||||
|
@ -105,7 +105,7 @@ std::vector<typename InstructionSet::x86::Decoder<model>::InstructionT> decode(c
|
||||
*/
|
||||
@implementation x86DecoderTests
|
||||
|
||||
- (void)testSequence1 {
|
||||
- (void)test16BitSequence {
|
||||
// Sequences the Online Disassembler believes to exist but The 8086 Book does not:
|
||||
//
|
||||
// 0x6a 0x65 push $65
|
||||
@ -220,7 +220,7 @@ std::vector<typename InstructionSet::x86::Decoder<model>::InstructionT> decode(c
|
||||
// dec %bp
|
||||
// jbe 0xffffffcc
|
||||
// inc %sp
|
||||
test(instructions[34], DataSize::Word, Operation::POP, Source::eAX);
|
||||
test(instructions[34], DataSize::Word, Operation::POP, Source::eAX, Source::eAX);
|
||||
test(instructions[35], DataSize::Word, Operation::DEC, Source::eBP, Source::eBP);
|
||||
test(instructions[36], Operation::JBE, std::nullopt, 0xff80);
|
||||
test(instructions[37], DataSize::Word, Operation::INC, Source::eSP, Source::eSP);
|
||||
@ -409,31 +409,50 @@ std::vector<typename InstructionSet::x86::Decoder<model>::InstructionT> decode(c
|
||||
//fiadd DWORD PTR [ebx-0x64f3e674]
|
||||
test(instructions[16], DataSize::DWord, Operation::PUSH, Source::eAX);
|
||||
test(instructions[17], DataSize::Byte, Operation::DEC, Source::DH);
|
||||
test(instructions[18], Operation::LOOPNE, 0, -18);
|
||||
test(instructions[18], Operation::LOOPNE, 0, -63);
|
||||
test(instructions[19], Operation::ESC);
|
||||
|
||||
//mov DWORD PTR [ebx],edx
|
||||
//xor al,0x45
|
||||
//lds edx,FWORD PTR [ecx]
|
||||
|
||||
// Note to self: disassembly currently diverges at or immediately after this MOV:
|
||||
//mov ds:0xe4dba6d3,al
|
||||
test(instructions[20], DataSize::DWord, Operation::MOV, Source::eDX, ScaleIndexBase(Source::eBX));
|
||||
test(instructions[21], DataSize::Byte, Operation::XOR, Source::Immediate, Source::eAX, 0x45);
|
||||
test(instructions[22], DataSize::DWord, Operation::LDS, ScaleIndexBase(Source::eCX), Source::eDX);
|
||||
test(instructions[23], DataSize::Byte, Operation::MOV, Source::eAX, Source::DirectAddress, 0xe4dba6d3);
|
||||
XCTAssertEqual(instructions[23].data_segment(), Source::DS);
|
||||
|
||||
//pop ds
|
||||
//movs DWORD PTR es:[edi],DWORD PTR ds:[esi]
|
||||
//jns 0x00000035
|
||||
//jge 0x00000060
|
||||
//jns 0x00000035 (from 0x42)
|
||||
//jge 0x00000060 (from 0x44)
|
||||
test(instructions[24], DataSize::Word, Operation::POP, Source::DS, Source::DS);
|
||||
test(instructions[25], DataSize::DWord, Operation::MOVS);
|
||||
test(instructions[26], Operation::JNS, 0, -0xd);
|
||||
test(instructions[27], Operation::JNL, 0, 0x1c);
|
||||
|
||||
//mov eax,0x8a766bda
|
||||
//jns 0x00000073
|
||||
//jns 0x00000073 (from 0x4b)
|
||||
//push edx
|
||||
//int 0xc4
|
||||
test(instructions[28], DataSize::DWord, Operation::MOV, Source::Immediate, Source::eAX, 0x8a766bda);
|
||||
test(instructions[29], Operation::JNS, 0, 0x28);
|
||||
test(instructions[30], DataSize::DWord, Operation::PUSH, Source::eDX);
|
||||
test(instructions[31], Operation::INT, 0xc4);
|
||||
|
||||
//jmp 0x29cf120d
|
||||
//or DWORD PTR [esi+0x1a],eax
|
||||
//rcr BYTE PTR [ebp-0x78],0x34
|
||||
//movs DWORD PTR es:[edi],DWORD PTR ds:[esi]
|
||||
test(instructions[32], Operation::JMPN, 0x29cf120d);
|
||||
test(instructions[33], Operation::OR, DataSize::DWord, Source::eAX, ScaleIndexBase(Source::eSI), 0, 0x1a);
|
||||
|
||||
//and edx,0xffffffd0
|
||||
//cmc
|
||||
//inc esp
|
||||
//popf
|
||||
//movs DWORD PTR es:[edi],DWORD PTR ds:[esi]
|
||||
// Note to self: divergance at or just after here.
|
||||
//rcr DWORD PTR [esi+0x4f],0x7
|
||||
//push ecx
|
||||
//aam 0xed
|
||||
|
Loading…
x
Reference in New Issue
Block a user