A two-pass assembler and emulator implementation in C++ for a custom instruction set architecture.
This project consists of two main components:
- Assembler (
assembler.cpp): Converts assembly language source code into machine code - Emulator (
emulator.cpp): Executes machine code with comprehensive debugging features
- Two-pass assembly process for proper label resolution
- Comprehensive error detection and reporting
- Support for multiple number formats (decimal, octal, hexadecimal)
- Label validation and duplicate detection
- Comment handling (because even assemblers need to understand your witty remarks)
- Generates listing files and machine code output
- Full instruction set support with 19 different operations
- Memory management with 2^24 addressable locations
- Register tracking (PC, SP, Accumulator, Register B)
- Multiple trace modes for debugging
- Infinite loop detection
- Segmentation fault protection
g++ -o assembler assembler.cpp
g++ -o emulator emulator.cpp./assembler source_file.asmGenerates:
source_file.o- Machine code (binary)source_file.lst- Listing filesource_file.log- Error/warning log
./emulator [command] program.oAvailable commands:
-trace- Show instruction execution trace-read- Show memory read operations-write- Show memory write operations-before- Memory dump before execution-after- Memory dump after execution-wipe- Reset all registers-isa- Display instruction set
| Opcode | Mnemonic | Operand | Description |
|---|---|---|---|
| 0 | ldc |
value | Load constant into accumulator |
| 1 | adc |
value | Add constant to accumulator |
| 2 | ldl |
offset | Load from local memory |
| 3 | stl |
offset | Store to local memory |
| 4 | ldnl |
offset | Load from non-local memory |
| 5 | stnl |
offset | Store to non-local memory |
| 6 | add |
- | Add register B to accumulator |
| 7 | sub |
- | Subtract accumulator from register B |
| 8 | shl |
- | Shift register B left by accumulator |
| 9 | shr |
- | Shift register B right by accumulator |
| 10 | adj |
value | Adjust stack pointer |
| 11 | a2sp |
- | Move accumulator to stack pointer |
| 12 | sp2a |
- | Move stack pointer to accumulator |
| 13 | call |
offset | Call subroutine |
| 14 | return |
- | Return from subroutine |
| 15 | brz |
offset | Branch if accumulator is zero |
| 16 | brlz |
offset | Branch if accumulator is negative |
| 17 | br |
offset | Unconditional branch |
| 18 | HALT |
- | Halt execution |
| - | SET |
value | Set variable value |
The assembler provides comprehensive error checking:
- Invalid label names
- Missing or extra operands
- Duplicate label definitions
- Undeclared label usage
- Invalid operation names
- Number format validation
start: ldc 10 ; Load constant 10
adc 5 ; Add 5
stl 0 ; Store result
brz end ; Branch if zero
br start ; Loop back
end: HALT ; Stop execution./assembler example.asm
./emulator -trace example.oThe codebase features detailed comments and follows a clean structure with:
- Comprehensive input validation
- Clear separation of concerns between assembler and emulator
- Robust error handling with helpful messages
- Efficient two-pass assembly algorithm
- C++ compiler with C++11 support
- Standard library support for file I/O and string manipulation
Open source - feel free to use and modify as needed.