ByteMachine is a small educational virtual machine built from scratch, designed to execute custom bytecode programs.
Inspired by projects like "Nand to Tetris," ByteMachine helps students and engineers understand how real CPUs, VMs, and low-level systems work — from memory management to instruction execution — but at a manageable, fun scale!
- Stack-based execution model
- 8 general-purpose registers
- Support for basic arithmetic (
ADD,SUB,MUL,DIV,MOD,POW) - Variable storage and retrieval (
STORE,LOAD) - Simple I/O (
OUTinstruction) - Full custom opcode set with clean extensibility
- Instruction Pointer (IP) tracking and control flow
- Bytecode loaded from
.binfiles - Assembly-to-binary compiler with label support
- Unit tests for each opcode at the
Apply()level
- Write a
.binfile containing raw bytecode instructions. - Load and execute the program using the
byte_machine. - The virtual machine handles stack, registers, and control flow.
- The program halts cleanly on the
HALTinstruction (0xFF).
| Byte | Meaning |
|---|---|
| 0x10 | PUSH |
| 0x02 | 2 |
| 0x10 | PUSH |
| 0x05 | 5 |
| 0x30 | ADD |
| 0xFF | HALT |
src/
cmd/byte_machine/ # CLI entry point (runs compiled .bin programs)
cmd/debugger/ # Optional debugger (WIP)
cmd/bmasm/ # CLI assembler for .bm source
internal/
byte_machine/ # Core VM: memory, stack, IP, execution
machine/ # Machine abstraction
opcodes/ # Opcode logic + decoding
tests/ # Unit tests per opcode
assembler/ # .bm to .bin conversion with label support
utils/ # Helpers
program.bin # Example compiled program
go install github.com/hasanaburayyan/byte-machine/src/cmd/byte_machine@latestgo install github.com/hasanaburayyan/bytewrite/src/cmd/bytewrite@latestInstall the official assembler CLI tool:
go install github.com/hasanaburayyan/byte-machine/src/cmd/bmasm@latestTo assemble a .bm file into a .bin file:
bmasm -i print10.bm -o print10.binTo run the file directly without saving a .bin:
bmasm -i print10.bm --run- If
--runis used,--outis not required. - If
--runis not used,--outis required.
You can write .bm files using readable opcodes and labels. Example:
# Print numbers 1 through 10
PUSH 1
STORE 1
loop:
LOAD 1
PUSH 10
GREATER
JUMP_IF_NOT_ZERO end
LOAD 1
OUT
PUSH 1
ADD
STORE 1
JUMP loop
end:
HALTbmasm -i print10.bm --runbmasm -i print10.bm -o print10.binbyte_machine print10.binIf you want to skip assembly and just run raw bytes, use bytewrite:
bytewrite -b 00010000 00000001 00010011 00000001 00010100 00000001 00010000 00001010 00100100 00010111 00010110 00010100 00000001 00000001 00010000 00000001 00110000 00010011 00000001 00010101 00000100 11111111 | byte_machinebytewrite -b 00010000 00000001 00010011 00000001 00010100 00000001 00010000 01100100 00100100 00010111 00010110 00010100 00000001 00000001 00010000 00000001 00110000 00010011 00000001 00010101 00000100 11111111 | byte_machine- Visual Studio Code debugger (DAP-based)
- Breakpoint support
- Decompiler:
.bin→.bm - Debugger-friendly pseudo-instructions
PRs welcome! Feel free to open issues, contribute docs, or submit test programs. ByteMachine is a learning sandbox — let's make it fun and useful together.
MIT © 2025 Hasan Abu-Rayyan