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-loption)-d: display debug information during running program
Example:
python main.py -l save.dump -dRun decompile script. The script requires dump file to operate on.
python decompile.py -l save.dumpAfter running the virtual machine, we can play in the text advature hidden in the given program. In the game we can find another puzzles: