A from-scratch implementation of the LC-3 (Little Computer 3) virtual machine. The VM simulates the basic architecture of the LC-3, a teaching-oriented 16-bit computer, including memory, registers, instruction decoding, and execution.
Created by Piyush V and Neha S as part of the Synero Project Summer Challenge.
The VM mimics a basic computer system with:
- 65536 (2^16) memory locations
- 10 registers: 8 general-purpose, 1 program counter (PC), 1 condition register (COND)
- Instruction fetch-decode-execute loop
- Support for arithmetic, memory, control flow, and TRAP routines
Each LC-3 instruction is 16 bits long and executed in a cycle:
- Fetch the instruction from memory at PC
- Decode the opcode and operands
- Execute the instruction
- Update condition flags
- Repeat until HALT
This project was built during our summer break to deepen our understanding of:
- Low-level computer architecture
- Instruction encoding and bit manipulation
- Memory and register management in C
Steps followed:
- Studied the LC-3 ISA and designed the memory/register layout
- Implemented the instruction cycle and opcode handlers
- Added TRAP routines for input/output
- Created sample
.objprograms for testing - Structured the project into modular files and folders
- (Upcoming) GUI visualizer to display memory, registers, and control flow
- GCC or compatible C compiler (MinGW/WSL/MSYS2)
- Terminal (Linux/macOS/WSL/MSYS2 recommended)
# Clone the repository
$ git clone https://github.com/Project-Synero/vm-lc3.git
$ cd vm-lc3
# Compile using Make
$ make
# Run a .obj file
$ ./build/lc3_vm examples/hello.obj
# Exit with HALT or Ctrl+C- Input buffering is disabled to support real-time keyboard input (
GETC/IN). .objfiles are compiled LC-3 machine code (can be generated using PennSim, lc3as, or any LC-3 assembler).
vm-lc3/
├── build/ # Compiled output (lc3_vm.exe)
│ └── lc3_vm.exe
│
├── obj/ # Intermediate .o files during build
│ ├── lc3.o
│ ├── memory.o
│ ├── opcodes.o
│ └── trap.o
│
├── include/ # Header files for all modules
│ ├── lc3.h # Global defines, register setup, enums
│ ├── memory.h
│ ├── opcodes.h
│ └── trap.h
│
├── src/ # Source code for the VM
│ ├── lc3.c # Main VM driver and loop
│ ├── memory.c # Memory functions
│ ├── opcodes.c # Instruction handlers
│ └── trap.c # TRAP implementations
│
├── examples/ # .obj programs for testing
│ ├── hello.obj #Folder structure could vary here.
│ └── lc3-vm_toRUN.obj
│
├── lc3-vm_toRUN.asm # Sample LC-3 assembly source
├── Makefile # Build script
├── .gitignore # Git exclusions
├── projNotes.md # Development notes
└── README.md # Project overview- GUI debugger/visualizer (registers, memory, execution steps)
- Optional support for loading custom
.asmand assembling - Step-by-step execution and breakpoints
- Enhanced terminal interaction and state logging
Special thanks to Justin Meiners for the original guide that inspired this project.