From 87a815ac27bd257b7c8bd67816119b8af1d92e4e Mon Sep 17 00:00:00 2001 From: Dimitri Lozeve Date: Wed, 13 Jan 2021 09:16:21 +0100 Subject: [PATCH] Initial commit: implementation of the virtual machine --- .gitignore | 4 ++ Makefile | 11 ++++ README.org | 10 ++++ arch-spec | 79 +++++++++++++++++++++++++ challenge.bin | Bin 0 -> 60100 bytes src/vm.c | 158 ++++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 262 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 README.org create mode 100644 arch-spec create mode 100644 challenge.bin create mode 100644 src/vm.c diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..70b6a74 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +*\~ +.gdb_history +vm +synacor-challenge.tgz diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..a31b575 --- /dev/null +++ b/Makefile @@ -0,0 +1,11 @@ +CC = gcc +CFLAGS = -Wall -Werror -pedantic -O3 + +.PHONY: all +all: vm + +vm: src/vm.c + $(CC) $^ -o $@ $(CFLAGS) + +clean: + rm -f vm diff --git a/README.org b/README.org new file mode 100644 index 0000000..2fa75d9 --- /dev/null +++ b/README.org @@ -0,0 +1,10 @@ +* Synacor Challenge + +Solutions to the [[https://challenge.synacor.com/][Synacor Challenge]] + +The virtual machine is implemented in [[src/vm.c]]. Compile it with =make= +and run it on the challenge program: + +#+begin_src sh + ./vm challenge.bin +#+end_src diff --git a/arch-spec b/arch-spec new file mode 100644 index 0000000..0ce07d6 --- /dev/null +++ b/arch-spec @@ -0,0 +1,79 @@ +== 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: SJIDydAvKFEH +- 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 to the value of +push: 2 a + push onto the stack +pop: 3 a + remove the top element from the stack and write it into ; empty stack = error +eq: 4 a b c + set to 1 if is equal to ; set it to 0 otherwise +gt: 5 a b c + set to 1 if is greater than ; set it to 0 otherwise +jmp: 6 a + jump to +jt: 7 a b + if is nonzero, jump to +jf: 8 a b + if is zero, jump to +add: 9 a b c + assign into the sum of and (modulo 32768) +mult: 10 a b c + store into the product of and (modulo 32768) +mod: 11 a b c + store into the remainder of divided by +and: 12 a b c + stores into the bitwise and of and +or: 13 a b c + stores into the bitwise or of and +not: 14 a b + stores 15-bit bitwise inverse of in +rmem: 15 a b + read memory at address and write it to +wmem: 16 a b + write the value from into memory at address +call: 17 a + write the address of the next instruction to the stack and jump to +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 to the terminal +in: 20 a + read a character from the terminal and write its ascii code to ; 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 diff --git a/challenge.bin b/challenge.bin new file mode 100644 index 0000000000000000000000000000000000000000..642b1ce7507b0d0f6318282275e1e04b630c82c8 GIT binary patch literal 60100 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 literal 0 HcmV?d00001 diff --git a/src/vm.c b/src/vm.c new file mode 100644 index 0000000..9560df4 --- /dev/null +++ b/src/vm.c @@ -0,0 +1,158 @@ +#include +#include +#include + +#define MEM_SIZE (2 << 15) +#define STACK_SIZE 10000 + +#define val(r) ((r >> 15) ? reg[r & 7] : r) + +size_t read_program(uint16_t mem[static 1], char *filename) { + FILE *fp = fopen(filename, "rb"); + if (fp == NULL) { + fprintf(stderr, "Could not open file %s\n", filename); + exit(EXIT_FAILURE); + } + + int c = 0; + size_t n = -1; + int i = 0; + while ((c = fgetc(fp)) != EOF) { + if (i == 0) { + n++; + mem[n] = c; + } else { + mem[n] = (c << 8) | mem[n]; + } + i = (i + 1) % 2; + } + fclose(fp); + + return n + 1; +} + +void run(uint16_t mem[static 1]) { + uint16_t reg[8] = {0}; // registers + uint16_t stack[STACK_SIZE] = {0}; // stack + size_t stack_top = 0; + + size_t pc = 0; + for (;;) { + uint16_t opcode = mem[pc]; + uint16_t a = mem[pc + 1]; + uint16_t b = mem[pc + 2]; + uint16_t c = mem[pc + 3]; + + switch (opcode) { + case 0: + return; + case 1: + reg[a & 7] = val(b); + pc += 3; + break; + case 2: + stack[stack_top] = val(a); + stack_top++; + pc += 2; + break; + case 3: + stack_top--; + reg[a & 7] = stack[stack_top]; + pc += 2; + break; + case 4: + reg[a & 7] = val(b) == val(c); + pc += 4; + break; + case 5: + reg[a & 7] = val(b) > val(c); + pc += 4; + break; + case 6: + pc = val(a); + break; + case 7: + if (val(a)) { + pc = val(b); + } else { + pc += 3; + } + break; + case 8: + if (!val(a)) { + pc = val(b); + } else { + pc += 3; + } + break; + case 9: + reg[a & 7] = (val(b) + val(c)) % 32768; + pc += 4; + break; + case 10: + reg[a & 7] = (val(b) * val(c)) % 32768; + pc += 4; + break; + case 11: + reg[a & 7] = val(b) % val(c); + pc += 4; + break; + case 12: + reg[a & 7] = val(b) & val(c); + pc += 4; + break; + case 13: + reg[a & 7] = val(b) | val(c); + pc += 4; + break; + case 14: + reg[a & 7] = ~val(b) & 0x7FFF; + pc += 3; + break; + case 15: + reg[a & 7] = mem[val(b)]; + pc += 3; + break; + case 16: + mem[val(a)] = val(b); + pc += 3; + break; + case 17: + stack[stack_top] = pc + 2; + stack_top++; + pc = val(a); + break; + case 18: + if (!stack_top) { + return; + } + stack_top--; + pc = stack[stack_top]; + break; + case 19: + putchar(val(a)); + pc += 2; + break; + case 20: + reg[a & 7] = getchar(); + pc += 2; + break; + case 21: + pc++; + break; + } + } +} + +int main(int argc, char *argv[]) { + if (argc < 2) { + printf("Usage: %s \n", argv[0]); + return EXIT_SUCCESS; + } + + uint16_t mem[MEM_SIZE] = {0}; + read_program(mem, argv[1]); + run(mem); + + return EXIT_SUCCESS; +}