597 lines
23 KiB
Rust
597 lines
23 KiB
Rust
//! Internal abstraction of the 8086 instructions.
|
|
|
|
use crate::{
|
|
operands::{Byte, MemoryIndex, ModRmTarget, Pointer16, Pointer32, Word},
|
|
register::{Register, SegmentRegister},
|
|
};
|
|
use core::fmt;
|
|
|
|
#[derive(Debug, Clone, Eq, PartialEq)]
|
|
/// A single 'line' of executable ASM is called an Instruction, which
|
|
/// contains the `Mnemonic` that will be executed, alongside its starting offset
|
|
/// and the raw parsed bytes
|
|
pub struct Instruction {
|
|
pub start: usize, // location of the instruction start
|
|
pub raw: Vec<u8>, // raw value of instruction
|
|
pub opcode: Mnemonic, // actual instruction
|
|
}
|
|
|
|
impl Instruction {
|
|
pub fn new() -> Self {
|
|
Instruction {
|
|
start: 0,
|
|
raw: Vec::new(),
|
|
opcode: Mnemonic::NOP(),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl fmt::Display for Instruction {
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
write!(f, "{:04x}:\t", self.start).unwrap();
|
|
|
|
write!(
|
|
f,
|
|
"{:<16}", // length of longest possible instruction
|
|
self.raw
|
|
.iter()
|
|
.map(|b| format!("{:02x}", b))
|
|
.collect::<Vec<String>>()
|
|
.join(" ")
|
|
)
|
|
.unwrap();
|
|
|
|
write!(f, "\t{}", self.opcode)
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone, PartialEq, Eq, Copy)]
|
|
#[allow(non_camel_case_types)]
|
|
/// All possible mnemonic variantions.
|
|
/// These are sorted by type and are not in hex-encoding order.
|
|
// XXX: convert this copy and paste horror in a proc macro like
|
|
// enum Opcode {
|
|
// #[derive(default_variations)]
|
|
// ADD,
|
|
// ...
|
|
// }
|
|
// which then add all variants and also create the matching logic for
|
|
// src/disasm.rs decode_instructions()
|
|
pub enum Mnemonic {
|
|
NOP(),
|
|
// ADD
|
|
ADD_FromReg(ModRmTarget, Register), // From Register into either Memory or Register
|
|
ADD_ToReg(ModRmTarget, Register), // From either Memory or Register into Reigster
|
|
ADD_Ib(ModRmTarget, Byte), // From Immediate into either Memory or Register
|
|
ADD_Iv(ModRmTarget, Word), // From Immediate into either Memory or Register
|
|
ADD_ALIb(Byte),
|
|
ADD_AXIv(Word),
|
|
// PUSH
|
|
PUSH_R(Register),
|
|
PUSH_S(SegmentRegister),
|
|
PUSH_Mod(ModRmTarget),
|
|
// POP
|
|
POP_S(SegmentRegister), // POP to Segment Register
|
|
POP_R(Register), // POP to Register
|
|
POP_M(MemoryIndex), // POP to Memory
|
|
// OR
|
|
OR_FromReg(ModRmTarget, Register),
|
|
OR_ToReg(ModRmTarget, Register),
|
|
OR_Ib(ModRmTarget, Byte),
|
|
OR_Iv(ModRmTarget, Word),
|
|
OR_ALIb(Byte),
|
|
OR_AXIv(Word),
|
|
// ADC
|
|
ADC_FromReg(ModRmTarget, Register),
|
|
ADC_ToReg(ModRmTarget, Register),
|
|
ADC_Ib(ModRmTarget, Byte),
|
|
ADC_Iv(ModRmTarget, Word),
|
|
ADC_ALIb(Byte),
|
|
ADC_AXIv(Word),
|
|
// SBB
|
|
SBB_FromReg(ModRmTarget, Register),
|
|
SBB_ToReg(ModRmTarget, Register),
|
|
SBB_Ib(ModRmTarget, Byte),
|
|
SBB_Iv(ModRmTarget, Word),
|
|
SBB_ALIb(Byte),
|
|
SBB_AXIv(Word),
|
|
// AND
|
|
AND_FromReg(ModRmTarget, Register),
|
|
AND_ToReg(ModRmTarget, Register),
|
|
AND_Ib(ModRmTarget, Byte),
|
|
AND_Iv(ModRmTarget, Word),
|
|
AND_ALIb(Byte),
|
|
AND_AXIv(Word),
|
|
// Override
|
|
OVERRIDE(SegmentRegister),
|
|
// Decimal Adjustment
|
|
DAA,
|
|
DAS,
|
|
AAA,
|
|
AAS,
|
|
// SUB
|
|
SUB_FromReg(ModRmTarget, Register),
|
|
SUB_ToReg(ModRmTarget, Register),
|
|
SUB_Ib(ModRmTarget, Byte),
|
|
SUB_Iv(ModRmTarget, Word),
|
|
SUB_ALIb(Byte),
|
|
SUB_AXIv(Word),
|
|
// XOR
|
|
XOR_FromReg(ModRmTarget, Register),
|
|
XOR_ToReg(ModRmTarget, Register),
|
|
XOR_Ib(ModRmTarget, Byte),
|
|
XOR_Iv(ModRmTarget, Word),
|
|
XOR_ALIb(Byte),
|
|
XOR_AXIv(Word),
|
|
// CMP
|
|
CMP_FromReg(ModRmTarget, Register),
|
|
CMP_ToReg(ModRmTarget, Register),
|
|
CMP_Ib(ModRmTarget, Byte),
|
|
CMP_Iv(ModRmTarget, Word),
|
|
CMP_ALIb(Byte),
|
|
CMP_AXIv(Word),
|
|
// INC
|
|
INC_Reg(Register),
|
|
INC_Mod(ModRmTarget),
|
|
// DEC
|
|
DEC_Reg(Register),
|
|
DEC_Mod(ModRmTarget),
|
|
// Jumps conditional
|
|
JO(usize),
|
|
JNO(usize),
|
|
JB(usize),
|
|
JNB(usize),
|
|
JZ(usize),
|
|
JNZ(usize),
|
|
JBE(usize),
|
|
JA(usize),
|
|
JS(usize),
|
|
JNS(usize),
|
|
JPE(usize),
|
|
JPO(usize),
|
|
JL(usize),
|
|
JGE(usize),
|
|
JLE(usize),
|
|
JG(usize),
|
|
LOOPNZ(usize),
|
|
LOOPZ(usize),
|
|
LOOP(usize),
|
|
JCXZ(usize),
|
|
|
|
// TEST
|
|
TEST(ModRmTarget, Register),
|
|
TEST_Ib(ModRmTarget, Byte),
|
|
TEST_Iv(ModRmTarget, Word),
|
|
TEST_ALIb(Byte),
|
|
TEST_AXIv(Word),
|
|
//XHCG
|
|
XCHG(ModRmTarget, Register),
|
|
XCHG_AX(Register), // from AX
|
|
// MOV
|
|
MOV_FromReg(ModRmTarget, Register),
|
|
MOV_ToReg(ModRmTarget, Register),
|
|
MOV_FromSReg(ModRmTarget, SegmentRegister),
|
|
MOV_ToSReg(ModRmTarget, SegmentRegister),
|
|
MOV_Ib(ModRmTarget, Byte),
|
|
MOV_Iv(ModRmTarget, Word),
|
|
|
|
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
|
|
CBW,
|
|
CWD,
|
|
// CALL
|
|
CALL_p(Pointer32),
|
|
CALL_v(usize),
|
|
CALL_Mod(ModRmTarget),
|
|
CALL_Mp(Pointer16),
|
|
// JUMP
|
|
JMP_p(Pointer32),
|
|
JMP_b(usize), // parses IByte, but stores as isize
|
|
JMP_v(usize), // parwses IWord, but stores as isize
|
|
JMP_Mod(ModRmTarget),
|
|
JMP_Mp(Pointer16),
|
|
// WAIT
|
|
WAIT,
|
|
// Push/Pop Flags
|
|
PUSHF,
|
|
POPF,
|
|
SAHF,
|
|
LAHF,
|
|
// String Byte Operations
|
|
MOVSB,
|
|
MOVSW,
|
|
CMPSB,
|
|
CMPSW,
|
|
STOSB,
|
|
STOSW,
|
|
LODSB,
|
|
LODSW,
|
|
SCASB,
|
|
SCASW,
|
|
// RET
|
|
RET_Iw(Word),
|
|
RET,
|
|
RETF_Iw(Word),
|
|
RETF,
|
|
IRET,
|
|
// Load ES/DS Register
|
|
LES(Register, Pointer16),
|
|
LDS(Register, Pointer16),
|
|
// NOT
|
|
NOT(ModRmTarget),
|
|
// NEG
|
|
NEG(ModRmTarget),
|
|
// MUL
|
|
MUL(ModRmTarget),
|
|
IMUL(ModRmTarget),
|
|
// DIV
|
|
DIV(ModRmTarget),
|
|
IDIV(ModRmTarget),
|
|
// HALT
|
|
HLT,
|
|
// Shift and Rotate
|
|
ROL_b(ModRmTarget, Byte),
|
|
ROR_b(ModRmTarget, Byte),
|
|
RCL_b(ModRmTarget, Byte),
|
|
RCR_b(ModRmTarget, Byte),
|
|
SHL_b(ModRmTarget, Byte),
|
|
SHR_b(ModRmTarget, Byte),
|
|
SAR_b(ModRmTarget, Byte),
|
|
ROL_fromReg(ModRmTarget, Register),
|
|
ROR_fromReg(ModRmTarget, Register),
|
|
RCL_fromReg(ModRmTarget, Register),
|
|
RCR_fromReg(ModRmTarget, Register),
|
|
SHL_fromReg(ModRmTarget, Register),
|
|
SHR_fromReg(ModRmTarget, Register),
|
|
SAR_fromReg(ModRmTarget, Register),
|
|
// IN
|
|
IN_AL(Byte),
|
|
IN_AX(Byte),
|
|
IN_ALDX,
|
|
IN_AXDX,
|
|
// OUT
|
|
OUT_AL(Byte),
|
|
OUT_AX(Byte),
|
|
OUT_ALDX,
|
|
OUT_AXDX,
|
|
// INT
|
|
INT(Byte),
|
|
INTO,
|
|
// Flag Manipulation
|
|
CLC,
|
|
STC,
|
|
CLI,
|
|
STI,
|
|
CLD,
|
|
STD,
|
|
CMC,
|
|
// Repeat prefix
|
|
REPNZ,
|
|
REPZ,
|
|
// Adjust
|
|
AAM(Byte),
|
|
AAD(Byte),
|
|
// MISC
|
|
XLAT,
|
|
LOCK,
|
|
}
|
|
|
|
impl fmt::Display for Mnemonic {
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
match self {
|
|
Self::ADD_FromReg(target, reg) => write!(f, "add {target}, {reg}"),
|
|
Self::ADD_ToReg(target, reg) => write!(f, "add {reg}, {target}"),
|
|
Self::ADD_Ib(target, byte) => match target {
|
|
ModRmTarget::Memory(_) => write!(f, "add byte ptr {target}, {byte:#04x}"),
|
|
ModRmTarget::Register(_) => write!(f, "add byte {target}, {byte:#04x}"),
|
|
},
|
|
Self::ADD_Iv(target, word) => match target {
|
|
ModRmTarget::Memory(_) => write!(f, "add word ptr {target}, {word:#04x}"),
|
|
ModRmTarget::Register(_) => write!(f, "add word {target}, {word:#04x}"),
|
|
},
|
|
Self::ADD_ALIb(byte) => write!(f, "add {}, {byte:#04x}", Register::AL),
|
|
Self::ADD_AXIv(word) => write!(f, "add {}, {word:#04x}", Register::AX),
|
|
|
|
Self::PUSH_R(reg) => write!(f, "push {reg}"),
|
|
Self::PUSH_S(reg) => write!(f, "push {reg}"),
|
|
Self::PUSH_Mod(target) => write!(f, "push {target}"),
|
|
|
|
Self::POP_R(reg) => write!(f, "pop {reg}"),
|
|
Self::POP_S(reg) => write!(f, "pop {reg}"),
|
|
Self::POP_M(mem) => write!(f, "pop {mem}"),
|
|
|
|
Self::OR_FromReg(target, reg) => write!(f, "or {target}, {reg}"),
|
|
Self::OR_ToReg(target, reg) => write!(f, "or {reg}, {target}"),
|
|
Self::OR_Ib(target, byte) => match target {
|
|
ModRmTarget::Memory(_) => write!(f, "or byte ptr {target}, {byte:#04x}"),
|
|
ModRmTarget::Register(_) => write!(f, "or byte {target}, {byte:#04x}"),
|
|
},
|
|
Self::OR_Iv(target, word) => match target {
|
|
ModRmTarget::Memory(_) => write!(f, "or word ptr {target}, {word:#04x}"),
|
|
ModRmTarget::Register(_) => write!(f, "or word {target}, {word:#04x}"),
|
|
},
|
|
Self::OR_ALIb(byte) => write!(f, "or {}, {byte:#04x}", Register::AL),
|
|
Self::OR_AXIv(word) => write!(f, "or {}, {word:#04x}", Register::AX),
|
|
|
|
Self::ADC_FromReg(target, reg) => write!(f, "adc {target}, {reg}"),
|
|
Self::ADC_ToReg(target, reg) => write!(f, "adc {reg}, {target}"),
|
|
Self::ADC_Ib(target, byte) => match target {
|
|
ModRmTarget::Memory(_) => write!(f, "adc byte ptr {target}, {byte:#04x}"),
|
|
ModRmTarget::Register(_) => write!(f, "adc byte {target}, {byte:#04x}"),
|
|
},
|
|
Self::ADC_Iv(target, word) => match target {
|
|
ModRmTarget::Memory(_) => write!(f, "adc word ptr {target}, {word:#04x}"),
|
|
ModRmTarget::Register(_) => write!(f, "adc word {target}, {word:#04x}"),
|
|
},
|
|
Self::ADC_ALIb(byte) => write!(f, "adc {}, {byte:#04x}", Register::AL),
|
|
Self::ADC_AXIv(word) => write!(f, "adc {}, {word:#04x}", Register::AX),
|
|
|
|
Self::SBB_FromReg(target, reg) => write!(f, "sbb {target}, {reg}"),
|
|
Self::SBB_ToReg(target, reg) => write!(f, "sbb {reg}, {target}"),
|
|
Self::SBB_Ib(target, byte) => match target {
|
|
ModRmTarget::Memory(_) => write!(f, "sbb byte ptr {target}, {byte:#04x}"),
|
|
ModRmTarget::Register(_) => write!(f, "sbb byte {target}, {byte:#04x}"),
|
|
},
|
|
Self::SBB_Iv(target, word) => match target {
|
|
ModRmTarget::Memory(_) => write!(f, "sbb word ptr {target}, {word:#04x}"),
|
|
ModRmTarget::Register(_) => write!(f, "sbb word {target}, {word:#04x}"),
|
|
},
|
|
Self::SBB_ALIb(byte) => write!(f, "sbb {}, {byte:#04x}", Register::AL),
|
|
Self::SBB_AXIv(word) => write!(f, "sbb {}, {word:#04x}", Register::AX),
|
|
|
|
Self::AND_FromReg(target, reg) => write!(f, "and {target}, {reg}"),
|
|
Self::AND_ToReg(target, reg) => write!(f, "and {reg}, {target}"),
|
|
Self::AND_Ib(target, byte) => match target {
|
|
ModRmTarget::Memory(_) => write!(f, "and byte ptr {target}, {byte:#04x}"),
|
|
ModRmTarget::Register(_) => write!(f, "and byte {target}, {byte:#04x}"),
|
|
},
|
|
Self::AND_Iv(target, word) => match target {
|
|
ModRmTarget::Memory(_) => write!(f, "and word ptr {target}, {word:#04x}"),
|
|
ModRmTarget::Register(_) => write!(f, "and word {target}, {word:#04x}"),
|
|
},
|
|
Self::AND_ALIb(byte) => write!(f, "and {}, {byte:#04x}", Register::AL),
|
|
Self::AND_AXIv(word) => write!(f, "and {}, {word:#04x}", Register::AX),
|
|
|
|
Self::OVERRIDE(reg) => write!(f, "{reg}:"),
|
|
|
|
Self::DAA => write!(f, "daa"),
|
|
Self::DAS => write!(f, "das"),
|
|
Self::AAA => write!(f, "aaa"),
|
|
Self::AAS => write!(f, "aas"),
|
|
|
|
Self::SUB_FromReg(target, reg) => write!(f, "sub {target}, {reg}"),
|
|
Self::SUB_ToReg(target, reg) => write!(f, "sub {reg}, {target}"),
|
|
Self::SUB_Ib(target, byte) => match target {
|
|
ModRmTarget::Memory(_) => write!(f, "sub byte ptr {target}, {byte:#04x}"),
|
|
ModRmTarget::Register(_) => write!(f, "sub byte {target}, {byte:#04x}"),
|
|
},
|
|
Self::SUB_Iv(target, word) => match target {
|
|
ModRmTarget::Memory(_) => write!(f, "sub word ptr {target}, {word:#04x}"),
|
|
ModRmTarget::Register(_) => write!(f, "sub word {target}, {word:#04x}"),
|
|
},
|
|
Self::SUB_ALIb(byte) => write!(f, "sub {}, {byte:#04x}", Register::AL),
|
|
Self::SUB_AXIv(word) => write!(f, "sub {}, {word:#04x}", Register::AX),
|
|
|
|
Self::XOR_FromReg(target, reg) => write!(f, "xor {target}, {reg}"),
|
|
Self::XOR_ToReg(target, reg) => write!(f, "xor {reg}, {target}"),
|
|
Self::XOR_Ib(target, byte) => match target {
|
|
ModRmTarget::Memory(_) => write!(f, "xor byte ptr {target}, {byte:#04x}"),
|
|
ModRmTarget::Register(_) => write!(f, "xor byte {target}, {byte:#04x}"),
|
|
},
|
|
Self::XOR_Iv(target, word) => match target {
|
|
ModRmTarget::Memory(_) => write!(f, "xor word ptr {target}, {word:#04x}"),
|
|
ModRmTarget::Register(_) => write!(f, "xor word {target}, {word:#04x}"),
|
|
},
|
|
Self::XOR_ALIb(byte) => write!(f, "xor {}, {byte:#04x}", Register::AL),
|
|
Self::XOR_AXIv(word) => write!(f, "xor {}, {word:#04x}", Register::AX),
|
|
|
|
Self::CMP_FromReg(target, reg) => write!(f, "cmp {target}, {reg}"),
|
|
Self::CMP_ToReg(target, reg) => write!(f, "cmp {reg}, {target}"),
|
|
Self::CMP_Ib(target, byte) => match target {
|
|
ModRmTarget::Memory(_) => write!(f, "cmp byte ptr {target}, {byte:#04x}"),
|
|
ModRmTarget::Register(_) => write!(f, "cmp byte {target}, {byte:#04x}"),
|
|
},
|
|
Self::CMP_Iv(target, word) => match target {
|
|
ModRmTarget::Memory(_) => write!(f, "cmp word ptr {target}, {word:#04x}"),
|
|
ModRmTarget::Register(_) => write!(f, "cmp word {target}, {word:#04x}"),
|
|
},
|
|
Self::CMP_ALIb(byte) => write!(f, "cmp {}, {byte:#04x}", Register::AL),
|
|
Self::CMP_AXIv(word) => write!(f, "cmp {}, {word:#04x}", Register::AX),
|
|
|
|
Self::INC_Reg(reg) => write!(f, "inc {reg}"),
|
|
Self::INC_Mod(target) => write!(f, "inc {target}"),
|
|
|
|
Self::DEC_Reg(reg) => write!(f, "dec {reg}"),
|
|
Self::DEC_Mod(target) => write!(f, "dec {target}"),
|
|
|
|
Self::JO(ibyte) => write!(f, "jo {ibyte:#04x}"),
|
|
Self::JNO(ibyte) => write!(f, "jno {ibyte:#04x}"),
|
|
Self::JB(ibyte) => write!(f, "jb {ibyte:#04x}"),
|
|
Self::JNB(ibyte) => write!(f, "jnb {ibyte:#04x}"),
|
|
Self::JZ(ibyte) => write!(f, "jz {ibyte:#04x}"),
|
|
Self::JNZ(ibyte) => write!(f, "jnz {ibyte:#04x}"),
|
|
Self::JBE(ibyte) => write!(f, "jbe {ibyte:#04x}"),
|
|
Self::JA(ibyte) => write!(f, "ja {ibyte:#04x}"),
|
|
Self::JS(ibyte) => write!(f, "js {ibyte:#04x}"),
|
|
Self::JNS(ibyte) => write!(f, "jns {ibyte:#04x}"),
|
|
Self::JPE(ibyte) => write!(f, "jpe {ibyte:#04x}"),
|
|
Self::JPO(ibyte) => write!(f, "jpo {ibyte:#04x}"),
|
|
Self::JL(ibyte) => write!(f, "jl {ibyte:#04x}"),
|
|
Self::JGE(ibyte) => write!(f, "jge {ibyte:#04x}"),
|
|
Self::JLE(ibyte) => write!(f, "jle {ibyte:#04x}"),
|
|
Self::JG(ibyte) => write!(f, "jg {ibyte:#04x}"),
|
|
Self::LOOPNZ(ibyte) => write!(f, "loopnz {ibyte:#04x}"),
|
|
Self::LOOPZ(ibyte) => write!(f, "loopz {ibyte:#04x}"),
|
|
Self::LOOP(ibyte) => write!(f, "loop {ibyte:#04x}"),
|
|
Self::JCXZ(ibyte) => write!(f, "jcxz {ibyte:#04x}"),
|
|
|
|
Self::TEST(target, reg) => write!(f, "test {target}, {reg}"),
|
|
Self::TEST_Ib(target, byte) => write!(f, "test byte ptr {target}, {byte:#04x}"),
|
|
Self::TEST_Iv(target, word) => write!(f, "test word ptr {target}, {word:#04x}"),
|
|
Self::TEST_ALIb(byte) => write!(f, "test {}, {byte:#04x}", Register::AL),
|
|
Self::TEST_AXIv(word) => write!(f, "test {}, {word:#04x}", Register::AX),
|
|
|
|
Self::XCHG(target, reg) => write!(f, "xchg {target}, {reg}"),
|
|
Self::XCHG_AX(reg) => write!(f, "xchg, {reg}, {}", Register::AX),
|
|
|
|
Self::MOV_FromReg(target, reg) => write!(f, "mov {target}, {reg}"),
|
|
Self::MOV_ToReg(target, reg) => write!(f, "mov {reg}, {target}"),
|
|
Self::MOV_FromSReg(target, reg) => write!(f, "mov {target}, {reg}"),
|
|
Self::MOV_ToSReg(target, reg) => write!(f, "mov {reg}, {target}"),
|
|
Self::MOV_Ib(target, byte) => match target {
|
|
ModRmTarget::Memory(_) => write!(f, "mov byte ptr {target}, {byte:#04x}"),
|
|
ModRmTarget::Register(_) => write!(f, "mov byte {target}, {byte:#04x}"),
|
|
},
|
|
Self::MOV_Iv(target, word) => match target {
|
|
ModRmTarget::Memory(_) => write!(f, "mov word ptr {target}, {word:#04x}"),
|
|
ModRmTarget::Register(_) => write!(f, "mov word {target}, {word:#04x}"),
|
|
},
|
|
|
|
Self::MOV_AL0b(byte) => write!(f, "mov {}, {byte:#04x}", Register::AL),
|
|
Self::MOV_AX0v(word) => write!(f, "mov {}, {word:#04x}", Register::AX),
|
|
Self::MOV_0bAL(byte) => write!(f, "mov {byte:#04x}, {}", Register::AL),
|
|
Self::MOV_0vAX(word) => write!(f, "mov {word:#04x}, {}", Register::AX),
|
|
|
|
Self::MOV_ALIb(byte) => write!(f, "mov {}, {byte:#04x}", Register::AL),
|
|
Self::MOV_CLIb(byte) => write!(f, "mov {}, {byte:#04x}", Register::CL),
|
|
Self::MOV_DLIb(byte) => write!(f, "mov {}, {byte:#04x}", Register::DL),
|
|
Self::MOV_BLIb(byte) => write!(f, "mov {}, {byte:#04x}", Register::BL),
|
|
Self::MOV_AHIb(byte) => write!(f, "mov {}, {byte:#04x}", Register::AH),
|
|
Self::MOV_CHIb(byte) => write!(f, "mov {}, {byte:#04x}", Register::CH),
|
|
Self::MOV_DHIb(byte) => write!(f, "mov {}, {byte:#04x}", Register::DH),
|
|
Self::MOV_BHIb(byte) => write!(f, "mov {}, {byte:#04x}", Register::BH),
|
|
Self::MOV_AXIv(word) => write!(f, "mov {}, {word:#04x}", Register::AX),
|
|
Self::MOV_CXIv(word) => write!(f, "mov {}, {word:#04x}", Register::CX),
|
|
Self::MOV_DXIv(word) => write!(f, "mov {}, {word:#04x}", Register::DX),
|
|
Self::MOV_BXIv(word) => write!(f, "mov {}, {word:#04x}", Register::BX),
|
|
Self::MOV_SPIv(word) => write!(f, "mov {}, {word:#04x}", Register::SP),
|
|
Self::MOV_BPIv(word) => write!(f, "mov {}, {word:#04x}", Register::BP),
|
|
Self::MOV_SIIv(word) => write!(f, "mov {}, {word:#04x}", Register::SI),
|
|
Self::MOV_DIIv(word) => write!(f, "mov {}, {word:#04x}", Register::DI),
|
|
|
|
Self::LEA(mem, reg) => write!(f, "lea {}, {}", reg, mem),
|
|
|
|
Self::CBW => write!(f, "cbw"),
|
|
Self::CWD => write!(f, "cwd"),
|
|
|
|
Self::CALL_p(ptr) => write!(f, "call {ptr}"),
|
|
Self::CALL_v(word) => write!(f, "call {word:#04x}"),
|
|
Self::CALL_Mod(target) => write!(f, "call {target}"),
|
|
Self::CALL_Mp(ptr) => write!(f, "call {ptr}"),
|
|
|
|
Self::JMP_p(ptr) => write!(f, "jmp {ptr}"),
|
|
Self::JMP_b(byte) => write!(f, "jmp {byte:#04x}"),
|
|
Self::JMP_v(word) => write!(f, "jmp {word:#04x}"),
|
|
Self::JMP_Mod(target) => write!(f, "jmp {target}"),
|
|
Self::JMP_Mp(ptr) => write!(f, "jmp {ptr}"),
|
|
|
|
Self::WAIT => write!(f, "wait"),
|
|
|
|
Self::PUSHF => write!(f, "pushf"),
|
|
Self::POPF => write!(f, "popf"),
|
|
Self::SAHF => write!(f, "sahf"),
|
|
Self::LAHF => write!(f, "lahf"),
|
|
|
|
Self::MOVSB => write!(f, "movsb"),
|
|
Self::MOVSW => write!(f, "movsw"),
|
|
Self::CMPSB => write!(f, "cmpsb"),
|
|
Self::CMPSW => write!(f, "cmpsw"),
|
|
Self::STOSB => write!(f, "stosb"),
|
|
Self::STOSW => write!(f, "stosw"),
|
|
Self::LODSB => write!(f, "lodsb"),
|
|
Self::LODSW => write!(f, "lodsw"),
|
|
Self::SCASB => write!(f, "scasb"),
|
|
Self::SCASW => write!(f, "scasw"),
|
|
|
|
Self::RET_Iw(word) => write!(f, "ret {word:#04x}"),
|
|
Self::RET => write!(f, "ret"),
|
|
Self::RETF_Iw(word) => write!(f, "retf {word:#04x}"),
|
|
Self::RETF => write!(f, "retf"),
|
|
Self::IRET => write!(f, "iret"),
|
|
|
|
Self::LES(reg, mem) => write!(f, "les {reg}, ptr {mem}"),
|
|
Self::LDS(reg, mem) => write!(f, "lds {reg}, ptr {mem}"),
|
|
|
|
Self::NOT(target) => write!(f, "not {target}"),
|
|
Self::NEG(target) => write!(f, "neg {target}"),
|
|
|
|
Self::MUL(target) => write!(f, "mul {target}"),
|
|
Self::IMUL(target) => write!(f, "imul {target}"),
|
|
Self::DIV(target) => write!(f, "mdiv {target}"),
|
|
Self::IDIV(target) => write!(f, "idiv {target}"),
|
|
|
|
Self::HLT => write!(f, "hlt"),
|
|
|
|
Self::ROL_b(target, byte) => write!(f, "rol byte ptr {target}, {byte:#04x}"),
|
|
Self::ROR_b(target, byte) => write!(f, "ror byte ptr {target}, {byte:#04x}"),
|
|
Self::RCL_b(target, byte) => write!(f, "rcl byte ptr {target}, {byte:#04x}"),
|
|
Self::RCR_b(target, byte) => write!(f, "rcr byte ptr {target}, {byte:#04x}"),
|
|
Self::SHL_b(target, byte) => write!(f, "shl byte ptr {target}, {byte:#04x}"),
|
|
Self::SHR_b(target, byte) => write!(f, "shr byte ptr {target}, {byte:#04x}"),
|
|
Self::SAR_b(target, byte) => write!(f, "sar byte ptr {target}, {byte:#04x}"),
|
|
Self::ROL_fromReg(target, reg) => write!(f, "rol {target}, {reg}"),
|
|
Self::ROR_fromReg(target, reg) => write!(f, "ror {target}, {reg}"),
|
|
Self::RCL_fromReg(target, reg) => write!(f, "rcl {target}, {reg}"),
|
|
Self::RCR_fromReg(target, reg) => write!(f, "rcr {target}, {reg}"),
|
|
Self::SHL_fromReg(target, reg) => write!(f, "shl {target}, {reg}"),
|
|
Self::SHR_fromReg(target, reg) => write!(f, "shr {target}, {reg}"),
|
|
Self::SAR_fromReg(target, reg) => write!(f, "sar {target}, {reg}"),
|
|
|
|
Self::IN_AL(byte) => write!(f, "in byte ptr {}, {byte:#04x}", Register::AL),
|
|
Self::IN_AX(byte) => write!(f, "in byte ptr {}, {byte:#04x}", Register::AX),
|
|
Self::IN_ALDX => write!(f, "in {}, {}", Register::AL, Register::DX),
|
|
Self::IN_AXDX => write!(f, "in {}, {}", Register::AX, Register::DX),
|
|
|
|
Self::OUT_AL(byte) => write!(f, "out byte ptr {}, {byte:#04x}", Register::AL),
|
|
Self::OUT_AX(byte) => write!(f, "out byte ptr {}, {byte:#04x}", Register::AX),
|
|
Self::OUT_ALDX => write!(f, "out {}, {}", Register::AL, Register::DX),
|
|
Self::OUT_AXDX => write!(f, "out {}, {}", Register::AX, Register::DX),
|
|
|
|
Self::INT(byte) => write!(f, "int {byte:#04x}"),
|
|
Self::INTO => write!(f, "into"),
|
|
|
|
Self::CLC => write!(f, "clc"),
|
|
Self::STC => write!(f, "stc"),
|
|
Self::CLI => write!(f, "cli"),
|
|
Self::STI => write!(f, "sti"),
|
|
Self::CLD => write!(f, "cld"),
|
|
Self::STD => write!(f, "std"),
|
|
Self::CMC => write!(f, "cmc"),
|
|
|
|
Self::REPNZ => write!(f, "repnz"),
|
|
Self::REPZ => write!(f, "repz"),
|
|
|
|
Self::AAM(byte) => write!(f, "aam {byte:#04x}"),
|
|
Self::AAD(byte) => write!(f, "aad {byte:#04x}"),
|
|
|
|
Self::XLAT => write!(f, "xlat"),
|
|
|
|
Self::LOCK => write!(f, "lock"),
|
|
|
|
_ => write!(f, "??? ??, ??"),
|
|
}
|
|
}
|
|
}
|