ft: add debug script
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1 +1,2 @@
|
||||
/target
|
||||
test.out
|
||||
|
||||
43
gen.py
Normal file
43
gen.py
Normal file
@@ -0,0 +1,43 @@
|
||||
### Python script to generate specific instructions for testing
|
||||
import struct
|
||||
|
||||
output_file = "test.out"
|
||||
|
||||
machine_code = bytes([
|
||||
0xC5, 0x06, 0x34, 0x12, 0xFF, 0x1E, 0x34, 0x12, 0x9A, 0x78, 0x56, 0x34, 0x12, 0xEA, 0x78, 0x56, 0x34, 0x12, 0xFF, 0x1E, 0x34, 0x12, 0xFF, 0x2E, 0x34, 0x12
|
||||
])
|
||||
|
||||
magic = b'\x01\x03'
|
||||
flags = 0x20
|
||||
cpu = 0x0
|
||||
hdrlen = 0x20
|
||||
unused = 0x00
|
||||
version = 0
|
||||
text = len(machine_code)
|
||||
data = 0x00 # 4b
|
||||
bss = 0x00 # 4b
|
||||
entry = 0x00 # 4b
|
||||
total = text + data + bss + entry # 4b
|
||||
syms = 0x00 # 4b
|
||||
|
||||
# pack with LE
|
||||
header = struct.pack('<2sBBBBHLLLLLL',
|
||||
magic,
|
||||
flags,
|
||||
cpu,
|
||||
hdrlen,
|
||||
unused,
|
||||
version,
|
||||
text,
|
||||
data,
|
||||
bss,
|
||||
entry,
|
||||
total,
|
||||
syms
|
||||
)
|
||||
|
||||
with open(output_file, "wb") as f:
|
||||
f.write(header + machine_code)
|
||||
|
||||
print(f"a.out written to: {output_file}")
|
||||
|
||||
@@ -43,7 +43,7 @@ impl fmt::Display for DisasmError {
|
||||
DisasmError::IoError(msg) => write!(f, "{}", msg),
|
||||
DisasmError::OpcodeUndefined(opcode) => write!(
|
||||
f,
|
||||
"Error (Undefined Opcode). '{:#x} is considered undefined by the Spec",
|
||||
"Error (Undefined Opcode). '{:#04x} is considered undefined by the Spec",
|
||||
opcode
|
||||
),
|
||||
DisasmError::IllegalGroupMnemonic(group, mnemonic) => write!(
|
||||
@@ -244,6 +244,8 @@ impl Disassembler {
|
||||
rm
|
||||
);
|
||||
|
||||
// not unused, but overwritten before first read
|
||||
#[allow(unused_assignments)]
|
||||
let mut displacement = None;
|
||||
match mode {
|
||||
0b00 => {
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
//! All types which a Mnemonic can have as some kind of operand.
|
||||
//! This includes things such as immediates, ModRM byte targets, etc. etc.
|
||||
|
||||
// used in doc, but not code
|
||||
#[allow(unused_imports)]
|
||||
use crate::register::SegmentRegister;
|
||||
|
||||
use crate::{disasm::DisasmError, register::Register};
|
||||
use core::fmt;
|
||||
|
||||
@@ -39,7 +43,8 @@ impl fmt::LowerHex for Operand {
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
/// ModRM byte can either target a memory location or some register.
|
||||
/// ModRM byte can either target a [`MemoryIndex`] (location in memory) or some
|
||||
/// [`Register`].
|
||||
pub enum ModRmTarget {
|
||||
Memory(MemoryIndex),
|
||||
Register(Register),
|
||||
@@ -57,6 +62,12 @@ impl std::fmt::Display for ModRmTarget {
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
/// Memory displacements are signed versions of Byte and Word operands.
|
||||
/// Encodes either Byte- or Word-sized operands.
|
||||
/// Generally, a [`Displacement`] is the result of a ModRM byte parse and
|
||||
/// usually really is the signed displacement of a [`MemoryIndex`] for memory
|
||||
/// operations.
|
||||
/// Although, some instructions use this parsed displacement as an unsigned
|
||||
/// pointer, hence the [`Displacement`] will be cast to [`Pointer16`], when this
|
||||
/// is the case.
|
||||
pub enum Displacement {
|
||||
IByte(IByte),
|
||||
IWord(IWord),
|
||||
@@ -133,6 +144,8 @@ impl fmt::Display for MemoryIndex {
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
/// 16-bit pointer for access, usually with a [`SegmentRegister`] as segment
|
||||
/// and [`Pointer16`] as offset.
|
||||
/// Generally, this type only gets constructed in rare scenarios, when the
|
||||
/// [`Displacement`] of ModRM byte is used as a raw pointer.
|
||||
pub struct Pointer16 {
|
||||
pub word: Word,
|
||||
}
|
||||
@@ -152,15 +165,21 @@ impl TryFrom<ModRmTarget> for Pointer16 {
|
||||
Some(disp) => match disp {
|
||||
Displacement::IWord(word) => Ok(Pointer16 { word: word as Word }),
|
||||
_ => {
|
||||
return Err(DisasmError::IllegalOperand("Word expected".into()));
|
||||
return Err(DisasmError::IllegalOperand(
|
||||
"Tried to construct Pointer16 with Byte, when a Word is expected"
|
||||
.into(),
|
||||
));
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
return Err(DisasmError::IllegalOperand("Displacement expected".into()));
|
||||
return Err(DisasmError::IllegalOperand("Tried to construct Pointer16 with Register, when a Displacement was expected".into()));
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
return Err(DisasmError::IllegalOperand("MemoryIndex expected".into()));
|
||||
return Err(DisasmError::IllegalOperand(
|
||||
"Tried to construct Pointer16 with Register, when a MemoryIndex expected"
|
||||
.into(),
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user