Solution for Synacor Challenge.
Language used: Python.
In this challenge, your job is to use this architecture spec to create a virtual machine capable of running the included binary. Along the way, you will find codes; submit these to the challenge website to track your progress. Good luck!
- three storage regions
- memory with 15-bit address space storing 16-bit values
- eight registers
- an unbounded stack which holds individual 16-bit values
- all numbers are unsigned integers 0..32767 (15-bit)
- all math is modulo 32768; 32758 + 15 => 5
- each number is stored as a 16-bit little-endian pair (low byte, high byte)
- numbers 0..32767 mean a literal value
- numbers 32768..32775 instead mean registers 0..7
- numbers 32776..65535 are invalid
- programs are loaded into memory starting at address 0
- address 0 is the first 16-bit value, address 1 is the second 16-bit value, etc
- After an operation is executed, the next instruction to read is immediately after the last argument of the current operation. If a jump was performed, the next operation is instead the exact destination of the jump.
- Encountering a register as an operation argument should be taken as reading from the register or setting into the register as appropriate.
Name | Code | Parameters | Notes |
---|---|---|---|
halt | 0 | stop execution and terminate the program | |
set | 1 | a b | set register a to the value of b |
push | 2 | a | push a onto the stack |
pop | 3 | a | remove the top element from the stack and write it into a ; empty stack = error |
eq | 4 | a b c | set a to 1 if b is equal to c ; set it to 0 otherwise |
gt | 5 | a b c | set a to 1 if b is greater than c ; set it to 0 otherwise |
jmp | 6 | a | jump to a |
jt | 7 | a b | if a is nonzero, jump to b |
jf | 8 | a b | if a is zero, jump to b |
add | 9 | a b c | assign into a the sum of b and c (modulo 32768) |
mult | 10 | a b c | store into a the product of b and c (modulo 32768) |
mod | 11 | a b c | store into a the remainder of b divided by c |
and | 12 | a b c | stores into a the bitwise and of b and c |
or | 13 | a b c | stores into a the bitwise or of b and c |
not | 14 | a b | stores 15-bit bitwise inverse of b in a |
rmem | 15 | a b | read memory at address b and write it to a |
wmem | 16 | a b | write the value from b into memory at address a |
call | 17 | a | write the address of the next instruction to the stack and jump to a |
ret | 18 | remove the top element from the stack and jump to it; empty stack = halt | |
out | 19 | a | write the character represented by ascii code a to the terminal |
in | 20 | a | read a character from the terminal and write its ascii code to a ; it can be assumed that once input starts, it will continue until a newline is encountered; this means that you can safely read whole lines from the keyboard and trust that they will be fully read |
noop | 21 | no operation |
Run Virtual Machine by command:
python main.py
-l
: load dump file (excepte file name after-l
option)-d
: display debug information during running program
Example:
python main.py -l save.dump -d
Run decompile script. The script requires dump file to operate on.
python decompile.py -l save.dump
After running the virtual machine, we can play in the text advature hidden in the given program. In the game we can find another puzzles: