Skip to content

Latest commit

 

History

History
93 lines (47 loc) · 3.69 KB

File metadata and controls

93 lines (47 loc) · 3.69 KB

Appedix A - Opcodes

Opcode 0x05 - A bit confusing, but since the argument is always zero in practice, it pushes 32.

0x05

Opcode 0x0C - Stop emulation. Since CALL literally calls the emulator loop again, this can return from a CALL as well. This also removes from an std::list of what I later learned were sort of like stack frames. They contain a reference to some offset from the stack so that you can load and store variables. This instruction also, in practice, always takes an argument of negative the number of arguments a subroutine has, but it doesn't affect execution.

0x0C

Opcode 0x12 - Call to subroutine. Literally causes the host to call the emulator again. Includes a bit of pointless arithmetic to confuse a reverse engineer.

0x12

Opcode 0x13 - Push string literal. The parsing is too long for an image, but it's still relatively straightforward. It reads <argument> dwords, converts the dword array to a char array, puts it in a vector, puts the vector on the stack, and returns the number of dwords read.

Opcode 0x14 - Compare whether the first element on the stack is greater or equal to the second element.

0x14

Opcode 0x17 - Add two elements on the stack. Implementation already described.

Opcode 0x1B - Load variable from the stack, using an offset from the stack frame if positive, or from the base of the stack if negative.

0x1B

Opcode 0x24 - The implementation was very confusing for me, but based on the context, using the disassembler I was building simultaneously, I guessed that it stored a variable from the top of the stack to some offset from the stack frame, and I seemed to have been correct.

0x24 Disassembly

0x24

Opcode 0x2C - Create a new stack frame. This implementation was also very confusing for me, so I guessed, but this also seems to be correct.

0x2C

Opcode 0x3A - Removes a number of elements from the stack.

0x3A

Opcode 0x3B - Boolean AND. Implementation already described.

0x43 - Push literal to stack. Also has useless arithmetic going on.

0x43

0x44 - Push literal to stack, just like 0x43. In practice, it seems to be used to push return values to the stack at the end of subroutines, but it does the same thing.

0x4A - Multiply.

0x4A

0x56 - Divide.

0x56

0x5C - Modulo.

0x5C

0x63 - Subtract.

0x63

0x69 - Compare if equal, with more multiplication involved to confuse.

0x69

0x71 - Compare if lesser.

0x71

0x73 - Branch of zero, and get floats involved to confuse. Argument is relative to PC after instruction executes.

0x73

0x74 - Load pointer of element.

0x74

0x75 - Compare if zero.

0x75

0x86 - Branch. Argument is relative to PC after instruction executes.

0x86

0x89 - System call. This calls into a predefined ser of x86 code somehow. Its implementation is complicated, and in practice, I just followed its execution to figure out what syscall numbers went to where.

This left me with a table of all the opcodes I'd need to know:

Opcode Table