ft: implement more mnemonics
This commit is contained in:
@@ -8,7 +8,7 @@ use crate::{
|
|||||||
Args,
|
Args,
|
||||||
instructions::{Instruction, Mnemonic},
|
instructions::{Instruction, Mnemonic},
|
||||||
};
|
};
|
||||||
use crate::{modrmb, modrmgprb, modrmgprv, modrms, modrmv};
|
use crate::{modrmb, modrmgpr1b, modrmgpr1v, modrms, modrmv};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
/// Generic errors, which are encountered during parsing.
|
/// Generic errors, which are encountered during parsing.
|
||||||
@@ -143,7 +143,7 @@ impl Disassembler {
|
|||||||
displacement = Some(Operand::Word(self.parse_word()));
|
displacement = Some(Operand::Word(self.parse_word()));
|
||||||
}
|
}
|
||||||
0b11 => {
|
0b11 => {
|
||||||
log::debug!("ModRM (0b{:b}) to/from Register (0b{:b})", rm, reg);
|
log::debug!("ModRM ({:#b}) to/from Register ({:#b})", rm, reg);
|
||||||
// XXX: find a nicer way instead of using Byte(0) and Word(0)
|
// XXX: find a nicer way instead of using Byte(0) and Word(0)
|
||||||
let target = match width {
|
let target = match width {
|
||||||
Operand::Byte(_) => ModRmTarget::Register(Register::by_id(Operand::Byte(rm))),
|
Operand::Byte(_) => ModRmTarget::Register(Register::by_id(Operand::Byte(rm))),
|
||||||
@@ -368,7 +368,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!("0x06 to 0x06F is considered undefined."),
|
0x60..=0x6F => panic!("{:#x} is considered undefined", 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()),
|
||||||
@@ -387,9 +387,10 @@ impl Disassembler {
|
|||||||
0x7E => Mnemonic::JLE(self.parse_byte()),
|
0x7E => Mnemonic::JLE(self.parse_byte()),
|
||||||
0x7F => Mnemonic::JG(self.parse_byte()),
|
0x7F => Mnemonic::JG(self.parse_byte()),
|
||||||
|
|
||||||
0x80 => modrmgprb!(self),
|
// Group 1
|
||||||
0x81 => modrmgprv!(self),
|
0x80 => modrmgpr1b!(self),
|
||||||
0x82 => modrmgprb!(self), // same as 0x80
|
0x81 => modrmgpr1v!(self),
|
||||||
|
0x82 => modrmgpr1b!(self), // same as 0x80
|
||||||
0x83 => panic!("Sign extented GPR1 not yet implemented"),
|
0x83 => panic!("Sign extented GPR1 not yet implemented"),
|
||||||
|
|
||||||
0x84 => modrmb!(self, TEST),
|
0x84 => modrmb!(self, TEST),
|
||||||
@@ -440,9 +441,55 @@ impl Disassembler {
|
|||||||
0x9E => Mnemonic::SAHF,
|
0x9E => Mnemonic::SAHF,
|
||||||
0x9F => Mnemonic::LAHF,
|
0x9F => Mnemonic::LAHF,
|
||||||
|
|
||||||
|
0xA0 => Mnemonic::MOV_AL0b(self.parse_byte()),
|
||||||
|
0xA1 => Mnemonic::MOV_AX0v(self.parse_word()),
|
||||||
|
0xA2 => Mnemonic::MOV_0bAL(self.parse_byte()),
|
||||||
|
0xA3 => Mnemonic::MOV_0vAX(self.parse_word()),
|
||||||
|
0xA4 => Mnemonic::MOVSB,
|
||||||
|
0xA5 => Mnemonic::MOVSW,
|
||||||
|
|
||||||
|
0xA6 => Mnemonic::CMPSB,
|
||||||
|
0xA7 => Mnemonic::CMPSW,
|
||||||
|
|
||||||
|
0xA8 => Mnemonic::TEST_ALIb(self.parse_byte()),
|
||||||
|
0xA9 => Mnemonic::TEST_AXIv(self.parse_word()),
|
||||||
|
|
||||||
|
0xAA => Mnemonic::STOSB,
|
||||||
|
0xAB => Mnemonic::STOSW,
|
||||||
|
0xAC => Mnemonic::LODSB,
|
||||||
|
0xAD => Mnemonic::LODSW,
|
||||||
|
0xAE => Mnemonic::SCASB,
|
||||||
|
0xAF => Mnemonic::SCASW,
|
||||||
|
|
||||||
|
0xB0 => Mnemonic::MOV_ALIb(self.parse_byte()),
|
||||||
|
0xB1 => Mnemonic::MOV_CLIb(self.parse_byte()),
|
||||||
|
0xB2 => Mnemonic::MOV_DLIb(self.parse_byte()),
|
||||||
|
0xB3 => Mnemonic::MOV_BLIb(self.parse_byte()),
|
||||||
|
0xB4 => Mnemonic::MOV_AHIb(self.parse_byte()),
|
||||||
|
0xB5 => Mnemonic::MOV_CHIb(self.parse_byte()),
|
||||||
|
0xB6 => Mnemonic::MOV_DHIb(self.parse_byte()),
|
||||||
|
0xB7 => Mnemonic::MOV_BHIb(self.parse_byte()),
|
||||||
|
0xB8 => Mnemonic::MOV_AXIv(self.parse_word()),
|
||||||
|
0xB9 => Mnemonic::MOV_CXIv(self.parse_word()),
|
||||||
|
0xBA => Mnemonic::MOV_DXIv(self.parse_word()),
|
||||||
|
0xBB => Mnemonic::MOV_BXIv(self.parse_word()),
|
||||||
|
0xBC => Mnemonic::MOV_SPIv(self.parse_word()),
|
||||||
|
0xBD => Mnemonic::MOV_BPIv(self.parse_word()),
|
||||||
|
0xBE => Mnemonic::MOV_SIIv(self.parse_word()),
|
||||||
|
0xBF => Mnemonic::MOV_DIIv(self.parse_word()),
|
||||||
|
|
||||||
|
0xC0..=0xC1 => panic!("{:#x} is considered in undefined", opcode),
|
||||||
|
|
||||||
|
0xC2 => Mnemonic::RETIw(self.parse_word()),
|
||||||
|
0xC3 => Mnemonic::RET,
|
||||||
|
|
||||||
|
0xC4..=0xC5 => panic!("{:#x} not yet implemented (LDS or LES)", opcode),
|
||||||
|
|
||||||
|
0xC8..=0xC9 => panic!("{:#x} is considered in undefined", opcode),
|
||||||
|
|
||||||
0xCD => Mnemonic::INT(self.parse_byte()),
|
0xCD => Mnemonic::INT(self.parse_byte()),
|
||||||
|
|
||||||
0xBB => Mnemonic::MOV_BXIv(self.parse_word()),
|
// Group 3
|
||||||
_ => {
|
_ => {
|
||||||
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.");
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ macro_rules! modrms {
|
|||||||
/// Generate the resulting Mnemonic from a GPR instruction with Byte-sized
|
/// Generate the resulting Mnemonic from a GPR instruction with Byte-sized
|
||||||
/// Immediate, encoded in a ModRM byte.
|
/// Immediate, encoded in a ModRM byte.
|
||||||
/// GPR always has an imm value as second operand.
|
/// GPR always has an imm value as second operand.
|
||||||
macro_rules! modrmgprb {
|
macro_rules! modrmgpr1b {
|
||||||
($self:ident) => {{
|
($self:ident) => {{
|
||||||
let (target, reg) = $self.parse_modrm_byte(Operand::Byte(0));
|
let (target, reg) = $self.parse_modrm_byte(Operand::Byte(0));
|
||||||
let imm = $self.parse_byte();
|
let imm = $self.parse_byte();
|
||||||
@@ -41,7 +41,7 @@ macro_rules! modrmgprb {
|
|||||||
/// Generate the resulting Mnemonic from a GPR instruction with Word-sized
|
/// Generate the resulting Mnemonic from a GPR instruction with Word-sized
|
||||||
/// Immediate, encoded in a ModRM byte.
|
/// Immediate, encoded in a ModRM byte.
|
||||||
/// GPR always has an imm value as second operand.
|
/// GPR always has an imm value as second operand.
|
||||||
macro_rules! modrmgprv {
|
macro_rules! modrmgpr1v {
|
||||||
($self:ident) => {{
|
($self:ident) => {{
|
||||||
let (target, reg) = $self.parse_modrm_byte(Operand::Word(0));
|
let (target, reg) = $self.parse_modrm_byte(Operand::Word(0));
|
||||||
let imm = $self.parse_word();
|
let imm = $self.parse_word();
|
||||||
|
|||||||
@@ -160,6 +160,8 @@ pub enum Mnemonic {
|
|||||||
JG(Byte),
|
JG(Byte),
|
||||||
// TEST
|
// TEST
|
||||||
TEST(ModRmTarget, Register),
|
TEST(ModRmTarget, Register),
|
||||||
|
TEST_ALIb(Byte),
|
||||||
|
TEST_AXIv(Word),
|
||||||
//XHCG
|
//XHCG
|
||||||
XHCG(ModRmTarget, Register),
|
XHCG(ModRmTarget, Register),
|
||||||
XCHG_AX(Register), // from AX
|
XCHG_AX(Register), // from AX
|
||||||
@@ -168,7 +170,27 @@ pub enum Mnemonic {
|
|||||||
MOV_ToReg(ModRmTarget, Register),
|
MOV_ToReg(ModRmTarget, Register),
|
||||||
MOV_FromSReg(ModRmTarget, SegmentRegister),
|
MOV_FromSReg(ModRmTarget, SegmentRegister),
|
||||||
MOV_ToSReg(ModRmTarget, SegmentRegister),
|
MOV_ToSReg(ModRmTarget, SegmentRegister),
|
||||||
|
MOV_AL0b(Byte),
|
||||||
|
MOV_AX0v(Word),
|
||||||
|
MOV_0bAL(Byte),
|
||||||
|
MOV_0vAX(Word),
|
||||||
|
|
||||||
|
MOV_ALIb(Byte),
|
||||||
|
MOV_CLIb(Byte),
|
||||||
|
MOV_DLIb(Byte),
|
||||||
|
MOV_BLIb(Byte),
|
||||||
|
MOV_AHIb(Byte),
|
||||||
|
MOV_CHIb(Byte),
|
||||||
|
MOV_DHIb(Byte),
|
||||||
|
MOV_BHIb(Byte),
|
||||||
|
MOV_AXIv(Word),
|
||||||
|
MOV_CXIv(Word),
|
||||||
|
MOV_DXIv(Word),
|
||||||
MOV_BXIv(Word),
|
MOV_BXIv(Word),
|
||||||
|
MOV_SPIv(Word),
|
||||||
|
MOV_BPIv(Word),
|
||||||
|
MOV_SIIv(Word),
|
||||||
|
MOV_DIIv(Word),
|
||||||
// LEA
|
// LEA
|
||||||
LEA(ModRmTarget, Register),
|
LEA(ModRmTarget, Register),
|
||||||
// Sign extensions
|
// Sign extensions
|
||||||
@@ -183,6 +205,23 @@ pub enum Mnemonic {
|
|||||||
POPF,
|
POPF,
|
||||||
SAHF,
|
SAHF,
|
||||||
LAHF,
|
LAHF,
|
||||||
|
// String Byte Operations
|
||||||
|
MOVSB,
|
||||||
|
MOVSW,
|
||||||
|
CMPSB,
|
||||||
|
CMPSW,
|
||||||
|
STOSB,
|
||||||
|
STOSW,
|
||||||
|
LODSB,
|
||||||
|
LODSW,
|
||||||
|
SCASB,
|
||||||
|
SCASW,
|
||||||
|
// RET
|
||||||
|
RETIw(Word),
|
||||||
|
RET,
|
||||||
|
// Load ES/DS Register
|
||||||
|
LES(ModRmTarget),
|
||||||
|
LDS(ModRmTarget),
|
||||||
// INT
|
// INT
|
||||||
INT(Byte),
|
INT(Byte),
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user