procem 0.1.0

A simple library for processor emulation
Documentation
  • Coverage
  • 68.82%
    64 out of 93 items documented2 out of 57 items with examples
  • Size
  • Source code size: 44.08 kB This is the summed size of all the files inside the crates.io package for this release.
  • Documentation size: 2.74 MB This is the summed size of all files generated by rustdoc for all configured targets
  • Ø build duration
  • this release: 14s Average build duration of successful builds.
  • all releases: 14s Average build duration of successful builds in releases after 2024-10-23.
  • Links
  • Repository
  • crates.io
  • Dependencies
  • Versions
  • Owners
  • A1cey

procem

procem is a toy Rust library that provides a flexible processor emulator, loosely inspired by the ARM architecture. It allows you to define and execute custom instruction sets, manage registers, flags, and stack memory, and run assembly-like programs.

Features

  • Processor: Emulates a processor with general-purpose registers, program counter, stack pointer, flags, and a stack.
  • Program: Container for a sequence of instructions to be executed by the processor.
  • Instruction: Trait for defining custom instruction sets. A default instruction set is implemented in the procem_default crate.
  • Registers: General-purpose registers, program counter, stack pointer, and flags.
  • Stack: Fixed-size stack for processor operations.
  • Word: Trait for word-size types. Word is already implemented for all signed integer types.

Customization

You can implement your own instruction set by implementing the Instruction trait, and support custom word types by implementing the Word trait. Alternatively, you can use the default instruction set and word types.

Example: Using procem_default

use procem::{processor::Processor, register::Register, word::I32};
use procem_default::assemble;

// Assemble a program from asm
let program = assemble::<I32>(
    "
    mov R0, #10
    mov R1, #5
    add R0, R1
    sub R0, #3
    mul R0, #2
    div R0, #4
    "
).unwrap();

// Create a processor and run the program
const STACK_SIZE: usize = 1024;

let mut processor = Processor::<STACK_SIZE, _, _, _>::builder()
    .with_program(&program)
    .build();

let _ = processor.run_program();

// Inspect register values
assert_eq!(processor.registers.get_reg(Register::R0), 6.into());

Example: Custom Instruction Set

use procem::{instruction::Instruction,processor::Processor, program::Program, register::Register,  word::Word};

// Define your own word type
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
struct MyWord(i64);

impl Word for MyWord {
    // Implement required methods...
}

// Define your own instruction set
enum MyInstruction {
    Mov { to: Register, from: MyWord },
    // Add more instructions...
}

impl Instruction<MyWord> for MyInstruction {
    // Implement required methods...
}

// Create a program and processor using your custom types
let program = Program::new(vec![
    MyInstruction::Mov { to: Register::R0, from: MyWord(42) },
    // Add more instructions...
]);

let mut processor = Processor::<128, _, _, _>::builder()
    .with_program(&program)
    .build();