ft: Implement Group 4 Instructions

This commit is contained in:
2025-05-14 13:35:00 +09:00
parent 986c99873d
commit 4fa789e6bb
2 changed files with 42 additions and 23 deletions

View File

@@ -15,6 +15,7 @@ use crate::{modrmb, modrms, modrmv};
pub enum DisasmError {
NoFile(Option<String>),
IoError(std::io::Error),
OpcodeUndefined(u8),
}
impl From<std::io::Error> for DisasmError {
@@ -28,6 +29,11 @@ impl fmt::Display for DisasmError {
match self {
DisasmError::NoFile(msg) => write!(f, "No file error: {:?}", msg),
DisasmError::IoError(msg) => write!(f, "{}", msg),
DisasmError::OpcodeUndefined(opcode) => write!(
f,
"Instruction '{:#x} is considered undefined by the Spec",
opcode
),
}
}
}
@@ -327,7 +333,8 @@ impl Disassembler {
0x0D => Mnemonic::OR_AXIv(self.parse_word()),
0x0E => Mnemonic::PUSH_S(SegmentRegister::CS),
0x0F => panic!("Opcode 0x0F (POP CS) is considered undefined"),
0x0F => return Err(DisasmError::OpcodeUndefined(opcode)),
0x10 => modrmb!(self, ADC_FromReg),
0x11 => modrmv!(self, ADC_FromReg),
@@ -389,23 +396,23 @@ impl Disassembler {
0x3E => Mnemonic::OVERRIDE(SegmentRegister::DS),
0x3F => Mnemonic::AAS,
0x40 => Mnemonic::INC(Register::AX),
0x41 => Mnemonic::INC(Register::CX),
0x42 => Mnemonic::INC(Register::DX),
0x43 => Mnemonic::INC(Register::BX),
0x44 => Mnemonic::INC(Register::SP),
0x45 => Mnemonic::INC(Register::BP),
0x46 => Mnemonic::INC(Register::SI),
0x47 => Mnemonic::INC(Register::DI),
0x40 => Mnemonic::INC_Reg(Register::AX),
0x41 => Mnemonic::INC_Reg(Register::CX),
0x42 => Mnemonic::INC_Reg(Register::DX),
0x43 => Mnemonic::INC_Reg(Register::BX),
0x44 => Mnemonic::INC_Reg(Register::SP),
0x45 => Mnemonic::INC_Reg(Register::BP),
0x46 => Mnemonic::INC_Reg(Register::SI),
0x47 => Mnemonic::INC_Reg(Register::DI),
0x48 => Mnemonic::DEC(Register::AX),
0x49 => Mnemonic::DEC(Register::CX),
0x4A => Mnemonic::DEC(Register::DX),
0x4B => Mnemonic::DEC(Register::BX),
0x4C => Mnemonic::DEC(Register::SP),
0x4D => Mnemonic::DEC(Register::BP),
0x4E => Mnemonic::DEC(Register::SI),
0x4F => Mnemonic::DEC(Register::DI),
0x48 => Mnemonic::DEC_Reg(Register::AX),
0x49 => Mnemonic::DEC_Reg(Register::CX),
0x4A => Mnemonic::DEC_Reg(Register::DX),
0x4B => Mnemonic::DEC_Reg(Register::BX),
0x4C => Mnemonic::DEC_Reg(Register::SP),
0x4D => Mnemonic::DEC_Reg(Register::BP),
0x4E => Mnemonic::DEC_Reg(Register::SI),
0x4F => Mnemonic::DEC_Reg(Register::DI),
0x50 => Mnemonic::PUSH_R(Register::AX),
0x51 => Mnemonic::PUSH_R(Register::CX),
@@ -425,7 +432,7 @@ impl Disassembler {
0x5E => Mnemonic::POP_R(Register::SI),
0x5F => Mnemonic::POP_R(Register::DI),
0x60..=0x6F => panic!("{:#x} is considered undefined", opcode),
0x60..=0x6F => return Err(DisasmError::OpcodeUndefined(opcode)),
0x70 => Mnemonic::JO(self.parse_byte()),
0x71 => Mnemonic::JNO(self.parse_byte()),
@@ -548,14 +555,14 @@ impl Disassembler {
0xBE => Mnemonic::MOV_SIIv(self.parse_word()),
0xBF => Mnemonic::MOV_DIIv(self.parse_word()),
0xC0..=0xC1 => panic!("{:#x} is considered in undefined", opcode),
0xC0..=0xC1 => return Err(DisasmError::OpcodeUndefined(opcode)),
0xC2 => Mnemonic::RETIw(self.parse_word()),
0xC3 => Mnemonic::RET,
0xC4..=0xC5 => panic!("{:#x} not yet implemented (LDS or LES)", opcode),
0xC4..=0xC5 => todo!("LES and LDS not yet implemented"),
0xC8..=0xC9 => panic!("{:#x} is considered in undefined", opcode),
0xC8..=0xC9 => return Err(DisasmError::OpcodeUndefined(opcode)),
0xCD => Mnemonic::INT(self.parse_byte()),
@@ -598,6 +605,16 @@ impl Disassembler {
self.modrm_reg_to_grp3(reg, target, Operand::Word(0))
}
0xFE => {
let (target, reg) = self.parse_modrm_byte(Operand::Byte(0));
match reg {
0b0 => Mnemonic::INC_Mod(target),
0b1 => Mnemonic::DEC_Mod(target),
_ => panic!("Illegal Group 4 mnemonic"),
}
}
0xFF => todo!("Group 5"),
_ => {
eprintln!("Encountered unknown instruction '0x{:x}'", opcode);
eprintln!("Offset might be misaligned and data is being interpreted.");

View File

@@ -138,9 +138,11 @@ pub enum Mnemonic {
CMP_ALIb(Byte),
CMP_AXIv(Word),
// INC
INC(Register),
INC_Reg(Register),
INC_Mod(ModRmTarget),
// DEC
DEC(Register),
DEC_Reg(Register),
DEC_Mod(ModRmTarget),
// Jumps
JO(Byte),
JNO(Byte),