1
0
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:
Thomas Harte 2022-03-09 08:38:34 -05:00
parent a125bc7242
commit de79acc790
3 changed files with 47 additions and 24 deletions

View File

@ -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;

View File

@ -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);
}

View File

@ -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