gnu / binutils-gdb / 2786ef85faf16c13029548832c4e4b025bf2624c / . / sim / example-synacor / README.arch-spec

== 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: jTTockJlJiOC | |

- 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 |