A rewriter is a class that transforms machine language instructions for a particular processor architecture into extremely simple [Register Transfer Language] (RTL) instructions. Many processor instructions have multiple side effects, and these need to be modeled accurately for the Decompiler to be able to reconstruct a reasonably faithful source version.
The rewriter for a particular architecture is an implementation of IEnumerable<RtlInstructionCluster>
. That is, it can be viewed as the source of a stream of RtlInstructionCluster
s. Each RtlInstructionCluster
corresponds to a single machine code instruction, and consists of the address of the instruction, its size (remember that many processor architectures have variable-sized instructions -- see VAX, 8080, 68000, x86 and ARM Thumb for examples), and one or more RtlInstruction
s which, when executed, model the behavior of the machine instruction.
As an example, the x86 Rewriter will take the following x86 machine instruction
add eax,[ebx+esi*4+0x204]
and rewrite it into:
eax = eax + Mem0[ebx + esi * 4 + 0x0204:word32] SZCO = cond(eax)
As you can see, it has translated the machine code instruction into its RTL equivalent. First, the main effect of the instruction is to add a memory value to the current value of the eax
register. The effective address of the memory instruction has been transformed into an RTL expression. Then the effective address is used inside of a MemoryAccess
expression, which also has been given a word32
as the size of the memory access.
However, the x86 add
instruction also affects the condition codes. Therefore, the rewriter must also emit a statement to model this. The second RTL instruction in the cluster assigns the S
, Z
, C
, and O
flags (sign, zero, carry, and overflow, respectively) with the result of applying the pseudo-function cond
to the result of the addition operation. The [condition code elimination] stage of the decompiler will replace processor flag references and cond
applications with higher-level constructs.