Skip to content
This repository has been archived by the owner on Aug 30, 2024. It is now read-only.

Commit

Permalink
feat: neg, better formatting
Browse files Browse the repository at this point in the history
  • Loading branch information
julio4 committed May 16, 2024
1 parent 3b3bc7b commit a59b593
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 14 deletions.
4 changes: 4 additions & 0 deletions src/disassembler/instruction/instruction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ pub enum IR {
Pop { dest: Operand },
Ret,
In { dest: Operand, src: Operand },
Neg { dest: Operand },
Undefined,
}

impl std::fmt::Display for IR {
Expand Down Expand Up @@ -111,6 +113,8 @@ impl std::fmt::Display for IR {
IR::Pop { dest } => write!(f, "pop {}", dest),
IR::Ret => write!(f, "ret"),
IR::In { dest, src } => write!(f, "in {}, {}", dest, src),
IR::Neg { dest } => write!(f, "neg {}", dest),
IR::Undefined => write!(f, "(undefined)"),
}
}
}
Expand Down
19 changes: 16 additions & 3 deletions src/disassembler/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -291,9 +291,7 @@ pub fn parse_instruction(bytes: &[u8], ip: usize) -> Result<(Instruction, usize)
let bits = (bytes[1] & 0b00111000) >> 3;
match bits {
// NEG
0b011 => {
unimplemented!()
}
0b011 => Ok((IR::Neg { dest: rm }, bytes_consumed + 1)),
// MUL
0b100 => {
unimplemented!()
Expand Down Expand Up @@ -1201,6 +1199,21 @@ mod tests {
assert_eq!(parse_instruction(&bytes, 0), Ok(expected_result));
}

#[test]
fn test_parse_instruction_neg() {
let bytes = [0xf7, 0xda];
let expected_result = (
Instruction::new(
IR::Neg {
dest: Operand::Register(Register::DX),
},
bytes.to_vec(),
),
bytes.len(),
);
assert_eq!(parse_instruction(&bytes, 0), Ok(expected_result));
}

#[test]
fn test_parse_instruction_invalid_opcode() {
// Test parsing an invalid opcode
Expand Down
19 changes: 14 additions & 5 deletions src/disassembler/program.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::{
disassembler::{error::ParseError, parser, Instruction},
disassembler::{error::ParseError, parser, Instruction, IR},
text_segment::TextSegment,
};

Expand All @@ -13,13 +13,22 @@ impl Program {
Program { instructions }
}

pub fn from_text_segment(segment: TextSegment) -> Result<Program, ParseError> {
pub fn from_text_segment(segment: TextSegment) -> Program {
let mut instructions = Vec::new();
let mut text = segment.text.as_slice();

let mut ip = 0;
while !text.is_empty() {
let (instruction, bytes_consumed) = parser::parse_instruction(text, ip)?;
let (instruction, bytes_consumed) = match parser::parse_instruction(text, ip) {
Ok((instruction, bytes_consumed)) => (instruction, bytes_consumed),
Err(ParseError::UnexpectedEOF) => {
(Instruction::new(IR::Undefined, text.to_vec()), text.len())
}
Err(err) => {
eprintln!("Error: {}", err);
break;
}
};
// DEBUG:
println!("{:04x}: {}", ip, instruction);
ip += bytes_consumed;
Expand All @@ -28,7 +37,7 @@ impl Program {
text = &text[bytes_consumed..];
}

Ok(Program::new(instructions))
Program::new(instructions)
}
}

Expand All @@ -53,7 +62,7 @@ mod tests {
let text_segment = TextSegment {
text: vec![0xbb, 0xFF, 0x00],
};
let program = Program::from_text_segment(text_segment).unwrap();
let program = Program::from_text_segment(text_segment);
assert_eq!(program.instructions.len(), 1);
assert_eq!(
program.instructions[0],
Expand Down
7 changes: 1 addition & 6 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,5 @@ fn main() {
let program = Program::from_text_segment(text_segment);

// Print program (same output as mmvm -d)
match program {
Ok(p) => println!("{}", p),
Err(e) => {
println!("Error parsing program: {}", e);
}
}
print!("{}", program);
}

0 comments on commit a59b593

Please sign in to comment.