![]() |
|
[C] Synacor Challenge #1 - Printable Version +- Sinisterly (https://sinister.ly) +-- Forum: Coding (https://sinister.ly/Forum-Coding) +--- Forum: C, C++, & Obj-C (https://sinister.ly/Forum-C-C-Obj-C) +--- Thread: [C] Synacor Challenge #1 (/Thread-C-Synacor-Challenge-1--72828) |
[C] Synacor Challenge #1 - bitm0de - 09-13-2015 https://challenge.synacor.com Woo, finally got the challenge key by writing a *virtual machine* for the given architecture format: Code: == Synacor Challenge ==
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!
== architecture ==
- 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
== binary format ==
- 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
== execution ==
- 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.
== hints ==
- Start with operations 0, 19, and 21.
- Here's a code for the challenge website: JRkeutHfWwcz
- The program "9,32768,32769,4,19,32768" occupies six memory addresses and should:
- Store into register 0 the sum of 4 and the value contained in register 1.
- Output to the terminal the character with the ascii code contained in register 0.
== opcode listing ==
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![]() ![]() *Currently reviewing my code to see why that is crashing on the bin file doing it's so called 'self-test'. RE: [C] Synacor Challenge #1 - bitm0de - 09-14-2015 Btw, fixed the issue with the crash... Fix is posted to my development branch on the github repo: https://github.com/bitm0de/SynacorChallenge/tree/development (which I've now merged to my master branch) "Executing self-test..." stage makes a jmp call to perhaps some random memory in the virtual address space where an invalid opcode instruction was found (4864), which is way larger than any valid opcode. I assume that any opcode was valid in my initial code and used this to index the function pointer which correlates to the proper instruction to execute... The issue was circumvented this with a VALID_OPCODE macro which tests the read opcode returned from the fread( ) call for the 16-bit value, as a pre-condition for making the callback to the appropriate function pointer from my function pointer table. in reality, it should have been a flaw with the imaginary compiler that created the *.bin file for having code that would allow such to occur, but I added the macro anyways just to make sure that my program runs without crashing and terminates successfully I could have simulated my own runtime exception and *thrown* it just to emulate awareness that the program was not behaving properly...
RE: [C] Synacor Challenge #1 - Toph - 01-07-2016 I'd like to think im getting a handle on C, i've started playing around with GTK and Curses but this is so far beyond me its scary. :/ Wish i was able to do things like this |