FANDOM


The decompiler is, at heart, flexible. It can do the same stuff on most CPUs, by relegating the odd stuff to a OP_CPUFUNCTION. Now, about Cpu Functions. Say we have the x86 opcode REPZ. This opcode takes in as arguments the registers esi and edi. When we get to the point with the REPZ opcode, all we have to do is get-value on esi and edi, and the contents of those registers will be exactly perfect for REPZ.

For these examples, we'll use x86 opcodes for illustration.

Operand Explanation
OP_ARITHMETIC xor eax,eax
OP_COMPARE Unsure
OP_CALL call dword ptr [0042C228h]
OP_JUMP jmp 0040AB2Bh
OP_COMPAREBRANCH jnz 0040AA63h
OP_SIGNED A Flag
OP_PUSH push ebp
OP_BRANCH Unused
OP_RET ret
OP_POP pop ebp
OP_MOVE_VALUE mov ebp,esp
OP_LEA lea edx,[ecx+eax+00000144h] (see OP_MOVE_ADDRESS)
OP_REPNZ CPU Function
OP_SCASB CPU Function
OP_NEG Negate (Unused)
OP_MOVSD ? Unused
OP_MOVE_ADDRESS lea edx,[ecx+eax+00000144h]
OP_AFFECTS_ZF Flag
OP_UNKNOWN Unknown
OP_AFFECTS_FPUSW Flag
OP_CPUFUNCTION Important: All opcodes not fitting the above, go here
OP_COMPAREANDBRANCH Not implemented

Now, an operand definition in the opcode-data list has this spec:

    ;name, (cpu-flags forced-operands num_opds opd1_changes opd2_changes arithop flags-read-from flags-affected source-type)

To illustrate, here is one:

("not" . ((logior OP_ARITHMETIC OP_AFFECTS_ZF) () 1 T NIL "!" () (list "Z")))

This is the following:

name = "not"

CPU flags = OP_ARITHMETIC OP_AFFECTS_ZF

forced-operands = None

num_opds = 1

opd1_changes = T

opd2_changes = NIL

arithop - "!"

flags-read-from = None

flags-affected = Z (the zero flag, which is affected by a 'not' operation)

source-type = N/A