ft: Implement Group 4 Instructions
This commit is contained in:
@@ -15,6 +15,7 @@ use crate::{modrmb, modrms, modrmv};
|
|||||||
pub enum DisasmError {
|
pub enum DisasmError {
|
||||||
NoFile(Option<String>),
|
NoFile(Option<String>),
|
||||||
IoError(std::io::Error),
|
IoError(std::io::Error),
|
||||||
|
OpcodeUndefined(u8),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<std::io::Error> for DisasmError {
|
impl From<std::io::Error> for DisasmError {
|
||||||
@@ -28,6 +29,11 @@ impl fmt::Display for DisasmError {
|
|||||||
match self {
|
match self {
|
||||||
DisasmError::NoFile(msg) => write!(f, "No file error: {:?}", msg),
|
DisasmError::NoFile(msg) => write!(f, "No file error: {:?}", msg),
|
||||||
DisasmError::IoError(msg) => write!(f, "{}", 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()),
|
0x0D => Mnemonic::OR_AXIv(self.parse_word()),
|
||||||
|
|
||||||
0x0E => Mnemonic::PUSH_S(SegmentRegister::CS),
|
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),
|
0x10 => modrmb!(self, ADC_FromReg),
|
||||||
0x11 => modrmv!(self, ADC_FromReg),
|
0x11 => modrmv!(self, ADC_FromReg),
|
||||||
@@ -389,23 +396,23 @@ impl Disassembler {
|
|||||||
0x3E => Mnemonic::OVERRIDE(SegmentRegister::DS),
|
0x3E => Mnemonic::OVERRIDE(SegmentRegister::DS),
|
||||||
0x3F => Mnemonic::AAS,
|
0x3F => Mnemonic::AAS,
|
||||||
|
|
||||||
0x40 => Mnemonic::INC(Register::AX),
|
0x40 => Mnemonic::INC_Reg(Register::AX),
|
||||||
0x41 => Mnemonic::INC(Register::CX),
|
0x41 => Mnemonic::INC_Reg(Register::CX),
|
||||||
0x42 => Mnemonic::INC(Register::DX),
|
0x42 => Mnemonic::INC_Reg(Register::DX),
|
||||||
0x43 => Mnemonic::INC(Register::BX),
|
0x43 => Mnemonic::INC_Reg(Register::BX),
|
||||||
0x44 => Mnemonic::INC(Register::SP),
|
0x44 => Mnemonic::INC_Reg(Register::SP),
|
||||||
0x45 => Mnemonic::INC(Register::BP),
|
0x45 => Mnemonic::INC_Reg(Register::BP),
|
||||||
0x46 => Mnemonic::INC(Register::SI),
|
0x46 => Mnemonic::INC_Reg(Register::SI),
|
||||||
0x47 => Mnemonic::INC(Register::DI),
|
0x47 => Mnemonic::INC_Reg(Register::DI),
|
||||||
|
|
||||||
0x48 => Mnemonic::DEC(Register::AX),
|
0x48 => Mnemonic::DEC_Reg(Register::AX),
|
||||||
0x49 => Mnemonic::DEC(Register::CX),
|
0x49 => Mnemonic::DEC_Reg(Register::CX),
|
||||||
0x4A => Mnemonic::DEC(Register::DX),
|
0x4A => Mnemonic::DEC_Reg(Register::DX),
|
||||||
0x4B => Mnemonic::DEC(Register::BX),
|
0x4B => Mnemonic::DEC_Reg(Register::BX),
|
||||||
0x4C => Mnemonic::DEC(Register::SP),
|
0x4C => Mnemonic::DEC_Reg(Register::SP),
|
||||||
0x4D => Mnemonic::DEC(Register::BP),
|
0x4D => Mnemonic::DEC_Reg(Register::BP),
|
||||||
0x4E => Mnemonic::DEC(Register::SI),
|
0x4E => Mnemonic::DEC_Reg(Register::SI),
|
||||||
0x4F => Mnemonic::DEC(Register::DI),
|
0x4F => Mnemonic::DEC_Reg(Register::DI),
|
||||||
|
|
||||||
0x50 => Mnemonic::PUSH_R(Register::AX),
|
0x50 => Mnemonic::PUSH_R(Register::AX),
|
||||||
0x51 => Mnemonic::PUSH_R(Register::CX),
|
0x51 => Mnemonic::PUSH_R(Register::CX),
|
||||||
@@ -425,7 +432,7 @@ impl Disassembler {
|
|||||||
0x5E => Mnemonic::POP_R(Register::SI),
|
0x5E => Mnemonic::POP_R(Register::SI),
|
||||||
0x5F => Mnemonic::POP_R(Register::DI),
|
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()),
|
0x70 => Mnemonic::JO(self.parse_byte()),
|
||||||
0x71 => Mnemonic::JNO(self.parse_byte()),
|
0x71 => Mnemonic::JNO(self.parse_byte()),
|
||||||
@@ -548,14 +555,14 @@ impl Disassembler {
|
|||||||
0xBE => Mnemonic::MOV_SIIv(self.parse_word()),
|
0xBE => Mnemonic::MOV_SIIv(self.parse_word()),
|
||||||
0xBF => Mnemonic::MOV_DIIv(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()),
|
0xC2 => Mnemonic::RETIw(self.parse_word()),
|
||||||
0xC3 => Mnemonic::RET,
|
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()),
|
0xCD => Mnemonic::INT(self.parse_byte()),
|
||||||
|
|
||||||
@@ -598,6 +605,16 @@ impl Disassembler {
|
|||||||
self.modrm_reg_to_grp3(reg, target, Operand::Word(0))
|
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!("Encountered unknown instruction '0x{:x}'", opcode);
|
||||||
eprintln!("Offset might be misaligned and data is being interpreted.");
|
eprintln!("Offset might be misaligned and data is being interpreted.");
|
||||||
|
|||||||
@@ -138,9 +138,11 @@ pub enum Mnemonic {
|
|||||||
CMP_ALIb(Byte),
|
CMP_ALIb(Byte),
|
||||||
CMP_AXIv(Word),
|
CMP_AXIv(Word),
|
||||||
// INC
|
// INC
|
||||||
INC(Register),
|
INC_Reg(Register),
|
||||||
|
INC_Mod(ModRmTarget),
|
||||||
// DEC
|
// DEC
|
||||||
DEC(Register),
|
DEC_Reg(Register),
|
||||||
|
DEC_Mod(ModRmTarget),
|
||||||
// Jumps
|
// Jumps
|
||||||
JO(Byte),
|
JO(Byte),
|
||||||
JNO(Byte),
|
JNO(Byte),
|
||||||
|
|||||||
Reference in New Issue
Block a user