ft: implement more mnemonics
This commit is contained in:
@@ -8,7 +8,7 @@ use crate::{
|
||||
Args,
|
||||
instructions::{Instruction, Mnemonic},
|
||||
};
|
||||
use crate::{modrmb, modrmgprb, modrmgprv, modrms, modrmv};
|
||||
use crate::{modrmb, modrmgpr1b, modrmgpr1v, modrms, modrmv};
|
||||
|
||||
#[derive(Debug)]
|
||||
/// Generic errors, which are encountered during parsing.
|
||||
@@ -143,7 +143,7 @@ impl Disassembler {
|
||||
displacement = Some(Operand::Word(self.parse_word()));
|
||||
}
|
||||
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)
|
||||
let target = match width {
|
||||
Operand::Byte(_) => ModRmTarget::Register(Register::by_id(Operand::Byte(rm))),
|
||||
@@ -368,7 +368,7 @@ impl Disassembler {
|
||||
0x5E => Mnemonic::POP_R(Register::SI),
|
||||
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()),
|
||||
0x71 => Mnemonic::JNO(self.parse_byte()),
|
||||
@@ -387,9 +387,10 @@ impl Disassembler {
|
||||
0x7E => Mnemonic::JLE(self.parse_byte()),
|
||||
0x7F => Mnemonic::JG(self.parse_byte()),
|
||||
|
||||
0x80 => modrmgprb!(self),
|
||||
0x81 => modrmgprv!(self),
|
||||
0x82 => modrmgprb!(self), // same as 0x80
|
||||
// Group 1
|
||||
0x80 => modrmgpr1b!(self),
|
||||
0x81 => modrmgpr1v!(self),
|
||||
0x82 => modrmgpr1b!(self), // same as 0x80
|
||||
0x83 => panic!("Sign extented GPR1 not yet implemented"),
|
||||
|
||||
0x84 => modrmb!(self, TEST),
|
||||
@@ -440,9 +441,55 @@ impl Disassembler {
|
||||
0x9E => Mnemonic::SAHF,
|
||||
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()),
|
||||
|
||||
0xBB => Mnemonic::MOV_BXIv(self.parse_word()),
|
||||
// Group 3
|
||||
_ => {
|
||||
eprintln!("Encountered unknown instruction '0x{:x}'", opcode);
|
||||
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
|
||||
/// Immediate, encoded in a ModRM byte.
|
||||
/// GPR always has an imm value as second operand.
|
||||
macro_rules! modrmgprb {
|
||||
macro_rules! modrmgpr1b {
|
||||
($self:ident) => {{
|
||||
let (target, reg) = $self.parse_modrm_byte(Operand::Byte(0));
|
||||
let imm = $self.parse_byte();
|
||||
@@ -41,7 +41,7 @@ macro_rules! modrmgprb {
|
||||
/// Generate the resulting Mnemonic from a GPR instruction with Word-sized
|
||||
/// Immediate, encoded in a ModRM byte.
|
||||
/// GPR always has an imm value as second operand.
|
||||
macro_rules! modrmgprv {
|
||||
macro_rules! modrmgpr1v {
|
||||
($self:ident) => {{
|
||||
let (target, reg) = $self.parse_modrm_byte(Operand::Word(0));
|
||||
let imm = $self.parse_word();
|
||||
|
||||
@@ -160,6 +160,8 @@ pub enum Mnemonic {
|
||||
JG(Byte),
|
||||
// TEST
|
||||
TEST(ModRmTarget, Register),
|
||||
TEST_ALIb(Byte),
|
||||
TEST_AXIv(Word),
|
||||
//XHCG
|
||||
XHCG(ModRmTarget, Register),
|
||||
XCHG_AX(Register), // from AX
|
||||
@@ -168,7 +170,27 @@ pub enum Mnemonic {
|
||||
MOV_ToReg(ModRmTarget, Register),
|
||||
MOV_FromSReg(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_SPIv(Word),
|
||||
MOV_BPIv(Word),
|
||||
MOV_SIIv(Word),
|
||||
MOV_DIIv(Word),
|
||||
// LEA
|
||||
LEA(ModRmTarget, Register),
|
||||
// Sign extensions
|
||||
@@ -183,6 +205,23 @@ pub enum Mnemonic {
|
||||
POPF,
|
||||
SAHF,
|
||||
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(Byte),
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user