ft: implement some more mnemonics
This commit is contained in:
@@ -2,7 +2,7 @@ use core::fmt;
|
|||||||
use std::{fs::File, io::Read, process::exit};
|
use std::{fs::File, io::Read, process::exit};
|
||||||
|
|
||||||
use crate::aout::Aout;
|
use crate::aout::Aout;
|
||||||
use crate::instructions::{ImmediateOperand, MemoryIndex, ModRmTarget};
|
use crate::instructions::{ImmediateOperand, MemoryIndex, ModRmTarget, Pointer};
|
||||||
use crate::register::{Register, RegisterId, SegmentRegister};
|
use crate::register::{Register, RegisterId, SegmentRegister};
|
||||||
use crate::{
|
use crate::{
|
||||||
Args,
|
Args,
|
||||||
@@ -143,7 +143,7 @@ impl Disassembler {
|
|||||||
displacement = Some(ImmediateOperand::Word(self.parse_word()));
|
displacement = Some(ImmediateOperand::Word(self.parse_word()));
|
||||||
}
|
}
|
||||||
0b11 => {
|
0b11 => {
|
||||||
log::debug!("ModRM to reg");
|
log::debug!("ModRM (0b{:b}) to/from Register (0b{: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 {
|
||||||
ImmediateOperand::Byte(_) => {
|
ImmediateOperand::Byte(_) => {
|
||||||
@@ -409,6 +409,39 @@ impl Disassembler {
|
|||||||
|
|
||||||
0x8D => modrmv!(self, LEA),
|
0x8D => modrmv!(self, LEA),
|
||||||
|
|
||||||
|
0x8F => {
|
||||||
|
let target = self.parse_modrm_byte(ImmediateOperand::Word(0)).0;
|
||||||
|
let mem = match target {
|
||||||
|
ModRmTarget::Memory(idx) => idx,
|
||||||
|
_ => panic!("POP_M instruction given a register to pop into"),
|
||||||
|
};
|
||||||
|
Mnemonic::POP_M(mem)
|
||||||
|
}
|
||||||
|
0x90 => Mnemonic::NOP(),
|
||||||
|
|
||||||
|
0x91 => Mnemonic::XCHG_AX(Register::CX),
|
||||||
|
0x92 => Mnemonic::XCHG_AX(Register::DX),
|
||||||
|
0x93 => Mnemonic::XCHG_AX(Register::BX),
|
||||||
|
0x94 => Mnemonic::XCHG_AX(Register::SP),
|
||||||
|
0x95 => Mnemonic::XCHG_AX(Register::BP),
|
||||||
|
0x96 => Mnemonic::XCHG_AX(Register::SI),
|
||||||
|
0x97 => Mnemonic::XCHG_AX(Register::DI),
|
||||||
|
|
||||||
|
0x98 => Mnemonic::CBW,
|
||||||
|
0x99 => Mnemonic::CWD,
|
||||||
|
|
||||||
|
0x9A => Mnemonic::CALL(Pointer {
|
||||||
|
segment: self.parse_word(),
|
||||||
|
offset: self.parse_word(),
|
||||||
|
}),
|
||||||
|
|
||||||
|
0x9B => Mnemonic::WAIT,
|
||||||
|
|
||||||
|
0x9C => Mnemonic::PUSHF,
|
||||||
|
0x9D => Mnemonic::POPF,
|
||||||
|
0x9E => Mnemonic::SAHF,
|
||||||
|
0x9F => Mnemonic::LAHF,
|
||||||
|
|
||||||
0xCD => Mnemonic::INT(self.parse_byte()),
|
0xCD => Mnemonic::INT(self.parse_byte()),
|
||||||
|
|
||||||
0xBB => Mnemonic::MOV_BXIv(self.parse_word()),
|
0xBB => Mnemonic::MOV_BXIv(self.parse_word()),
|
||||||
|
|||||||
@@ -68,18 +68,19 @@ impl fmt::Display for Instruction {
|
|||||||
pub enum Mnemonic {
|
pub enum Mnemonic {
|
||||||
NOP(),
|
NOP(),
|
||||||
// ADD
|
// ADD
|
||||||
ADD_FromReg(ModRmTarget, Register),
|
ADD_FromReg(ModRmTarget, Register), // From Register into either Memory or Register
|
||||||
ADD_ToReg(ModRmTarget, Register),
|
ADD_ToReg(ModRmTarget, Register), // From either Memory or Register into Reigster
|
||||||
ADD_Ib(ModRmTarget, ImmediateByte),
|
ADD_Ib(ModRmTarget, ImmediateByte), // From Immediate into either Memory or Register
|
||||||
ADD_Iv(ModRmTarget, ImmediateWord),
|
ADD_Iv(ModRmTarget, ImmediateWord), // From Immediate into either Memory or Register
|
||||||
ADD_ALIb(ImmediateByte),
|
ADD_ALIb(ImmediateByte),
|
||||||
ADD_AXIv(ImmediateWord),
|
ADD_AXIv(ImmediateWord),
|
||||||
// PUSH
|
// PUSH
|
||||||
PUSH_R(Register),
|
PUSH_R(Register),
|
||||||
PUSH_S(SegmentRegister),
|
PUSH_S(SegmentRegister),
|
||||||
// POP
|
// POP
|
||||||
POP_S(SegmentRegister),
|
POP_S(SegmentRegister), // POP to Segment Register
|
||||||
POP_R(Register),
|
POP_R(Register), // POP to Register
|
||||||
|
POP_M(MemoryIndex), // POP to Memory
|
||||||
// OR
|
// OR
|
||||||
OR_FromReg(ModRmTarget, Register),
|
OR_FromReg(ModRmTarget, Register),
|
||||||
OR_ToReg(ModRmTarget, Register),
|
OR_ToReg(ModRmTarget, Register),
|
||||||
@@ -161,6 +162,7 @@ pub enum Mnemonic {
|
|||||||
TEST(ModRmTarget, Register),
|
TEST(ModRmTarget, Register),
|
||||||
//XHCG
|
//XHCG
|
||||||
XHCG(ModRmTarget, Register),
|
XHCG(ModRmTarget, Register),
|
||||||
|
XCHG_AX(Register), // from AX
|
||||||
// MOV
|
// MOV
|
||||||
MOV_FromReg(ModRmTarget, Register),
|
MOV_FromReg(ModRmTarget, Register),
|
||||||
MOV_ToReg(ModRmTarget, Register),
|
MOV_ToReg(ModRmTarget, Register),
|
||||||
@@ -169,6 +171,18 @@ pub enum Mnemonic {
|
|||||||
MOV_BXIv(ImmediateWord),
|
MOV_BXIv(ImmediateWord),
|
||||||
// LEA
|
// LEA
|
||||||
LEA(ModRmTarget, Register),
|
LEA(ModRmTarget, Register),
|
||||||
|
// Sign extensions
|
||||||
|
CBW,
|
||||||
|
CWD,
|
||||||
|
// CALL
|
||||||
|
CALL(Pointer),
|
||||||
|
// WAIT
|
||||||
|
WAIT,
|
||||||
|
// Push/Pop Flags
|
||||||
|
PUSHF,
|
||||||
|
POPF,
|
||||||
|
SAHF,
|
||||||
|
LAHF,
|
||||||
// INT
|
// INT
|
||||||
INT(ImmediateByte),
|
INT(ImmediateByte),
|
||||||
}
|
}
|
||||||
@@ -182,6 +196,7 @@ impl fmt::Display for Mnemonic {
|
|||||||
Self::CMP_Iv(mem, imm) => write!(f, "cmp {}, {:04x}", mem, imm),
|
Self::CMP_Iv(mem, imm) => write!(f, "cmp {}, {:04x}", mem, imm),
|
||||||
Self::LEA(mem, reg) => write!(f, "lea {}, {}", reg, mem),
|
Self::LEA(mem, reg) => write!(f, "lea {}, {}", reg, mem),
|
||||||
Self::MOV_BXIv(word) => write!(f, "mov bx, {:04x}", word),
|
Self::MOV_BXIv(word) => write!(f, "mov bx, {:04x}", word),
|
||||||
|
Self::MOV_FromReg(target, reg) => write!(f, "mov {}, {}", target, reg),
|
||||||
Self::XOR_FromReg(mem, reg) => write!(f, "xor {}, {}", mem, reg),
|
Self::XOR_FromReg(mem, reg) => write!(f, "xor {}, {}", mem, reg),
|
||||||
_ => write!(f, "??? ??, ??"),
|
_ => write!(f, "??? ??, ??"),
|
||||||
}
|
}
|
||||||
@@ -236,3 +251,16 @@ impl fmt::Display for MemoryIndex {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
/// 32-bit segment:offset pointer (e.g. for CALL instruction)
|
||||||
|
pub struct Pointer {
|
||||||
|
pub segment: ImmediateWord,
|
||||||
|
pub offset: ImmediateWord,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Display for Pointer {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
|
write!(f, "{}:{}", self.segment, self.offset)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user