public CreateMemoryAccess ( Reko.Arch.X86.X86Instruction instr, Reko.Arch.X86.MemoryOperand mem, DataType dt, Reko.Arch.X86.X86State state ) : Expression | ||
instr | Reko.Arch.X86.X86Instruction | |
mem | Reko.Arch.X86.MemoryOperand | |
dt | DataType | |
state | Reko.Arch.X86.X86State | |
Résultat | Expression |
/// <summary> /// Generates assignments, with special-case logic to break up /// instructions where the destination is a memory address. /// </summary> /// <remarks> /// The special case breaks instructions that write to memory /// like this: /// <code> /// op [memaddr], reg /// </code> /// into into the equivalent: /// <code> /// tmp := [memaddr] op reg; /// store([memaddr], tmp); /// </code> /// This makes analysis easier for the subsequent phases of the /// decompiler. /// </remarks> public void EmitCopy(MachineOperand opDst, Expression src, CopyFlags flags) { Expression dst = SrcOp(opDst); if (dst is Identifier idDst) { AssignToRegister(idDst, src); } else { var tmp = binder.CreateTemporary(opDst.Width); m.Assign(tmp, src); var ea = orw.CreateMemoryAccess(instrCur, (MemoryOperand)opDst, state); m.Assign(ea, tmp); dst = tmp; } if ((flags & CopyFlags.EmitCc) != 0) { EmitCcInstr(dst, X86Instruction.DefCc(instrCur.Mnemonic)); } if ((flags & CopyFlags.SetCfIf0) != 0) { m.Assign(orw.FlagGroup(FlagM.CF), m.Eq0(dst)); } }
/// <summary> /// Breaks up very common case of x86: /// <code> /// op [memaddr], reg /// </code> /// into the equivalent: /// <code> /// tmp := [memaddr] op reg; /// store([memaddr], tmp); /// </code> /// </summary> /// <param name="opDst"></param> /// <param name="src"></param> /// <param name="forceBreak">if true, forcibly splits the assignments in two if the destination is a memory store.</param> /// <returns>Returns the destination of the copy.</returns> public void EmitCopy(MachineOperand opDst, Expression src, CopyFlags flags) { Expression dst = SrcOp(opDst); Identifier idDst = dst as Identifier; if (idDst != null || (flags & CopyFlags.ForceBreak) == 0) { emitter.Assign(dst, src); } else { Identifier tmp = frame.CreateTemporary(opDst.Width); emitter.Assign(tmp, src); var ea = orw.CreateMemoryAccess(instrCur, (MemoryOperand)opDst, state); emitter.Assign(ea, tmp); dst = tmp; } if ((flags & CopyFlags.EmitCc) != 0) { EmitCcInstr(dst, X86Instruction.DefCc(instrCur.code)); } if ((flags & CopyFlags.SetCfIf0) != 0) { emitter.Assign(orw.FlagGroup(FlagM.CF), emitter.Eq0(dst)); } }