예제 #1
0
        /*
         * the C0 bit becomes the CF (carry) flag, 
 the C2 bit becomes the PF(parity) flag, and 
 the C3 bit becomes the ZF (zero) flag. 
         */
        //  >              0
        //  <              1
        //  =             40
        //  inordered     45

        public FstswChainMatcher(X86Instruction[] instrs, OperandRewriter orw)
        {
            this.instrs = instrs;
            this.orw = orw;
            this.zappedInstructions = new Dictionary<int, Opcode>();
            this.rewritten = new List<Instruction>();
        }
예제 #2
0
		public void Setup()
		{
            program = new Program();
            program.Image = new LoadedImage(Address.Ptr32(0x10000), new byte[4]);
            var procAddress = Address.Ptr32(0x10000000);
            instr = new X86Instruction(Opcode.nop, PrimitiveType.Word32, PrimitiveType.Word32)
            {
                Address = procAddress,
            };
            proc = Procedure.Create(procAddress, arch.CreateFrame());
			state = (X86State) arch.CreateProcessorState();
			orw = new OperandRewriter32(arch, proc.Frame, new FakeRewriterHost(program));
		}
예제 #3
0
		public void Setup()
		{
            var mem = new MemoryArea(Address.Ptr32(0x10000), new byte[4]);
            program = new Program
            {
                SegmentMap = new SegmentMap(
                    mem.BaseAddress,
                    new ImageSegment(".text", mem, AccessMode.ReadExecute))
            };
            var procAddress = Address.Ptr32(0x10000000);
            instr = new X86Instruction(Opcode.nop, PrimitiveType.Word32, PrimitiveType.Word32)
            {
                Address = procAddress,
            };
            proc = Procedure.Create(procAddress, arch.CreateFrame());
			state = (X86State) arch.CreateProcessorState();
			orw = new OperandRewriter32(arch, new ExpressionEmitter(), proc.Frame, new FakeRewriterHost(program));
		}
예제 #4
0
        public void Setup()
        {
            arch = new IntelArchitecture(ProcessorMode.Real);
            var image = new LoadedImage(Address.Ptr32(0x10000), new byte[4]);
            var prog = new Program(
                image,
                image.CreateImageMap(),
                arch,
                null);
            var procAddress = Address.Ptr32(0x10000000);
            instr = new X86Instruction(Opcode.nop, PrimitiveType.Word16, PrimitiveType.Word16)
            {
                Address = procAddress,
            };

            proc = Procedure.Create(procAddress, arch.CreateFrame());
            orw = new OperandRewriter16(arch, proc.Frame, new FakeRewriterHost(prog));
            state = (X86State)arch.CreateProcessorState();
        }
예제 #5
0
 public Expression Transform(X86Instruction instr, MachineOperand op, PrimitiveType opWidth, X86State state)
 {
     var reg = op as RegisterOperand;
     if (reg != null)
         return AluRegister(reg);
     var mem = op as MemoryOperand;
     if (mem != null)
         return CreateMemoryAccess(instr, mem, opWidth, state);
     var imm = op as ImmediateOperand;
     if (imm != null)
         return CreateConstant(imm, opWidth);
     var fpu = op as FpuOperand;
     if (fpu != null)
         return FpuRegister(fpu.StNumber, state);
     var addr = op as AddressOperand;
     if (addr != null)
         return addr.Address;
     throw new NotImplementedException(string.Format("Operand {0}", op));
 }
예제 #6
0
		public void Setup()
		{
			arch = new X86ArchitectureReal();
            var mem = new MemoryArea(Address.Ptr32(0x10000), new byte[4]);
			var prog = new Program(
                new SegmentMap(
                    mem.BaseAddress,
                    new ImageSegment(
                        "code", mem, AccessMode.ReadWriteExecute)),
                arch,
                new DefaultPlatform(null, arch));
			var procAddress = Address.Ptr32(0x10000000);
            instr = new X86Instruction(Opcode.nop, PrimitiveType.Word16, PrimitiveType.Word16)
            {
                Address = procAddress,
            };

            proc = Procedure.Create(procAddress, arch.CreateFrame());
			orw = new OperandRewriter16(arch, proc.Frame, new FakeRewriterHost(prog));
            state = (X86State)arch.CreateProcessorState();
        }
예제 #7
0
 private string DumpInstr(X86Instruction instr)
 {
     return($"{instr.Address} XX {instr.ToString().ToUpper()}");
 }
예제 #8
0
        public Expression CreateMemoryAccess(X86Instruction instr, MemoryOperand mem, DataType dt, X86State state)
        {
            var exp = ImportedProcedure(instr.Address, mem.Width, mem);
            if (exp != null)
                return new ProcedureConstant(arch.PointerType, exp);

            Expression expr = EffectiveAddressExpression(instr, mem, state);
            if (IsSegmentedAccessRequired ||
                (mem.DefaultSegment != Registers.ds && mem.DefaultSegment != Registers.ss))
            {
                Expression seg = ReplaceCodeSegment(mem.DefaultSegment, state);
                if (seg == null)
                    seg = AluRegister(mem.DefaultSegment);
                return new SegmentedAccess(MemoryIdentifier.GlobalMemory, seg, expr, dt);
            }
            else
            {
                return new MemoryAccess(MemoryIdentifier.GlobalMemory, expr, dt);
            }
        }
예제 #9
0
        /// <summary>
        /// Iterator that yields one RtlIntructionCluster for each x86 instruction.
        /// </summary>
        /// <returns></returns>
        public IEnumerator <RtlInstructionCluster> GetEnumerator()
        {
            while (dasm.MoveNext())
            {
                instrCur  = dasm.Current;
                ric       = new RtlInstructionCluster(instrCur.Address, instrCur.Length);
                ric.Class = RtlClass.Linear;
                emitter   = new RtlEmitter(ric.Instructions);
                orw       = arch.ProcessorMode.CreateOperandRewriter(arch, frame, host);
                switch (instrCur.code)
                {
                default:
                    throw new AddressCorrelatedException(
                              instrCur.Address,
                              "Rewriting x86 opcode '{0}' is not supported yet.",
                              instrCur.code);

                case Opcode.illegal: ric.Class = 0; emitter.Invalid(); break;

                case Opcode.aaa: RewriteAaa(); break;

                case Opcode.aad: RewriteAad(); break;

                case Opcode.aam: RewriteAam(); break;

                case Opcode.aas: RewriteAas(); break;

                case Opcode.adc: RewriteAdcSbb(BinaryOperator.IAdd); break;

                case Opcode.add: RewriteAddSub(BinaryOperator.IAdd); break;

                case Opcode.and: RewriteLogical(BinaryOperator.And); break;

                case Opcode.arpl: RewriteArpl(); break;

                case Opcode.bound: RewriteBound(); break;

                case Opcode.bsr: RewriteBsr(); break;

                case Opcode.bswap: RewriteBswap(); break;

                case Opcode.bt: RewriteBt(); break;

                case Opcode.btr: RewriteBtr(); break;

                case Opcode.bts: RewriteBts(); break;

                case Opcode.call: RewriteCall(instrCur.op1, instrCur.op1.Width); break;

                case Opcode.cbw: RewriteCbw(); break;

                case Opcode.clc: RewriteSetFlag(FlagM.CF, Constant.False()); break;

                case Opcode.cld: RewriteSetFlag(FlagM.DF, Constant.False()); break;

                case Opcode.cli: RewriteCli(); break;

                case Opcode.cmc: emitter.Assign(orw.FlagGroup(FlagM.CF), emitter.Not(orw.FlagGroup(FlagM.CF))); break;

                case Opcode.cmova: RewriteConditionalMove(ConditionCode.UGT, instrCur.op1, instrCur.op2); break;

                case Opcode.cmovbe: RewriteConditionalMove(ConditionCode.ULE, instrCur.op1, instrCur.op2); break;

                case Opcode.cmovc: RewriteConditionalMove(ConditionCode.ULT, instrCur.op1, instrCur.op2); break;

                case Opcode.cmovge: RewriteConditionalMove(ConditionCode.GE, instrCur.op1, instrCur.op2); break;

                case Opcode.cmovg: RewriteConditionalMove(ConditionCode.GT, instrCur.op1, instrCur.op2); break;

                case Opcode.cmovl: RewriteConditionalMove(ConditionCode.LT, instrCur.op1, instrCur.op2); break;

                case Opcode.cmovle: RewriteConditionalMove(ConditionCode.LE, instrCur.op1, instrCur.op2); break;

                case Opcode.cmovnc: RewriteConditionalMove(ConditionCode.UGE, instrCur.op1, instrCur.op2); break;

                case Opcode.cmovno: RewriteConditionalMove(ConditionCode.NO, instrCur.op1, instrCur.op2); break;

                case Opcode.cmovns: RewriteConditionalMove(ConditionCode.NS, instrCur.op1, instrCur.op2); break;

                case Opcode.cmovnz: RewriteConditionalMove(ConditionCode.NE, instrCur.op1, instrCur.op2); break;

                case Opcode.cmovo: RewriteConditionalMove(ConditionCode.OV, instrCur.op1, instrCur.op2); break;

                case Opcode.cmovpe: RewriteConditionalMove(ConditionCode.PE, instrCur.op1, instrCur.op2); break;

                case Opcode.cmovpo: RewriteConditionalMove(ConditionCode.PO, instrCur.op1, instrCur.op2); break;

                case Opcode.cmovs: RewriteConditionalMove(ConditionCode.SG, instrCur.op1, instrCur.op2); break;

                case Opcode.cmovz: RewriteConditionalMove(ConditionCode.EQ, instrCur.op1, instrCur.op2); break;

                case Opcode.cmpxchg: RewriteCmpxchg(); break;

                case Opcode.cmp: RewriteCmp(); break;

                case Opcode.cmps: RewriteStringInstruction(); break;

                case Opcode.cmpsb: RewriteStringInstruction(); break;

                case Opcode.cpuid: RewriteCpuid(); break;

                case Opcode.cvttsd2si: RewriteCvttsd2si(); break;

                case Opcode.cwd: RewriteCwd(); break;

                case Opcode.daa: EmitDaaDas("__daa"); break;

                case Opcode.das: EmitDaaDas("__das"); break;

                case Opcode.dec: RewriteIncDec(-1); break;

                case Opcode.div: RewriteDivide(Operator.UDiv, Domain.UnsignedInt); break;

                case Opcode.enter: RewriteEnter(); break;

                case Opcode.fabs: RewriteFabs(); break;

                case Opcode.fadd: EmitCommonFpuInstruction(Operator.FAdd, false, false); break;

                case Opcode.faddp: EmitCommonFpuInstruction(Operator.FAdd, false, true); break;

                case Opcode.fbld: RewriteFbld(); break;

                case Opcode.fbstp: RewriteFbstp(); break;

                case Opcode.fchs: EmitFchs(); break;

                case Opcode.fclex: RewriteFclex(); break;

                case Opcode.fcom: RewriteFcom(0); break;

                case Opcode.fcomp: RewriteFcom(1); break;

                case Opcode.fcompp: RewriteFcom(2); break;

                case Opcode.fcos: RewriteFUnary("cos"); break;

                case Opcode.fdecstp: RewriteFdecstp(); break;

                case Opcode.fdiv: EmitCommonFpuInstruction(Operator.FDiv, false, false); break;

                case Opcode.fdivp: EmitCommonFpuInstruction(Operator.FDiv, false, true); break;

                case Opcode.ffree: RewriteFfree(); break;

                case Opcode.fiadd: EmitCommonFpuInstruction(Operator.FAdd, false, false, PrimitiveType.Real64); break;

                case Opcode.ficom: RewriteFicom(false); break;

                case Opcode.ficomp: RewriteFicom(true); break;

                case Opcode.fimul: EmitCommonFpuInstruction(Operator.FMul, false, false, PrimitiveType.Real64); break;

                case Opcode.fisub: EmitCommonFpuInstruction(Operator.FSub, false, false, PrimitiveType.Real64); break;

                case Opcode.fisubr: EmitCommonFpuInstruction(Operator.FSub, true, false, PrimitiveType.Real64); break;

                case Opcode.fidiv: EmitCommonFpuInstruction(Operator.FDiv, false, false, PrimitiveType.Real64); break;

                case Opcode.fidivr: EmitCommonFpuInstruction(Operator.FDiv, true, false, PrimitiveType.Real64); break;

                case Opcode.fdivr: EmitCommonFpuInstruction(Operator.FDiv, true, false); break;

                case Opcode.fdivrp: EmitCommonFpuInstruction(Operator.FDiv, true, true); break;

                case Opcode.fild: RewriteFild(); break;

                case Opcode.fincstp: RewriteFincstp(); break;

                case Opcode.fist: RewriteFist(false); break;

                case Opcode.fistp: RewriteFist(true); break;

                case Opcode.fld: RewriteFld(); break;

                case Opcode.fld1: RewriteFldConst(1.0); break;

                case Opcode.fldcw: RewriteFldcw(); break;

                case Opcode.fldenv: RewriteFldenv(); break;

                case Opcode.fldl2t: RewriteFldConst(Constant.Lg10()); break;

                case Opcode.fldln2: RewriteFldConst(Constant.Ln2()); break;

                case Opcode.fldpi: RewriteFldConst(Constant.Pi()); break;

                case Opcode.fldz: RewriteFldConst(0.0); break;

                case Opcode.fmul: EmitCommonFpuInstruction(Operator.FMul, false, false); break;

                case Opcode.fmulp: EmitCommonFpuInstruction(Operator.FMul, false, true); break;

                case Opcode.fpatan: RewriteFpatan(); break;

                case Opcode.fprem: RewriteFprem(); break;

                case Opcode.frndint: RewriteFUnary("__rndint"); break;

                case Opcode.frstor: RewriteFrstor(); break;

                case Opcode.fsave: RewriteFsave(); break;

                case Opcode.fscale: RewriteFscale(); break;

                case Opcode.fsin: RewriteFUnary("sin"); break;

                case Opcode.fsincos: RewriteFsincos(); break;

                case Opcode.fsqrt: RewriteFUnary("sqrt"); break;

                case Opcode.fst: RewriteFst(false); break;

                case Opcode.fstenv: RewriteFstenv(); break;

                case Opcode.fstcw: RewriterFstcw(); break;

                case Opcode.fstp: RewriteFst(true); break;

                case Opcode.fstsw: RewriteFstsw(); break;

                case Opcode.fsub: EmitCommonFpuInstruction(Operator.FSub, false, false); break;

                case Opcode.fsubp: EmitCommonFpuInstruction(Operator.FSub, false, true); break;

                case Opcode.fsubr: EmitCommonFpuInstruction(Operator.FSub, true, false); break;

                case Opcode.fsubrp: EmitCommonFpuInstruction(Operator.FSub, true, true); break;

                case Opcode.ftst: RewriteFtst(); break;

                case Opcode.fucompp: RewriteFcom(2); break;

                case Opcode.fxam: RewriteFxam(); break;

                case Opcode.fxch: RewriteExchange(); break;

                case Opcode.fyl2x: RewriteFyl2x(); break;

                case Opcode.hlt: RewriteHlt(); break;

                case Opcode.idiv: RewriteDivide(Operator.SDiv, Domain.SignedInt); break;

                case Opcode.@in: RewriteIn(); break;

                case Opcode.imul: RewriteMultiply(Operator.SMul, Domain.SignedInt); break;

                case Opcode.inc: RewriteIncDec(1); break;

                case Opcode.insb: RewriteStringInstruction(); break;

                case Opcode.ins: RewriteStringInstruction(); break;

                case Opcode.@int: RewriteInt(); break;

                case Opcode.into: RewriteInto(); break;

                case Opcode.iret: RewriteIret(); break;

                case Opcode.jmp: RewriteJmp(); break;

                case Opcode.ja: RewriteConditionalGoto(ConditionCode.UGT, instrCur.op1); break;

                case Opcode.jbe: RewriteConditionalGoto(ConditionCode.ULE, instrCur.op1); break;

                case Opcode.jc: RewriteConditionalGoto(ConditionCode.ULT, instrCur.op1); break;

                case Opcode.jcxz: RewriteJcxz(); break;

                case Opcode.jge: RewriteConditionalGoto(ConditionCode.GE, instrCur.op1); break;

                case Opcode.jg: RewriteConditionalGoto(ConditionCode.GT, instrCur.op1); break;

                case Opcode.jl: RewriteConditionalGoto(ConditionCode.LT, instrCur.op1); break;

                case Opcode.jle: RewriteConditionalGoto(ConditionCode.LE, instrCur.op1); break;

                case Opcode.jnc: RewriteConditionalGoto(ConditionCode.UGE, instrCur.op1); break;

                case Opcode.jno: RewriteConditionalGoto(ConditionCode.NO, instrCur.op1); break;

                case Opcode.jns: RewriteConditionalGoto(ConditionCode.NS, instrCur.op1); break;

                case Opcode.jnz: RewriteConditionalGoto(ConditionCode.NE, instrCur.op1); break;

                case Opcode.jo: RewriteConditionalGoto(ConditionCode.OV, instrCur.op1); break;

                case Opcode.jpe: RewriteConditionalGoto(ConditionCode.PE, instrCur.op1); break;

                case Opcode.jpo: RewriteConditionalGoto(ConditionCode.PO, instrCur.op1); break;

                case Opcode.js: RewriteConditionalGoto(ConditionCode.SG, instrCur.op1); break;

                case Opcode.jz: RewriteConditionalGoto(ConditionCode.EQ, instrCur.op1); break;

                case Opcode.lahf: RewriteLahf(); break;

                case Opcode.lds: RewriteLxs(Registers.ds); break;

                case Opcode.lea: RewriteLea(); break;

                case Opcode.leave: RewriteLeave(); break;

                case Opcode.les: RewriteLxs(Registers.es); break;

                case Opcode.lfs: RewriteLxs(Registers.fs); break;

                case Opcode.lgs: RewriteLxs(Registers.gs); break;

                case Opcode.@lock: RewriteLock(); break;

                case Opcode.lods: RewriteStringInstruction(); break;

                case Opcode.lodsb: RewriteStringInstruction(); break;

                case Opcode.loop: RewriteLoop(0, ConditionCode.EQ); break;

                case Opcode.loope: RewriteLoop(FlagM.ZF, ConditionCode.EQ); break;

                case Opcode.loopne: RewriteLoop(FlagM.ZF, ConditionCode.NE); break;

                case Opcode.lss: RewriteLxs(Registers.ss); break;

                case Opcode.mov: RewriteMov(); break;

                case Opcode.movd: RewriteMovzx(); break;

                case Opcode.movdqa: RewriteMov(); break;

                case Opcode.movq: RewriteMov(); break;

                case Opcode.movs: RewriteStringInstruction(); break;

                case Opcode.movsb: RewriteStringInstruction(); break;

                case Opcode.movsx: RewriteMovsx(); break;

                case Opcode.movzx: RewriteMovzx(); break;

                case Opcode.mul: RewriteMultiply(Operator.UMul, Domain.UnsignedInt); break;

                case Opcode.neg: RewriteNeg(); break;

                case Opcode.nop: emitter.Nop(); break;

                case Opcode.not: RewriteNot(); break;

                case Opcode.or: RewriteLogical(BinaryOperator.Or); break;

                case Opcode.@out: RewriteOut(); break;

                case Opcode.@outs: RewriteStringInstruction(); break;

                case Opcode.@outsb: RewriteStringInstruction(); break;

                case Opcode.palignr: RewritePalignr(); break;

                case Opcode.pcmpeqb: RewritePcmpeqb(); break;

                case Opcode.pop: RewritePop(); break;

                case Opcode.popa: RewritePopa(); break;

                case Opcode.popf: RewritePopf(); break;

                case Opcode.pshufd: RewritePshufd(); break;

                case Opcode.punpcklbw: RewritePunpcklbw(); break;

                case Opcode.punpcklwd: RewritePunpcklwd(); break;

                case Opcode.push: RewritePush(); break;

                case Opcode.pusha: RewritePusha(); break;

                case Opcode.pushf: RewritePushf(); break;

                case Opcode.pxor: RewritePxor(); break;

                case Opcode.rcl: RewriteRotation(PseudoProcedure.RolC, true, true); break;

                case Opcode.rcr: RewriteRotation(PseudoProcedure.RorC, true, false); break;

                case Opcode.rol: RewriteRotation(PseudoProcedure.Rol, false, true); break;

                case Opcode.ror: RewriteRotation(PseudoProcedure.Ror, false, false); break;

                case Opcode.rdtsc: RewriteRdtsc(); break;

                case Opcode.rep: RewriteRep(); break;

                case Opcode.repne: RewriteRep(); break;

                case Opcode.ret: RewriteRet(); break;

                case Opcode.retf: RewriteRet(); break;

                case Opcode.sahf: emitter.Assign(orw.FlagGroup(X86Instruction.DefCc(instrCur.code)), orw.AluRegister(Registers.ah)); break;

                case Opcode.sar: RewriteBinOp(Operator.Sar); break;

                case Opcode.sbb: RewriteAdcSbb(BinaryOperator.ISub); break;

                case Opcode.scas: RewriteStringInstruction(); break;

                case Opcode.scasb: RewriteStringInstruction(); break;

                case Opcode.seta: RewriteSet(ConditionCode.UGT); break;

                case Opcode.setc: RewriteSet(ConditionCode.ULT); break;

                case Opcode.setbe: RewriteSet(ConditionCode.ULE); break;

                case Opcode.setg: RewriteSet(ConditionCode.GT); break;

                case Opcode.setge: RewriteSet(ConditionCode.GE); break;

                case Opcode.setl: RewriteSet(ConditionCode.LT); break;

                case Opcode.setle: RewriteSet(ConditionCode.LE); break;

                case Opcode.setnc: RewriteSet(ConditionCode.UGE); break;

                case Opcode.setno: RewriteSet(ConditionCode.NO); break;

                case Opcode.setns: RewriteSet(ConditionCode.NS); break;

                case Opcode.setnz: RewriteSet(ConditionCode.NE); break;

                case Opcode.setpe: RewriteSet(ConditionCode.PE); break;

                case Opcode.setpo: RewriteSet(ConditionCode.PO); break;

                case Opcode.seto: RewriteSet(ConditionCode.OV); break;

                case Opcode.sets: RewriteSet(ConditionCode.SG); break;

                case Opcode.setz: RewriteSet(ConditionCode.EQ); break;

                case Opcode.shl: RewriteBinOp(BinaryOperator.Shl); break;

                case Opcode.shld: RewriteShxd("__shld"); break;

                case Opcode.shr: RewriteBinOp(BinaryOperator.Shr); break;

                case Opcode.shrd: RewriteShxd("__shrd"); break;

                case Opcode.stc: RewriteSetFlag(FlagM.CF, Constant.True()); break;

                case Opcode.std: RewriteSetFlag(FlagM.DF, Constant.True()); break;

                case Opcode.sti: RewriteSti(); break;

                case Opcode.stos: RewriteStringInstruction(); break;

                case Opcode.stosb: RewriteStringInstruction(); break;

                case Opcode.sub: RewriteAddSub(BinaryOperator.ISub); break;

                case Opcode.test: RewriteTest(); break;

                case Opcode.wait: RewriteWait(); break;

                case Opcode.xadd: RewriteXadd(); break;

                case Opcode.xchg: RewriteExchange(); break;

                case Opcode.xgetbv: RewriteXgetbv(); break;

                case Opcode.xlat: RewriteXlat(); break;

                case Opcode.xor: RewriteLogical(BinaryOperator.Xor); break;

                case Opcode.BOR_exp: RewriteFUnary("exp"); break;

                case Opcode.BOR_ln: RewriteFUnary("log"); break;
                }
                yield return(ric);
            }
        }
예제 #10
0
 /// <summary>
 /// A jump to 0xFFFF:0x0000 in real mode is a reboot.
 /// </summary>
 /// <param name="instrCur"></param>
 /// <returns></returns>
 private bool IsRealModeReboot(X86Instruction instrCur)
 {
     var addrOp = instrCur.op1 as X86AddressOperand;
     bool isRealModeReboot = addrOp != null && addrOp.Address.ToLinear() == 0xFFFF0;
     return isRealModeReboot;
 }
예제 #11
0
        protected virtual void RenderOperand(
            MachineOperand operand,
            X86Instruction instr,
            MachineInstructionRenderer renderer,
            MachineInstructionRendererOptions options)
        {
            switch (operand)
            {
            case RegisterOperand reg:
                RenderRegister(reg.Register.Name, renderer);
                break;

            case ImmediateOperand imm:
                RenderImmediate(imm, instr, renderer);
                break;

            case MemoryOperand memOp:
                var flags = options.Flags;
                if (NeedsExplicitMemorySize(instr))
                {
                    flags |= MachineInstructionRendererFlags.ExplicitOperandSize;
                }

                if (memOp.Base == Registers.rip)
                {
                    var addr = instr.Address + instr.Length + memOp.Offset !.ToInt32();
                    if ((flags & MachineInstructionRendererFlags.ResolvePcRelativeAddress) != 0)
                    {
                        renderer.WriteString("[");
                        renderer.WriteAddress(addr.ToString(), addr);
                        renderer.WriteString("]");
                        renderer.AddAnnotation(memOp.ToString());
                    }
                    else
                    {
                        RenderMemory(memOp, renderer, flags);
                        renderer.AddAnnotation(addr.ToString());
                    }
                }
                else
                {
                    RenderMemory(memOp, renderer, flags);
                }
                break;

            case AddressOperand addrOp:
                if (addrOp.Address.Selector.HasValue)
                {
                    renderer.WriteString("far");
                    renderer.WriteString(" ");
                    renderer.WriteString(FormatUnsignedValue(addrOp.Address.Selector.Value, "{0:X4}"));
                    renderer.WriteChar(':');
                    renderer.WriteString(FormatUnsignedValue(addrOp.Address.Offset, "{0:X4}"));
                }
                else
                {
                    renderer.WriteAddress(FormatUnsignedValue(addrOp.Address.ToLinear(), "{0:X4}"), addrOp.Address);
                }
                break;

            case FpuOperand fpu:
                renderer.WriteFormat("st({0})", fpu.StNumber);
                break;

            default: throw new NotImplementedException(operand.GetType().Name);
            }
        }
예제 #12
0
        /// <summary>
        /// Iterator that yields one RtlIntructionCluster for each x86 instruction.
        /// </summary>
        /// <returns></returns>
        public IEnumerator <RtlInstructionCluster> GetEnumerator()
        {
            while (dasm.MoveNext())
            {
                instrCur = dasm.Current;
                var addr = instrCur.Address;
                this.rtlInstructions = new List <RtlInstruction>();
                this.iclass          = instrCur.InstructionClass;
                m   = new RtlEmitter(rtlInstructions);
                orw = arch.ProcessorMode.CreateOperandRewriter(arch, m, binder, host);
                switch (instrCur.Mnemonic)
                {
                default:
                    EmitUnitTest();
                    host.Warn(
                        dasm.Current.Address,
                        "x86 instruction '{0}' is not supported yet.",
                        instrCur.Mnemonic);
                    goto case Mnemonic.illegal;

                case Mnemonic.illegal: iclass = InstrClass.Invalid; m.Invalid(); break;

                case Mnemonic.aaa: RewriteAaa(); break;

                case Mnemonic.aad: RewriteAad(); break;

                case Mnemonic.aam: RewriteAam(); break;

                case Mnemonic.aas: RewriteAas(); break;

                case Mnemonic.adc: RewriteAdcSbb(m.IAdd); break;

                case Mnemonic.add: RewriteAddSub(Operator.IAdd); break;

                case Mnemonic.addss: RewriteScalarBinop(m.FAdd, PrimitiveType.Real32); break;

                case Mnemonic.addsd:
                case Mnemonic.vaddsd: RewriteScalarBinop(m.FAdd, PrimitiveType.Real64); break;

                case Mnemonic.addps: RewritePackedBinop("__addps", PrimitiveType.Real32); break;

                case Mnemonic.addpd: RewritePackedBinop("__addpd", PrimitiveType.Real64); break;

                case Mnemonic.aesimc: RewriteAesimc(); break;

                case Mnemonic.and: RewriteLogical(Operator.And); break;

                case Mnemonic.andnps: RewriteAndnps(); break;

                case Mnemonic.andpd: RewritePackedBinop("__andpd", PrimitiveType.Real64); break;

                case Mnemonic.andps: RewritePackedBinop("__andps", PrimitiveType.Real32); break;

                case Mnemonic.arpl: RewriteArpl(); break;

                case Mnemonic.bound: RewriteBound(); break;

                case Mnemonic.bsf: RewriteBsf(); break;

                case Mnemonic.bsr: RewriteBsr(); break;

                case Mnemonic.bswap: RewriteBswap(); break;

                case Mnemonic.bt: RewriteBt(); break;

                case Mnemonic.btc: RewriteBtc(); break;

                case Mnemonic.btr: RewriteBtr(); break;

                case Mnemonic.bts: RewriteBts(); break;

                case Mnemonic.call: RewriteCall(instrCur.Operands[0], instrCur.Operands[0].Width); break;

                case Mnemonic.cbw: RewriteCbw(); break;

                case Mnemonic.clc: RewriteSetFlag(FlagM.CF, Constant.False()); break;

                case Mnemonic.cld: RewriteSetFlag(FlagM.DF, Constant.False()); break;

                case Mnemonic.cli: RewriteCli(); break;

                case Mnemonic.clts: RewriteClts(); break;

                case Mnemonic.cmc: m.Assign(orw.FlagGroup(FlagM.CF), m.Not(orw.FlagGroup(FlagM.CF))); break;

                case Mnemonic.cmova: RewriteConditionalMove(ConditionCode.UGT, instrCur.Operands[0], instrCur.Operands[1]); break;

                case Mnemonic.cmovbe: RewriteConditionalMove(ConditionCode.ULE, instrCur.Operands[0], instrCur.Operands[1]); break;

                case Mnemonic.cmovc: RewriteConditionalMove(ConditionCode.ULT, instrCur.Operands[0], instrCur.Operands[1]); break;

                case Mnemonic.cmovge: RewriteConditionalMove(ConditionCode.GE, instrCur.Operands[0], instrCur.Operands[1]); break;

                case Mnemonic.cmovg: RewriteConditionalMove(ConditionCode.GT, instrCur.Operands[0], instrCur.Operands[1]); break;

                case Mnemonic.cmovl: RewriteConditionalMove(ConditionCode.LT, instrCur.Operands[0], instrCur.Operands[1]); break;

                case Mnemonic.cmovle: RewriteConditionalMove(ConditionCode.LE, instrCur.Operands[0], instrCur.Operands[1]); break;

                case Mnemonic.cmovnc: RewriteConditionalMove(ConditionCode.UGE, instrCur.Operands[0], instrCur.Operands[1]); break;

                case Mnemonic.cmovno: RewriteConditionalMove(ConditionCode.NO, instrCur.Operands[0], instrCur.Operands[1]); break;

                case Mnemonic.cmovns: RewriteConditionalMove(ConditionCode.NS, instrCur.Operands[0], instrCur.Operands[1]); break;

                case Mnemonic.cmovnz: RewriteConditionalMove(ConditionCode.NE, instrCur.Operands[0], instrCur.Operands[1]); break;

                case Mnemonic.cmovo: RewriteConditionalMove(ConditionCode.OV, instrCur.Operands[0], instrCur.Operands[1]); break;

                case Mnemonic.cmovpe: RewriteConditionalMove(ConditionCode.PE, instrCur.Operands[0], instrCur.Operands[1]); break;

                case Mnemonic.cmovpo: RewriteConditionalMove(ConditionCode.PO, instrCur.Operands[0], instrCur.Operands[1]); break;

                case Mnemonic.cmovs: RewriteConditionalMove(ConditionCode.SG, instrCur.Operands[0], instrCur.Operands[1]); break;

                case Mnemonic.cmovz: RewriteConditionalMove(ConditionCode.EQ, instrCur.Operands[0], instrCur.Operands[1]); break;

                case Mnemonic.cmpxchg: RewriteCmpxchg(); break;

                case Mnemonic.cmp: RewriteCmp(); break;

                case Mnemonic.cmps: RewriteStringInstruction(); break;

                case Mnemonic.cmppd: RewriteCmpp("__cmppd", PrimitiveType.Real64); break;

                case Mnemonic.cmpps: RewriteCmpp("__cmpps", PrimitiveType.Real32); break;

                case Mnemonic.cmpsb: RewriteStringInstruction(); break;

                case Mnemonic.comisd: RewriteComis(PrimitiveType.Real64); break;

                case Mnemonic.comiss: RewriteComis(PrimitiveType.Real32); break;

                case Mnemonic.cpuid: RewriteCpuid(); break;

                case Mnemonic.cvtpi2ps: RewriteCvtPackedToReal(PrimitiveType.Real32); break;

                case Mnemonic.cvtps2pi: RewriteCvtps2pi("__cvtps2pi", PrimitiveType.Real32, PrimitiveType.Int32); break;

                case Mnemonic.cvtps2pd: RewriteCvtps2pi("__cvtps2pd", PrimitiveType.Real32, PrimitiveType.Real64); break;

                case Mnemonic.cvtdq2ps: RewriteCvtps2pi("__cvtdq2ps", PrimitiveType.Int64, PrimitiveType.Real32); break;

                case Mnemonic.cvtsd2si: RewriteCvts2si(PrimitiveType.Real64); break;

                case Mnemonic.cvtsd2ss: RewriteCvtToReal(PrimitiveType.Real32); break;

                case Mnemonic.cvtsi2ss:
                case Mnemonic.vcvtsi2ss: RewriteCvtToReal(PrimitiveType.Real32); break;

                case Mnemonic.cvtsi2sd:
                case Mnemonic.vcvtsi2sd: RewriteCvtToReal(PrimitiveType.Real64); break;

                case Mnemonic.cvtss2sd: RewriteCvtToReal(PrimitiveType.Real64); break;

                case Mnemonic.cvtss2si: RewriteCvts2si(PrimitiveType.Real32); break;

                case Mnemonic.cvttsd2si: RewriteCvtts2si(PrimitiveType.Real64); break;

                case Mnemonic.cvttss2si: RewriteCvtts2si(PrimitiveType.Real32); break;

                case Mnemonic.cvttps2pi: RewriteCvttps2pi(); break;

                case Mnemonic.cwd: RewriteCwd(); break;

                case Mnemonic.daa: EmitDaaDas("__daa"); break;

                case Mnemonic.das: EmitDaaDas("__das"); break;

                case Mnemonic.dec: RewriteIncDec(-1); break;

                case Mnemonic.div: RewriteDivide(m.UDiv, Domain.UnsignedInt); break;

                case Mnemonic.divps: RewritePackedBinop("__divps", PrimitiveType.Real32); break;

                case Mnemonic.divsd: RewriteScalarBinop(m.FDiv, PrimitiveType.Real64); break;

                case Mnemonic.divss: RewriteScalarBinop(m.FDiv, PrimitiveType.Real32); break;

                case Mnemonic.f2xm1: RewriteF2xm1(); break;

                case Mnemonic.emms: RewriteEmms(); break;

                case Mnemonic.enter: RewriteEnter(); break;

                case Mnemonic.fabs: RewriteFabs(); break;

                case Mnemonic.fadd: EmitCommonFpuInstruction(m.FAdd, false, false); break;

                case Mnemonic.faddp: EmitCommonFpuInstruction(m.FAdd, false, true); break;

                case Mnemonic.fbld: RewriteFbld(); break;

                case Mnemonic.fbstp: RewriteFbstp(); break;

                case Mnemonic.fchs: EmitFchs(); break;

                case Mnemonic.fclex: RewriteFclex(); break;

                case Mnemonic.fcmovb: RewriteFcmov(FlagM.CF, ConditionCode.GE); break;

                case Mnemonic.fcmovbe: RewriteFcmov(FlagM.CF | FlagM.ZF, ConditionCode.GT); break;

                case Mnemonic.fcmove: RewriteFcmov(FlagM.ZF, ConditionCode.NE); break;

                case Mnemonic.fcmovnb: RewriteFcmov(FlagM.CF | FlagM.ZF, ConditionCode.GE); break;

                case Mnemonic.fcmovnbe: RewriteFcmov(FlagM.CF | FlagM.ZF, ConditionCode.LE); break;

                case Mnemonic.fcmovne: RewriteFcmov(FlagM.ZF, ConditionCode.EQ); break;

                case Mnemonic.fcmovnu: RewriteFcmov(FlagM.PF, ConditionCode.IS_NAN); break;

                case Mnemonic.fcmovu: RewriteFcmov(FlagM.PF, ConditionCode.NOT_NAN); break;

                case Mnemonic.fcom: RewriteFcom(0); break;

                case Mnemonic.fcomi: RewriteFcomi(false); break;

                case Mnemonic.fcomip: RewriteFcomi(true); break;

                case Mnemonic.fcomp: RewriteFcom(1); break;

                case Mnemonic.fcompp: RewriteFcom(2); break;

                case Mnemonic.fcos: RewriteFUnary("cos"); break;

                case Mnemonic.fdecstp: RewriteFdecstp(); break;

                case Mnemonic.fdiv: EmitCommonFpuInstruction(m.FDiv, false, false); break;

                case Mnemonic.fdivp: EmitCommonFpuInstruction(m.FDiv, false, true); break;

                case Mnemonic.ffree: RewriteFfree(); break;

                case Mnemonic.fiadd: EmitCommonFpuInstruction(m.FAdd, false, false, PrimitiveType.Real64); break;

                case Mnemonic.ficom: RewriteFicom(false); break;

                case Mnemonic.ficomp: RewriteFicom(true); break;

                case Mnemonic.fimul: EmitCommonFpuInstruction(m.FMul, false, false, PrimitiveType.Real64); break;

                case Mnemonic.fisub: EmitCommonFpuInstruction(m.FSub, false, false, PrimitiveType.Real64); break;

                case Mnemonic.fisubr: EmitCommonFpuInstruction(m.FSub, true, false, PrimitiveType.Real64); break;

                case Mnemonic.fidiv: EmitCommonFpuInstruction(m.FDiv, false, false, PrimitiveType.Real64); break;

                case Mnemonic.fidivr: EmitCommonFpuInstruction(m.FDiv, true, false, PrimitiveType.Real64); break;

                case Mnemonic.fdivr: EmitCommonFpuInstruction(m.FDiv, true, false); break;

                case Mnemonic.fdivrp: EmitCommonFpuInstruction(m.FDiv, true, true); break;

                case Mnemonic.fild: RewriteFild(); break;

                case Mnemonic.fincstp: RewriteFincstp(); break;

                case Mnemonic.fist: RewriteFist(false); break;

                case Mnemonic.fistp: RewriteFist(true); break;

                case Mnemonic.fisttp: RewriteFistt(true); break;

                case Mnemonic.fld: RewriteFld(); break;

                case Mnemonic.fld1: RewriteFldConst(1.0); break;

                case Mnemonic.fldcw: RewriteFldcw(); break;

                case Mnemonic.fldenv: RewriteFldenv(); break;

                case Mnemonic.fldl2e: RewriteFldConst(Constant.LgE()); break;

                case Mnemonic.fldl2t: RewriteFldConst(Constant.Lg10()); break;

                case Mnemonic.fldlg2: RewriteFldConst(Constant.Log2()); break;

                case Mnemonic.fldln2: RewriteFldConst(Constant.Ln2()); break;

                case Mnemonic.fldpi: RewriteFldConst(Constant.Pi()); break;

                case Mnemonic.fldz: RewriteFldConst(0.0); break;

                case Mnemonic.fmul: EmitCommonFpuInstruction(m.FMul, false, false); break;

                case Mnemonic.fmulp: EmitCommonFpuInstruction(m.FMul, false, true); break;

                case Mnemonic.fninit: RewriteFninit(); break;

                case Mnemonic.fnop: m.Nop(); break;

                case Mnemonic.fpatan: RewriteFpatan(); break;

                case Mnemonic.fprem: RewriteFprem(); break;

                case Mnemonic.fprem1: RewriteFprem1(); break;

                case Mnemonic.fptan: RewriteFptan(); break;

                case Mnemonic.frndint: RewriteFUnary("__rndint"); break;

                case Mnemonic.frstor: RewriteFrstor(); break;

                case Mnemonic.fsave: RewriteFsave(); break;

                case Mnemonic.fscale: RewriteFscale(); break;

                case Mnemonic.fsin: RewriteFUnary("sin"); break;

                case Mnemonic.fsincos: RewriteFsincos(); break;

                case Mnemonic.fsqrt: RewriteFUnary("sqrt"); break;

                case Mnemonic.fst: RewriteFst(false); break;

                case Mnemonic.fstenv: RewriteFstenv(); break;

                case Mnemonic.fstcw: RewriterFstcw(); break;

                case Mnemonic.fstp: RewriteFst(true); break;

                case Mnemonic.fstsw: RewriteFstsw(); break;

                case Mnemonic.fsub: EmitCommonFpuInstruction(m.FSub, false, false); break;

                case Mnemonic.fsubp: EmitCommonFpuInstruction(m.FSub, false, true); break;

                case Mnemonic.fsubr: EmitCommonFpuInstruction(m.FSub, true, false); break;

                case Mnemonic.fsubrp: EmitCommonFpuInstruction(m.FSub, true, true); break;

                case Mnemonic.ftst: RewriteFtst(); break;

                case Mnemonic.fucom: RewriteFcom(0); break;

                case Mnemonic.fucomp: RewriteFcom(1); break;

                case Mnemonic.fucompp: RewriteFcom(2); break;

                case Mnemonic.fucomi: RewriteFcomi(false); break;

                case Mnemonic.fucomip: RewriteFcomi(true); break;

                case Mnemonic.fxam: RewriteFxam(); break;

                case Mnemonic.fxch: RewriteExchange(); break;

                case Mnemonic.fxtract: RewriteFxtract(); break;

                case Mnemonic.fyl2x: RewriteFyl2x(); break;

                case Mnemonic.fyl2xp1: RewriteFyl2xp1(); break;

                case Mnemonic.getsec: RewriteGetsec(); break;

                case Mnemonic.hlt: RewriteHlt(); break;

                case Mnemonic.idiv: RewriteDivide(m.SDiv, Domain.SignedInt); break;

                case Mnemonic.@in: RewriteIn(); break;

                case Mnemonic.imul: RewriteMultiply(Operator.SMul, Domain.SignedInt); break;

                case Mnemonic.inc: RewriteIncDec(1); break;

                case Mnemonic.insb: RewriteStringInstruction(); break;

                case Mnemonic.ins: RewriteStringInstruction(); break;

                case Mnemonic.@int: RewriteInt(); break;

                case Mnemonic.into: RewriteInto(); break;

                case Mnemonic.invd: RewriteInvd(); break;

                case Mnemonic.iret: RewriteIret(); break;

                case Mnemonic.jmp: RewriteJmp(); break;

                case Mnemonic.ja: RewriteConditionalGoto(ConditionCode.UGT, instrCur.Operands[0]); break;

                case Mnemonic.jbe: RewriteConditionalGoto(ConditionCode.ULE, instrCur.Operands[0]); break;

                case Mnemonic.jc: RewriteConditionalGoto(ConditionCode.ULT, instrCur.Operands[0]); break;

                case Mnemonic.jcxz: RewriteJcxz(); break;

                case Mnemonic.jge: RewriteConditionalGoto(ConditionCode.GE, instrCur.Operands[0]); break;

                case Mnemonic.jg: RewriteConditionalGoto(ConditionCode.GT, instrCur.Operands[0]); break;

                case Mnemonic.jl: RewriteConditionalGoto(ConditionCode.LT, instrCur.Operands[0]); break;

                case Mnemonic.jle: RewriteConditionalGoto(ConditionCode.LE, instrCur.Operands[0]); break;

                case Mnemonic.jnc: RewriteConditionalGoto(ConditionCode.UGE, instrCur.Operands[0]); break;

                case Mnemonic.jno: RewriteConditionalGoto(ConditionCode.NO, instrCur.Operands[0]); break;

                case Mnemonic.jns: RewriteConditionalGoto(ConditionCode.NS, instrCur.Operands[0]); break;

                case Mnemonic.jnz: RewriteConditionalGoto(ConditionCode.NE, instrCur.Operands[0]); break;

                case Mnemonic.jo: RewriteConditionalGoto(ConditionCode.OV, instrCur.Operands[0]); break;

                case Mnemonic.jpe: RewriteConditionalGoto(ConditionCode.PE, instrCur.Operands[0]); break;

                case Mnemonic.jpo: RewriteConditionalGoto(ConditionCode.PO, instrCur.Operands[0]); break;

                case Mnemonic.js: RewriteConditionalGoto(ConditionCode.SG, instrCur.Operands[0]); break;

                case Mnemonic.jz: RewriteConditionalGoto(ConditionCode.EQ, instrCur.Operands[0]); break;

                case Mnemonic.lahf: RewriteLahf(); break;

                case Mnemonic.lar: RewriteLar(); break;

                case Mnemonic.lds: RewriteLxs(Registers.ds); break;

                case Mnemonic.ldmxcsr: RewriteLdmxcsr(); break;

                case Mnemonic.stmxcsr: RewriteStmxcsr(); break;

                case Mnemonic.lea: RewriteLea(); break;

                case Mnemonic.leave: RewriteLeave(); break;

                case Mnemonic.les: RewriteLxs(Registers.es); break;

                case Mnemonic.lfence: RewriteLfence(); break;

                case Mnemonic.lfs: RewriteLxs(Registers.fs); break;

                case Mnemonic.lgs: RewriteLxs(Registers.gs); break;

                case Mnemonic.lgdt: RewriteLxdt("__lgdt"); break;

                case Mnemonic.lidt: RewriteLxdt("__lidt"); break;

                case Mnemonic.lldt: RewriteLxdt("__lldt"); break;

                case Mnemonic.@lock: RewriteLock(); break;

                case Mnemonic.lods: RewriteStringInstruction(); break;

                case Mnemonic.lodsb: RewriteStringInstruction(); break;

                case Mnemonic.loop: RewriteLoop(0, ConditionCode.EQ); break;

                case Mnemonic.loope: RewriteLoop(FlagM.ZF, ConditionCode.EQ); break;

                case Mnemonic.loopne: RewriteLoop(FlagM.ZF, ConditionCode.NE); break;

                case Mnemonic.lsl: RewriteLsl(); break;

                case Mnemonic.lss: RewriteLxs(Registers.ss); break;

                case Mnemonic.maskmovq: RewriteMaskmovq(); break;

                case Mnemonic.maxps: RewritePackedBinop("__maxps", PrimitiveType.Real32); break;

                case Mnemonic.mfence: RewriteMfence(); break;

                case Mnemonic.minpd: RewritePackedBinop("__minpd", PrimitiveType.Real64); break;

                case Mnemonic.minps: RewritePackedBinop("__minps", PrimitiveType.Real32); break;

                case Mnemonic.mov: RewriteMov(); break;

                case Mnemonic.movapd:
                case Mnemonic.movaps:
                case Mnemonic.vmovapd:
                case Mnemonic.vmovaps: RewriteMov(); break;

                case Mnemonic.vmread: RewriteVmread(); break;

                case Mnemonic.vmwrite: RewriteVmwrite(); break;

                case Mnemonic.movd: RewriteMovzx(); break;

                case Mnemonic.movdqa: RewriteMov(); break;

                case Mnemonic.movhpd: RewritePackedUnaryop("__movhpd", PrimitiveType.Real64, PrimitiveType.Real64); break;

                case Mnemonic.movhps: RewritePackedUnaryop("__movhps", PrimitiveType.Real32, PrimitiveType.Real64); break;

                case Mnemonic.movlpd: RewritePackedUnaryop("__movlpd", PrimitiveType.Real64, PrimitiveType.Real64); break;

                case Mnemonic.movlps: RewritePackedUnaryop("__movlps", PrimitiveType.Real32, PrimitiveType.Real64); break;

                case Mnemonic.movlhps: RewriteMovlhps(); break;

                case Mnemonic.movmskpd: RewriteMovmsk("__movmskpd", PrimitiveType.Real64); break;

                case Mnemonic.movmskps: RewriteMovmsk("__movmskps", PrimitiveType.Real32); break;

                case Mnemonic.movnti: RewriteMov(); break;

                case Mnemonic.movntps: RewriteMov(); break;

                case Mnemonic.movntq: RewriteMov(); break;

                case Mnemonic.movq: RewriteMov(); break;

                case Mnemonic.movs: RewriteStringInstruction(); break;

                case Mnemonic.movsb: RewriteStringInstruction(); break;

                case Mnemonic.movsd:
                case Mnemonic.vmovsd: RewriteMovssd(PrimitiveType.Real64); break;

                case Mnemonic.movss:
                case Mnemonic.vmovss: RewriteMovssd(PrimitiveType.Real32); break;

                case Mnemonic.movsx: RewriteMovsx(); break;

                case Mnemonic.movups: RewriteMov(); break;

                case Mnemonic.movupd: RewriteMov(); break;

                case Mnemonic.movzx: RewriteMovzx(); break;

                case Mnemonic.mul: RewriteMultiply(Operator.UMul, Domain.UnsignedInt); break;

                case Mnemonic.mulpd: RewritePackedBinop("__mulpd", PrimitiveType.Real64); break;

                case Mnemonic.mulps: RewritePackedBinop("__mulps", PrimitiveType.Real32); break;

                case Mnemonic.mulss: RewriteScalarBinop(m.FMul, PrimitiveType.Real32); break;

                case Mnemonic.mulsd: RewriteScalarBinop(m.FMul, PrimitiveType.Real64); break;

                case Mnemonic.neg: RewriteNeg(); break;

                case Mnemonic.nop: m.Nop(); break;

                case Mnemonic.not: RewriteNot(); break;

                case Mnemonic.or: RewriteLogical(BinaryOperator.Or); break;

                case Mnemonic.orpd: RewritePackedBinop("__orpd", PrimitiveType.Real64); break;

                case Mnemonic.orps: RewritePackedBinop("__orps", PrimitiveType.Real32); break;

                case Mnemonic.@out: RewriteOut(); break;

                case Mnemonic.@outs: RewriteStringInstruction(); break;

                case Mnemonic.@outsb: RewriteStringInstruction(); break;

                case Mnemonic.packssdw: RewritePackedBinop("__packssdw", PrimitiveType.Int32, new ArrayType(PrimitiveType.Int16, 0)); break;

                case Mnemonic.packuswb: RewritePackedBinop("__packuswb", PrimitiveType.UInt16, new ArrayType(PrimitiveType.UInt8, 0)); break;

                case Mnemonic.paddb: RewritePackedBinop("__paddb", PrimitiveType.Byte); break;

                case Mnemonic.paddd: RewritePackedBinop("__paddd", PrimitiveType.Word32); break;

                case Mnemonic.paddq:
                case Mnemonic.vpaddq: RewritePackedBinop("__paddq", PrimitiveType.Word64); break;

                case Mnemonic.paddsw: RewritePackedBinop("__paddsw", PrimitiveType.Word16); break;

                case Mnemonic.paddsb: RewritePackedBinop("__paddsb", PrimitiveType.SByte); break;

                case Mnemonic.paddusb: RewritePackedBinop("__paddusb", PrimitiveType.Byte); break;

                case Mnemonic.paddusw: RewritePackedBinop("__paddsw", PrimitiveType.Word16); break;

                case Mnemonic.paddw: RewritePackedBinop("__paddw", PrimitiveType.Word16); break;

                case Mnemonic.pand:
                case Mnemonic.vpand: RewritePackedLogical("__pand"); break;

                case Mnemonic.pandn:
                case Mnemonic.vpandn: RewritePackedLogical("__pandn"); break;

                case Mnemonic.pause: RewritePause(); break;

                case Mnemonic.palignr: RewritePalignr(); break;

                case Mnemonic.pavgb: RewritePavg("__pavgb", PrimitiveType.Byte); break;

                case Mnemonic.pavgw: RewritePavg("__pavgw", PrimitiveType.Byte); break;

                case Mnemonic.pcmpeqb: RewritePcmp("__pcmpeqb", PrimitiveType.Byte); break;

                case Mnemonic.pcmpeqd: RewritePcmp("__pcmpeqd", PrimitiveType.Word32); break;

                case Mnemonic.pcmpeqw: RewritePcmp("__pcmpeqw", PrimitiveType.Word16); break;

                case Mnemonic.pcmpgtb: RewritePcmp("__pcmpgtb", PrimitiveType.Byte); break;

                case Mnemonic.pcmpgtd: RewritePcmp("__pcmpgtd", PrimitiveType.Word32); break;

                case Mnemonic.pcmpgtw: RewritePcmp("__pcmpgtw", PrimitiveType.Word16); break;

                case Mnemonic.pextrw:
                case Mnemonic.vextrw:  RewritePextrw(); break;

                case Mnemonic.pinsrw:
                case Mnemonic.vpinsrw: RewritePinsrw(); break;

                case Mnemonic.pmaddwd: RewritePackedBinop("__pmaddwd", PrimitiveType.Word16, new ArrayType(PrimitiveType.Word32, 0)); break;

                case Mnemonic.pmaxsw: RewritePackedBinop("__pmaxsw", PrimitiveType.Int16); break;

                case Mnemonic.pmaxub: RewritePackedBinop("__pmaxub", PrimitiveType.UInt8); break;

                case Mnemonic.pminsw: RewritePackedBinop("__pminsw", PrimitiveType.Int16); break;

                case Mnemonic.pminub: RewritePackedBinop("__pminub", PrimitiveType.UInt8); break;

                case Mnemonic.pmovmskb: RewriteMovmsk("__pmovmskb", PrimitiveType.Byte); break;

                case Mnemonic.pmulhuw: RewritePackedBinop("__pmulhuw", PrimitiveType.UInt16, new ArrayType(PrimitiveType.UInt16, 8)); break;

                case Mnemonic.pmulhw: RewritePackedBinop("__pmulhw", PrimitiveType.Int16, new ArrayType(PrimitiveType.Int16, 8)); break;

                case Mnemonic.pmullw:
                case Mnemonic.vpmullw: RewritePackedBinop("__pmullw", PrimitiveType.Int16, new ArrayType(PrimitiveType.Int16, 8)); break;

                case Mnemonic.pmuludq: RewritePackedBinop("__pmuludq", PrimitiveType.UInt32, new ArrayType(PrimitiveType.UInt64, 0)); break;

                case Mnemonic.prefetchw: RewritePrefetch("__prefetchw"); break;

                case Mnemonic.psadbw: RewritePackedBinop("__psadbw", PrimitiveType.Byte, PrimitiveType.Word16); break;

                case Mnemonic.pslld: RewritePackedBinop("__pslld", PrimitiveType.Word32); break;

                case Mnemonic.psllq:
                case Mnemonic.vpsllq: RewritePackedBinop("__psllq", PrimitiveType.Word64); break;

                case Mnemonic.psllw: RewritePackedBinop("__psllw", PrimitiveType.Word16); break;

                case Mnemonic.psrad: RewritePackedBinop("__psrad", PrimitiveType.Int32); break;

                case Mnemonic.psraw: RewritePackedBinop("__psraw", PrimitiveType.Int16); break;

                case Mnemonic.psrlq: RewritePackedBinop("__psrlq", PrimitiveType.Word64); break;

                case Mnemonic.pop: RewritePop(); break;

                case Mnemonic.popa: RewritePopa(); break;

                case Mnemonic.popf: RewritePopf(); break;

                case Mnemonic.por: RewritePackedLogical("__por"); break;

                case Mnemonic.prefetchnta: RewritePrefetch("__prefetchnta"); break;

                case Mnemonic.prefetcht0: RewritePrefetch("__prefetcht0"); break;

                case Mnemonic.prefetcht1: RewritePrefetch("__prefetcht1"); break;

                case Mnemonic.prefetcht2: RewritePrefetch("__prefetcht2"); break;

                case Mnemonic.pshufd: RewritePshuf("__pshufd", PrimitiveType.Word32); break;

                case Mnemonic.pshufw: RewritePshuf("__pshufw", PrimitiveType.Word16); break;

                case Mnemonic.psrld: RewritePackedShift("__psrld", PrimitiveType.Word32); break;

                case Mnemonic.psrlw: RewritePackedShift("__psrlw", PrimitiveType.Word16); break;

                case Mnemonic.psubb: RewritePackedBinop("__psubb", PrimitiveType.Byte); break;

                case Mnemonic.psubd:
                case Mnemonic.vpsubd: RewritePackedBinop("__psubd", PrimitiveType.Word32); break;

                case Mnemonic.psubq: RewritePackedBinop("__psubq", PrimitiveType.Word64); break;

                case Mnemonic.psubsb: RewritePackedBinop("__psubsb", PrimitiveType.SByte); break;

                case Mnemonic.psubsw: RewritePackedBinop("__psubsw", PrimitiveType.Word16); break;

                case Mnemonic.psubusb: RewritePackedBinop("__psubusb", PrimitiveType.UInt8); break;

                case Mnemonic.psubusw: RewritePackedBinop("__psubusw", PrimitiveType.UInt16); break;

                case Mnemonic.psubw: RewritePackedBinop("__psubw", PrimitiveType.Word16); break;

                case Mnemonic.punpckhbw: RewritePunpckhbw(); break;

                case Mnemonic.punpckhdq: RewritePunpckhdq(); break;

                case Mnemonic.punpckhwd: RewritePunpckhwd(); break;

                case Mnemonic.punpcklbw: RewritePunpcklbw(); break;

                case Mnemonic.punpckldq: RewritePunpckldq(); break;

                case Mnemonic.punpcklwd: RewritePunpcklwd(); break;

                case Mnemonic.push: RewritePush(); break;

                case Mnemonic.pusha: RewritePusha(); break;

                case Mnemonic.pushf: RewritePushf(); break;

                case Mnemonic.pxor:
                case Mnemonic.vpxor: RewritePxor(); break;

                case Mnemonic.rcl: RewriteRotation(PseudoProcedure.RolC, true, true); break;

                case Mnemonic.rcpps: RewritePackedUnaryop("__rcpps", PrimitiveType.Real32); break;

                case Mnemonic.rcr: RewriteRotation(PseudoProcedure.RorC, true, false); break;

                case Mnemonic.rol: RewriteRotation(PseudoProcedure.Rol, false, true); break;

                case Mnemonic.ror: RewriteRotation(PseudoProcedure.Ror, false, false); break;

                case Mnemonic.rdmsr: RewriteRdmsr(); break;

                case Mnemonic.rdpmc: RewriteRdpmc(); break;

                case Mnemonic.rdtsc: RewriteRdtsc(); break;

                case Mnemonic.ret: RewriteRet(); break;

                case Mnemonic.retf: RewriteRet(); break;

                case Mnemonic.rsqrtps: RewritePackedUnaryop("__rsqrtps", PrimitiveType.Real32); break;

                case Mnemonic.sahf: m.Assign(orw.FlagGroup(X86Instruction.DefCc(instrCur.Mnemonic)), orw.AluRegister(Registers.ah)); break;

                case Mnemonic.sar: RewriteBinOp(Operator.Sar); break;

                case Mnemonic.sbb: RewriteAdcSbb(m.ISub); break;

                case Mnemonic.scas: RewriteStringInstruction(); break;

                case Mnemonic.scasb: RewriteStringInstruction(); break;

                case Mnemonic.seta: RewriteSet(ConditionCode.UGT); break;

                case Mnemonic.setc: RewriteSet(ConditionCode.ULT); break;

                case Mnemonic.setbe: RewriteSet(ConditionCode.ULE); break;

                case Mnemonic.setg: RewriteSet(ConditionCode.GT); break;

                case Mnemonic.setge: RewriteSet(ConditionCode.GE); break;

                case Mnemonic.setl: RewriteSet(ConditionCode.LT); break;

                case Mnemonic.setle: RewriteSet(ConditionCode.LE); break;

                case Mnemonic.setnc: RewriteSet(ConditionCode.UGE); break;

                case Mnemonic.setno: RewriteSet(ConditionCode.NO); break;

                case Mnemonic.setns: RewriteSet(ConditionCode.NS); break;

                case Mnemonic.setnz: RewriteSet(ConditionCode.NE); break;

                case Mnemonic.setpe: RewriteSet(ConditionCode.PE); break;

                case Mnemonic.setpo: RewriteSet(ConditionCode.PO); break;

                case Mnemonic.seto: RewriteSet(ConditionCode.OV); break;

                case Mnemonic.sets: RewriteSet(ConditionCode.SG); break;

                case Mnemonic.setz: RewriteSet(ConditionCode.EQ); break;

                case Mnemonic.sfence: RewriteSfence(); break;

                case Mnemonic.sgdt: RewriteSxdt("__sgdt"); break;

                case Mnemonic.sha1msg2: RewriteSha1msg2(); break;

                case Mnemonic.shl: RewriteBinOp(BinaryOperator.Shl); break;

                case Mnemonic.shld: RewriteShxd("__shld"); break;

                case Mnemonic.shr: RewriteBinOp(BinaryOperator.Shr); break;

                case Mnemonic.shrd: RewriteShxd("__shrd"); break;

                case Mnemonic.sidt: RewriteSxdt("__sidt"); break;

                case Mnemonic.vshufps: RewritePackedTernaryop("__vshufps", PrimitiveType.Real32); break;

                case Mnemonic.sldt: RewriteSxdt("__sldt"); break;

                case Mnemonic.sqrtps: RewritePackedUnaryop("__sqrtps", PrimitiveType.Real32); break;

                case Mnemonic.sqrtsd: RewriteSqrtsd(); break;

                case Mnemonic.stc: RewriteSetFlag(FlagM.CF, Constant.True()); break;

                case Mnemonic.std: RewriteSetFlag(FlagM.DF, Constant.True()); break;

                case Mnemonic.sti: RewriteSti(); break;

                case Mnemonic.stos: RewriteStringInstruction(); break;

                case Mnemonic.stosb: RewriteStringInstruction(); break;

                case Mnemonic.sub: RewriteAddSub(BinaryOperator.ISub); break;

                case Mnemonic.subsd: RewriteScalarBinop(m.FSub, PrimitiveType.Real64); break;

                case Mnemonic.subss: RewriteScalarBinop(m.FSub, PrimitiveType.Real32); break;

                case Mnemonic.subpd: RewritePackedBinop("__subpd", PrimitiveType.Real64); break;

                case Mnemonic.subps: RewritePackedBinop("__subps", PrimitiveType.Real32); break;

                case Mnemonic.syscall: RewriteSyscall(); break;

                case Mnemonic.sysenter: RewriteSysenter(); break;

                case Mnemonic.sysexit: RewriteSysexit(); break;

                case Mnemonic.sysret: RewriteSysret(); break;

                case Mnemonic.ucomiss: RewriteComis(PrimitiveType.Real32); break;

                case Mnemonic.ucomisd: RewriteComis(PrimitiveType.Real64); break;

                case Mnemonic.ud0: iclass = InstrClass.Invalid; m.Invalid(); break;

                case Mnemonic.ud1: iclass = InstrClass.Invalid; m.Invalid(); break;

                case Mnemonic.ud2: iclass = InstrClass.Invalid; m.Invalid(); break;

                case Mnemonic.unpcklpd: RewritePackedBinop("__unpcklpd", PrimitiveType.Real64); break;

                case Mnemonic.unpcklps: RewritePackedBinop("__unpcklps", PrimitiveType.Real32); break;

                case Mnemonic.test: RewriteTest(); break;

                case Mnemonic.wait: RewriteWait(); break;

                case Mnemonic.wbinvd: RewriteWbinvd(); break;

                case Mnemonic.wrmsr: RewriteWrsmr(); break;

                case Mnemonic.xadd: RewriteXadd(); break;

                case Mnemonic.xchg: RewriteExchange(); break;

                case Mnemonic.xgetbv: RewriteXgetbv(); break;

                case Mnemonic.xsetbv: RewriteXsetbv(); break;

                case Mnemonic.xlat: RewriteXlat(); break;

                case Mnemonic.xor: RewriteLogical(BinaryOperator.Xor); break;

                case Mnemonic.xorpd:
                case Mnemonic.vxorpd: RewritePackedBinop("__xorpd", PrimitiveType.Word64); break;

                case Mnemonic.xorps: RewritePackedBinop("__xorps", PrimitiveType.Word32); break;

                case Mnemonic.BOR_exp: RewriteFUnary("exp"); break;

                case Mnemonic.BOR_ln: RewriteFUnary("log"); break;
                }
                var len = (int)(dasm.Current.Address - addr) + dasm.Current.Length;
                yield return(m.MakeCluster(addr, len, iclass));
            }
        }
예제 #13
0
        /// <summary>
        /// Memory accesses are translated into expressions, performing simplifications
        /// where possible.
        /// </summary>
        public Expression EffectiveAddressExpression(X86Instruction instr, MemoryOperand mem)
        {
            Expression?eIndex      = null;
            Expression?eBase       = null;
            Expression?expr        = null;
            bool       ripRelative = false;

            if (mem.Base != RegisterStorage.None)
            {
                if (mem.Base == Registers.rip)
                {
                    ripRelative = true;
                }
                else
                {
                    eBase = AluRegister(mem.Base);
                    if (expr != null)
                    {
                        expr = m.IAdd(eBase, expr);
                    }
                    else
                    {
                        expr = eBase;
                    }
                }
            }

            if (mem.Offset !.IsValid)
            {
                if (ripRelative)
                {
                    expr = instr.Address + (instr.Length + mem.Offset.ToInt64());
                }
                else if (expr != null)
                {
                    BinaryOperator op = Operator.IAdd;
                    long           l  = mem.Offset.ToInt64();
                    if (l < 0 && l > -0x800)
                    {
                        l  = -l;
                        op = Operator.ISub;
                    }

                    DataType dt      = (eBase != null) ? eBase.DataType : eIndex !.DataType;
                    Constant cOffset = Constant.Create(dt, l);
                    expr = new BinaryExpression(op, dt, expr, cOffset);
                }
                else
                {
                    expr = mem.Offset;
                }
            }

            if (mem.Index != RegisterStorage.None)
            {
                eIndex = AluRegister(mem.Index);
                if (mem.Scale != 0 && mem.Scale != 1)
                {
                    eIndex = m.IMul(eIndex, Constant.Create(mem.Index.DataType, mem.Scale));
                }
                expr = m.IAdd(expr !, eIndex);
            }
            if (!IsSegmentedAccessRequired && expr is Constant c && mem.SegOverride == RegisterStorage.None)
            {
                return(arch.MakeAddressFromConstant(c, false) !);
            }
            return(expr !);
        }
예제 #14
0
        /// <summary>
        /// Rewrites the current instruction as a string instruction.
        /// </summary>
        /// <returns>False if the current instruction is not a string
        /// instruction. This can happen when disassembling data where
        /// a "rep" prefix is followed by some other junk byte.
        /// </returns>
        private bool RewriteStringInstruction()
        {
            bool incSi       = false;
            bool incDi       = false;
            var  incOperator = GetIncrementOperator();

            Identifier      regDX;
            PseudoProcedure ppp;

            switch (instrCur.code)
            {
            default:
                return(false);

            case Opcode.cmps:
            case Opcode.cmpsb:
                emitter.Assign(
                    orw.FlagGroup(X86Instruction.DefCc(Opcode.cmp)),
                    emitter.Cond(emitter.ISub(MemSi(), MemDi())));
                incSi = true;
                incDi = true;
                break;

            case Opcode.lods:
            case Opcode.lodsb:
                emitter.Assign(RegAl, MemSi());
                incSi = true;
                break;

            case Opcode.movs:
            case Opcode.movsb:
                Identifier tmp = frame.CreateTemporary(instrCur.dataWidth);
                emitter.Assign(tmp, MemSi());
                emitter.Assign(MemDi(), tmp);
                incSi = true;
                incDi = true;
                break;

            case Opcode.ins:
            case Opcode.insb:
                regDX = orw.AluRegister(Registers.edx, instrCur.addrWidth);
                ppp   = host.EnsurePseudoProcedure("__in", instrCur.dataWidth, 1);
                emitter.Assign(MemDi(), emitter.Fn(ppp, regDX));
                incDi = true;
                break;

            case Opcode.outs:
            case Opcode.outsb:
                regDX = orw.AluRegister(Registers.edx, instrCur.addrWidth);
                ppp   = host.EnsurePseudoProcedure("__out" + RegAl.DataType.Prefix, VoidType.Instance, 2);
                emitter.SideEffect(emitter.Fn(ppp, regDX, RegAl));
                incSi = true;
                break;

            case Opcode.scas:
            case Opcode.scasb:
                emitter.Assign(
                    orw.FlagGroup(X86Instruction.DefCc(Opcode.cmp)),
                    emitter.Cond(emitter.ISub(RegAl, MemDi())));
                incDi = true;
                break;

            case Opcode.stos:
            case Opcode.stosb:
                emitter.Assign(MemDi(), RegAl);
                incDi = true;
                break;

            case Opcode.ret:
                // "AMD recommends to avoid the penalty by adding rep prefix instead of nop
                // because it saves decode bandwidth."
                RewriteRet();
                return(true);
            }

            if (incSi)
            {
                emitter.Assign(RegSi, incOperator(RegSi, instrCur.dataWidth.Size));
            }

            if (incDi)
            {
                emitter.Assign(RegDi, incOperator(RegDi, instrCur.dataWidth.Size));
            }
            return(true);
        }
예제 #15
0
        /// <summary>
        /// Memory accesses are translated into expressions.
        /// </summary>
        /// <param name="mem"></param>
        /// <param name="state"></param>
        /// <returns></returns>
        public Expression EffectiveAddressExpression(X86Instruction instr, MemoryOperand mem, X86State state)
        {
            Expression    eIndex      = null;
            Expression    eBase       = null;
            Expression    expr        = null;
            PrimitiveType type        = PrimitiveType.CreateWord(mem.Width.Size);
            bool          ripRelative = false;

            if (mem.Base != RegisterStorage.None)
            {
                if (mem.Base == Registers.rip)
                {
                    ripRelative = true;
                }
                else
                {
                    eBase = AluRegister(mem.Base);
                    if (expr != null)
                    {
                        expr = new BinaryExpression(Operator.IAdd, eBase.DataType, eBase, expr);
                    }
                    else
                    {
                        expr = eBase;
                    }
                }
            }

            if (mem.Offset.IsValid)
            {
                if (ripRelative)
                {
                    expr = instr.Address + (instr.Length + mem.Offset.ToInt64());
                }
                else if (expr != null)
                {
                    BinaryOperator op = Operator.IAdd;
                    long           l  = mem.Offset.ToInt64();
                    if (l < 0 && l > -0x800)
                    {
                        l  = -l;
                        op = Operator.ISub;
                    }

                    DataType dt      = (eBase != null) ? eBase.DataType : eIndex.DataType;
                    Constant cOffset = Constant.Create(dt, l);
                    expr = new BinaryExpression(op, dt, expr, cOffset);
                }
                else
                {
                    expr = mem.Offset;
                }
            }

            if (mem.Index != RegisterStorage.None)
            {
                eIndex = AluRegister(mem.Index);
                if (mem.Scale != 0 && mem.Scale != 1)
                {
                    eIndex = new BinaryExpression(
                        Operator.IMul, eIndex.DataType, eIndex, Constant.Create(mem.Width, mem.Scale));
                }
                expr = new BinaryExpression(Operator.IAdd, expr.DataType, expr, eIndex);
            }
            return(expr);
        }
예제 #16
0
        protected override void RenderMnemonic(X86Instruction instr, StringBuilder sb)
        {
            switch (instr.Mnemonic)
            {
            case Mnemonic.retf:
                sb.Append("lret");
                return;

            case Mnemonic.jmp:
            case Mnemonic.call:
                if (IsFar(instr.Operands[0]))
                {
                    sb.Append("l");
                    sb.Append(instr.MnemonicAsString);
                    return;
                }
                else
                {
                    sb.Append(instr.MnemonicAsString);
                }
                break;

            case Mnemonic.bound:
            case Mnemonic.enter:
                sb.Append(instr.MnemonicAsString);
                return;

            case Mnemonic.cbw:
                sb.Append("cbtw");
                return;

            case Mnemonic.cdq:
                sb.Append("cltd");
                return;

            case Mnemonic.cdqe:
                sb.Append("cltq");
                return;

            case Mnemonic.cqo:
                sb.Append("cqto");
                return;

            case Mnemonic.cwd:
                sb.Append("cwtd");
                return;

            case Mnemonic.cwde:
                sb.Append("cwtl");
                return;

            case Mnemonic.cmps:
            case Mnemonic.ins:
            case Mnemonic.lods:
            case Mnemonic.movs:
            case Mnemonic.outs:
            case Mnemonic.stos:
                sb.Append(instr.MnemonicAsString);
                sb.Append(MnemonicSuffix(instr.dataWidth));
                return;

            case Mnemonic.movsx:
                sb.Append("movs");
                sb.Append(MnemonicSuffix(instr.Operands[1]));
                sb.Append(MnemonicSuffix(instr.Operands[0]));
                return;

            case Mnemonic.movzx:
                sb.Append("movz");
                sb.Append(MnemonicSuffix(instr.Operands[1]));
                sb.Append(MnemonicSuffix(instr.Operands[0]));
                return;

            default:
                sb.Append(instr.MnemonicAsString);
                break;
            }

            if (base.NeedsExplicitMemorySize(instr))
            {
                char suffix = MnemonicSuffix(instr.Operands[0]);
                sb.Append(suffix);
            }
        }
예제 #17
0
        protected override void RenderOperand(MachineOperand operand, X86Instruction instr, MachineInstructionRenderer renderer, MachineInstructionRendererOptions options)
        {
            switch (operand)
            {
            case RegisterOperand reg:
                if (instr.Mnemonic == Mnemonic.call || instr.Mnemonic == Mnemonic.jmp)
                {
                    renderer.WriteChar('*');
                }
                this.RenderRegister(reg.Register.Name, renderer);
                break;

            case ImmediateOperand imm:
                renderer.WriteChar('$');
                RenderImmediate(imm, instr, renderer);
                break;

            case MemoryOperand mem:
                if (mem.Width is PrimitiveType pt && pt.Domain == Domain.SegPointer)
                {
                    renderer.WriteChar('*');
                }
                if (mem.SegOverride != RegisterStorage.None)
                {
                    RenderRegister(mem.SegOverride.Name, renderer);
                    renderer.WriteChar(':');
                }
                if (mem.Offset is not null && !mem.Offset.IsZero)
                {
                    string sOffset;
                    if (mem.Base == RegisterStorage.None && mem.Index == RegisterStorage.None)
                    {
                        sOffset = FormatUnsignedValue(mem.Offset.ToUInt64(), "{0:X}");
                    }
                    else
                    {
                        sOffset = FormatSignedValue(mem.Offset.ToInt64(), false);
                    }
                    renderer.WriteString(sOffset);
                }

                if (mem.Base != RegisterStorage.None)
                {
                    renderer.WriteChar('(');
                    RenderRegister(mem.Base.Name, renderer);
                }

                if (mem.Index != RegisterStorage.None)
                {
                    if (mem.Base == RegisterStorage.None)
                    {
                        renderer.WriteChar('(');
                    }
                    renderer.WriteChar(',');
                    RenderRegister(mem.Index.Name, renderer);
                    if (mem.Scale != 0)
                    {
                        renderer.WriteFormat(",{0}", mem.Scale);
                    }
                }
                renderer.WriteChar(')');
                break;

            case AddressOperand aop:
                var addr = aop.Address;
                if (options.SymbolResolver(addr, out string?name, out long symOffset))
                {
                    base.RenderSymbolReference(addr, name !, symOffset, renderer);
                }
                else if (addr.Selector.HasValue)
                {
                    switch (addr.DataType.BitSize)
                    {
                    case 32:
                        renderer.WriteFormat("$0x{0:X}, $0x{1:X}",
                                             addr.Selector.Value,
                                             addr.Offset & 0xFFFF);
                        break;

                    case 48:
                        renderer.WriteFormat("$0x{0:X}, $0x{1:X}",
                                             addr.Selector.Value,
                                             addr.Offset);
                        break;
                    }
                }
                else
                {
                    renderer.WriteAddress(FormatUnsignedValue(aop.Address.Offset, "${0}"), addr);
                }
                break;

            default: throw new NotImplementedException($"Not implemeted operand type {operand.GetType().Name}");
            }
        }
예제 #18
0
        public void EmitStringInstruction(X86Instruction instr, CodeEmitter emitter)
        {
            this.emitter = emitter;

            bool incSi = false;
            bool incDi = false;

            this.instrCur = instr;
            switch (instrCur.code)
            {
            default:
                throw new ApplicationException("NYI");

            case Mnemonic.cmps:
            case Mnemonic.cmpsb:
                emitter.Assign(
                    orw.FlagGroup(X86Instruction.DefCc(Mnemonic.cmp)),
                    new ConditionOf(
                        new BinaryExpression(Operator.ISub, instrCur.dataWidth, MemSi(), MemDi())));
                incSi = true;
                incDi = true;
                break;

            case Mnemonic.lods:
            case Mnemonic.lodsb:
                emitter.Assign(RegAl, MemSi());
                incSi = true;
                break;

            case Mnemonic.movs:
            case Mnemonic.movsb:
            {
                Identifier tmp = frame.CreateTemporary(instrCur.dataWidth);
                emitter.Assign(tmp, MemSi());
                emitter.Store(MemDi(), tmp);
                incSi = true;
                incDi = true;
                break;
            }

            case Mnemonic.ins:
            case Mnemonic.insb:
            {
                Identifier regDX = orw.AluRegister(Registers.edx, instrCur.addrWidth);
                emitter.Store(MemDi(), emitter.PseudoProc("__in", instrCur.dataWidth, regDX));
                incDi = true;
                break;
            }

            case Mnemonic.outs:
            case Mnemonic.outsb:
            {
                Identifier regDX = orw.AluRegister(Registers.edx, instrCur.addrWidth);
                emitter.SideEffect("__out" + RegAl.DataType.Prefix, regDX, RegAl);
                incSi = true;
                break;
            }

            case Mnemonic.scas:
            case Mnemonic.scasb:
                emitter.Assign(
                    orw.FlagGroup(X86Instruction.DefCc(Mnemonic.cmp)),
                    new ConditionOf(
                        new BinaryExpression(Operator.ISub,
                                             instrCur.dataWidth,
                                             RegAl,
                                             MemDi())));
                incDi = true;
                break;

            case Mnemonic.stos:
            case Mnemonic.stosb:
                emitter.Store(MemDi(), RegAl);
                incDi = true;
                break;
            }

            if (incSi)
            {
                emitter.Assign(RegSi,
                               new BinaryExpression(Operator.IAdd,
                                                    instrCur.addrWidth,
                                                    RegSi,
                                                    Constant.Create(instrCur.addrWidth, instrCur.dataWidth.Size)));
            }

            if (incDi)
            {
                emitter.Assign(RegDi,
                               new BinaryExpression(Operator.IAdd,
                                                    instrCur.addrWidth,
                                                    RegDi,
                                                    Constant.Create(instrCur.addrWidth, instrCur.dataWidth.Size)));
            }
        }
예제 #19
0
        public void Execute(X86Instruction instr)
        {
            if (instr.repPrefix == 2 && !ignoreRep)
            {
                // repne
                switch (instr.code)
                {
                case Opcode.scasb: Repne(); return;
                }
                throw new NotImplementedException();
            }
            switch (instr.code)
            {
            default:
                throw new NotImplementedException(string.Format("Instruction emulation for {0} not implemented yet.", instr));

            case Opcode.adc: Adc(instr.op1, instr.op2); return;

            case Opcode.add: Add(instr.op1, instr.op2); return;

            case Opcode.and: And(instr.op1, instr.op2); return;

            case Opcode.call: Call(instr.op1); return;

            case Opcode.cmp: Cmp(instr.op1, instr.op2); return;

            case Opcode.dec: Dec(instr.op1); return;

            case Opcode.hlt: running = false; return;

            case Opcode.inc: Inc(instr.op1); return;

            case Opcode.ja: if ((Flags & (Cmask | Zmask)) == 0)
                {
                    InstructionPointer = ((AddressOperand)instr.op1).Address;
                }
                return;

            case Opcode.jbe: if ((Flags & (Cmask | Zmask)) != 0)
                {
                    InstructionPointer = ((AddressOperand)instr.op1).Address;
                }
                return;

            case Opcode.jc: if ((Flags & Cmask) != 0)
                {
                    InstructionPointer = ((AddressOperand)instr.op1).Address;
                }
                return;

            case Opcode.jmp: Jump(instr.op1); return;

            case Opcode.jnc: if ((Flags & Cmask) == 0)
                {
                    InstructionPointer = ((AddressOperand)instr.op1).Address;
                }
                return;

            case Opcode.jnz: if ((Flags & Zmask) == 0)
                {
                    InstructionPointer = ((AddressOperand)instr.op1).Address;
                }
                return;

            case Opcode.jz: if ((Flags & Zmask) != 0)
                {
                    InstructionPointer = ((AddressOperand)instr.op1).Address;
                }
                return;

            case Opcode.lea: Write(instr.op1, GetEffectiveAddress((MemoryOperand)instr.op2)); break;

            case Opcode.loop: Loop(instr.op1); break;

            case Opcode.mov: Write(instr.op1, Read(instr.op2)); break;

            case Opcode.or: Or(instr.op1, instr.op2); return;

            case Opcode.pop: Write(instr.op1, Pop()); return;

            case Opcode.popa: Popa(); return;

            case Opcode.push: Push(Read(instr.op1)); return;

            case Opcode.pusha: Pusha(); return;

            case Opcode.rol: Rol(instr.op1, instr.op2); return;

            case Opcode.scasb: Scasb(); return;

            case Opcode.shl: Shl(instr.op1, instr.op2); return;

            case Opcode.shr: Shr(instr.op1, instr.op2); return;

            case Opcode.sub: Sub(instr.op1, instr.op2); return;

            case Opcode.xor: Xor(instr.op1, instr.op2); return;

            case Opcode.xchg: Xchg(instr.op1, instr.op2); return;
            }
        }
예제 #20
0
		private X86Instruction CreateMov(RegisterStorage regDst, RegisterStorage regSrc)
		{
            X86Instruction inst = new X86Instruction(
                Opcode.mov,
                PrimitiveType.Word16,
                PrimitiveType.Word16,
                new RegisterOperand(regDst),
                new RegisterOperand(regSrc));
			return inst;
		}
예제 #21
0
 public Expression CreateMemoryAccess(X86Instruction instr, MemoryOperand memoryOperand, X86State state)
 {
     return(CreateMemoryAccess(instr, memoryOperand, memoryOperand.Width, state));
 }
예제 #22
0
        /// <summary>
        /// Rewrites the current instruction as a string instruction.
        /// </summary>
        /// If a rep prefix is present, converts it into a loop:
        /// <code>
        /// while ([e]cx != 0)
        ///		[string instruction]
        ///		--ecx;
        ///		if (zF)				; only cmps[b] and scas[b]
        ///			goto follow;
        /// follow: ...
        /// </code>
        /// </summary>
        private void RewriteStringInstruction()
        {
            var        topOfLoop = instrCur.Address;
            Identifier regCX     = null;

            if (instrCur.repPrefix != 0)
            {
                regCX = orw.AluRegister(Registers.rcx, instrCur.addrWidth);
                m.BranchInMiddleOfInstruction(m.Eq0(regCX), instrCur.Address + instrCur.Length, RtlClass.ConditionalTransfer);
            }

            bool incSi       = false;
            bool incDi       = false;
            var  incOperator = GetIncrementOperator();

            Identifier regDX;

            switch (instrCur.code)
            {
            default:
                return;

            case Opcode.cmps:
            case Opcode.cmpsb:
                m.Assign(
                    orw.FlagGroup(X86Instruction.DefCc(Opcode.cmp)),
                    m.Cond(m.ISub(MemSi(), MemDi())));
                incSi = true;
                incDi = true;
                break;

            case Opcode.lods:
            case Opcode.lodsb:
                m.Assign(RegAl, MemSi());
                incSi = true;
                break;

            case Opcode.movs:
            case Opcode.movsb:
                Identifier tmp = binder.CreateTemporary(instrCur.dataWidth);
                m.Assign(tmp, MemSi());
                m.Assign(MemDi(), tmp);
                incSi = true;
                incDi = true;
                break;

            case Opcode.ins:
            case Opcode.insb:
                regDX = binder.EnsureRegister(Registers.dx);
                m.Assign(MemDi(), host.PseudoProcedure("__in", instrCur.dataWidth, regDX));
                incDi = true;
                break;

            case Opcode.outs:
            case Opcode.outsb:
                regDX = binder.EnsureRegister(Registers.dx);
                m.SideEffect(host.PseudoProcedure("__out" + RegAl.DataType.Prefix, VoidType.Instance, regDX, RegAl));
                incSi = true;
                break;

            case Opcode.scas:
            case Opcode.scasb:
                m.Assign(
                    orw.FlagGroup(X86Instruction.DefCc(Opcode.cmp)),
                    m.Cond(m.ISub(RegAl, MemDi())));
                incDi = true;
                break;

            case Opcode.stos:
            case Opcode.stosb:
                m.Assign(MemDi(), RegAl);
                incDi = true;
                break;
            }

            if (incSi)
            {
                m.Assign(RegSi, incOperator(RegSi, instrCur.dataWidth.Size));
            }

            if (incDi)
            {
                m.Assign(RegDi, incOperator(RegDi, instrCur.dataWidth.Size));
            }
            if (instrCur.repPrefix == 0)
            {
                return;
            }

            m.Assign(regCX, m.ISub(regCX, 1));

            switch (instrCur.code)
            {
            case Opcode.cmps:
            case Opcode.cmpsb:
            case Opcode.scas:
            case Opcode.scasb:
            {
                var cc = (instrCur.repPrefix == 2)
                        ? ConditionCode.NE
                        : ConditionCode.EQ;
                m.Branch(new TestCondition(cc, orw.FlagGroup(FlagM.ZF)).Invert(), topOfLoop, RtlClass.ConditionalTransfer);
                break;
            }

            default:
                m.Goto(topOfLoop);
                break;
            }
        }
예제 #23
0
		private X86Instruction CreatePush(RegisterStorage reg)
		{
            X86Instruction inst = new X86Instruction(
                Opcode.push,
                reg.DataType,
                reg.DataType,
                new RegisterOperand(reg));
			return inst;
		}
예제 #24
0
        private void RewriteMultiply(BinaryOperator op, Domain resultDomain)
        {
            Expression product;

            switch (instrCur.Operands)
            {
            case 1:
                Identifier multiplicator;

                switch (instrCur.op1.Width.Size)
                {
                case 1:
                    multiplicator = orw.AluRegister(Registers.al);
                    product       = orw.AluRegister(Registers.ax);
                    break;

                case 2:
                    multiplicator = orw.AluRegister(Registers.ax);
                    product       = binder.EnsureSequence(
                        Registers.dx, multiplicator.Storage, PrimitiveType.Word32);
                    break;

                case 4:
                    multiplicator = orw.AluRegister(Registers.eax);
                    product       = binder.EnsureSequence(
                        Registers.edx, multiplicator.Storage, PrimitiveType.Word64);
                    break;

                case 8:
                    multiplicator = orw.AluRegister(Registers.rax);
                    product       = binder.EnsureSequence(
                        Registers.rdx, multiplicator.Storage, PrimitiveType.Word64);
                    break;

                default:
                    throw new ApplicationException(string.Format("Unexpected operand size: {0}", instrCur.op1.Width));
                }
                ;
                m.Assign(
                    product,
                    new BinaryExpression(
                        op,
                        PrimitiveType.Create(resultDomain, product.DataType.Size),
                        SrcOp(instrCur.op1),
                        multiplicator));
                EmitCcInstr(product, X86Instruction.DefCc(instrCur.code));
                return;

            case 2:
                EmitBinOp(op, instrCur.op1, instrCur.op1.Width.MaskDomain(resultDomain), SrcOp(instrCur.op1), SrcOp(instrCur.op2),
                          CopyFlags.EmitCc);
                return;

            case 3:
                EmitBinOp(op, instrCur.op1, instrCur.op1.Width.MaskDomain(resultDomain), SrcOp(instrCur.op2), SrcOp(instrCur.op3),
                          CopyFlags.EmitCc);
                return;

            default:
                throw new ArgumentException("Invalid number of operands");
            }
        }
예제 #25
0
파일: X86Emulator.cs 프로젝트: relaxar/reko
 public void Execute(X86Instruction instr)
 {
     switch (instr.code)
     {
     default:
         throw new NotImplementedException(string.Format("Instruction emulation for {0} not implemented yet.", instr));
     case Opcode.adc: Adc(instr.op1, instr.op2); return;
     case Opcode.add: Add(instr.op1, instr.op2); return;
     case Opcode.and: And(instr.op1, instr.op2); return;
     case Opcode.call: Call(instr.op1); return;
     case Opcode.cmp: Cmp(instr.op1, instr.op2); return;
     case Opcode.dec: Dec(instr.op1); return;
     case Opcode.hlt: running = false; return;
     case Opcode.inc: Inc(instr.op1); return;
     case Opcode.ja: if ((Flags & (Cmask | Zmask)) == 0) InstructionPointer = ((AddressOperand)instr.op1).Address; return;
     case Opcode.jbe: if ((Flags & (Cmask | Zmask)) != 0) InstructionPointer = ((AddressOperand)instr.op1).Address; return;
     case Opcode.jc: if ((Flags & Cmask) != 0) InstructionPointer = ((AddressOperand)instr.op1).Address; return;
     case Opcode.jmp: Jump(instr.op1); return;
     case Opcode.jnc: if ((Flags & Cmask) == 0) InstructionPointer = ((AddressOperand)instr.op1).Address; return;
     case Opcode.jnz: if ((Flags & Zmask) == 0) InstructionPointer = ((AddressOperand)instr.op1).Address; return;
     case Opcode.jz: if ((Flags & Zmask) != 0) InstructionPointer = ((AddressOperand)instr.op1).Address; return;
     case Opcode.lea: Write(instr.op1, GetEffectiveAddress((MemoryOperand)instr.op2)); break;
     case Opcode.loop: Loop(instr.op1); break;
     case Opcode.mov: Write(instr.op1, Read(instr.op2)); break;
     case Opcode.or: Or(instr.op1, instr.op2); return;
     case Opcode.pop: Write(instr.op1, Pop()); return;
     case Opcode.popa: Popa(); return;
     case Opcode.push: Push(Read(instr.op1)); return;
     case Opcode.pusha: Pusha(); return;
     case Opcode.repne: Repne(); return;
     case Opcode.rol: Rol(instr.op1, instr.op2); return;
     case Opcode.scasb: Scasb(); return;
     case Opcode.shl: Shl(instr.op1, instr.op2); return;
     case Opcode.shr: Shr(instr.op1, instr.op2); return;
     case Opcode.sub: Sub(instr.op1, instr.op2); return;
     case Opcode.xor: Xor(instr.op1, instr.op2); return;
     case Opcode.xchg: Xchg(instr.op1, instr.op2); return;
     }
 }
예제 #26
0
 public Expression CreateMemoryAccess(X86Instruction instr, MemoryOperand memoryOperand, X86State state)
 {
     return CreateMemoryAccess(instr, memoryOperand, memoryOperand.Width, state);
 }
예제 #27
0
        /// <summary>
        /// Memory accesses are translated into expressions.
        /// </summary>
        /// <param name="mem"></param>
        /// <param name="state"></param>
        /// <returns></returns>
        public Expression EffectiveAddressExpression(X86Instruction instr, MemoryOperand mem, X86State state)
        {
            Expression eIndex = null;
            Expression eBase = null;
            Expression expr = null;
            PrimitiveType type = PrimitiveType.CreateWord(mem.Width.Size);
            bool ripRelative = false;

            if (mem.Base != RegisterStorage.None)
            {
                if (mem.Base == Registers.rip)
                {
                    ripRelative = true;
                }
                else
                {
                    eBase = AluRegister(mem.Base);
                    if (expr != null)
                    {
                        expr = new BinaryExpression(Operator.IAdd, eBase.DataType, eBase, expr);
                    }
                    else
                    {
                        expr = eBase;
                    }
                }
            }

            if (mem.Offset.IsValid)
            {
                if (ripRelative)
                {
                    expr = instr.Address + (instr.Length + mem.Offset.ToInt64());
                }
                else if (expr != null)
                {
                    BinaryOperator op = Operator.IAdd;
                    long l = mem.Offset.ToInt64();
                    if (l < 0 && l > -0x800)
                    {
                        l = -l;
                        op = Operator.ISub;
                    }

                    DataType dt = (eBase != null) ? eBase.DataType : eIndex.DataType;
                    Constant cOffset = Constant.Create(dt, l);
                    expr = new BinaryExpression(op, dt, expr, cOffset);
                }
                else
                {
                    expr = mem.Offset;
                }
            }

            if (mem.Index != RegisterStorage.None)
            {
                eIndex = AluRegister(mem.Index);
                if (mem.Scale != 0 && mem.Scale != 1)
                {
                    eIndex = new BinaryExpression(
                        Operator.IMul, eIndex.DataType, eIndex, Constant.Create(mem.Width, mem.Scale));
                }
                expr = new BinaryExpression(Operator.IAdd, expr.DataType, expr, eIndex);
            }
            return expr;
        }
예제 #28
0
        /// <summary>
        /// Iterator that yields one RtlIntructionCluster for each x86 instruction.
        /// </summary>
        /// <returns></returns>
        public IEnumerator <RtlInstructionCluster> GetEnumerator()
        {
            while (dasm.MoveNext())
            {
                instrCur = dasm.Current;
                var addr = instrCur.Address;
                this.len             = instrCur.Length;
                this.rtlInstructions = new List <RtlInstruction>();
                this.rtlc            = RtlClass.Linear;
                m   = new RtlEmitter(rtlInstructions);
                orw = arch.ProcessorMode.CreateOperandRewriter(arch, m, binder, host);
                switch (instrCur.code)
                {
                default:
                    host.Warn(
                        dasm.Current.Address,
                        "Rewriting x86 opcode '{0}' is not supported yet.",
                        instrCur.code);
                    goto case Opcode.illegal;

                case Opcode.illegal: rtlc = RtlClass.Invalid; m.Invalid(); break;

                case Opcode.aaa: RewriteAaa(); break;

                case Opcode.aad: RewriteAad(); break;

                case Opcode.aam: RewriteAam(); break;

                case Opcode.aas: RewriteAas(); break;

                case Opcode.adc: RewriteAdcSbb(m.IAdd); break;

                case Opcode.add: RewriteAddSub(Operator.IAdd); break;

                case Opcode.addss: RewriteScalarBinop(m.FAdd, PrimitiveType.Real32); break;

                case Opcode.addsd:
                case Opcode.vaddsd: RewriteScalarBinop(m.FAdd, PrimitiveType.Real64); break;

                case Opcode.addps: RewritePackedBinop("__addps", PrimitiveType.Real32); break;

                case Opcode.aesimc: RewriteAesimc(); break;

                case Opcode.and: RewriteLogical(Operator.And); break;

                case Opcode.arpl: RewriteArpl(); break;

                case Opcode.bound: RewriteBound(); break;

                case Opcode.bsr: RewriteBsr(); break;

                case Opcode.bswap: RewriteBswap(); break;

                case Opcode.bt: RewriteBt(); break;

                case Opcode.btr: RewriteBtr(); break;

                case Opcode.bts: RewriteBts(); break;

                case Opcode.call: RewriteCall(instrCur.op1, instrCur.op1.Width); break;

                case Opcode.cbw: RewriteCbw(); break;

                case Opcode.clc: RewriteSetFlag(FlagM.CF, Constant.False()); break;

                case Opcode.cld: RewriteSetFlag(FlagM.DF, Constant.False()); break;

                case Opcode.cli: RewriteCli(); break;

                case Opcode.cmc: m.Assign(orw.FlagGroup(FlagM.CF), m.Not(orw.FlagGroup(FlagM.CF))); break;

                case Opcode.cmova: RewriteConditionalMove(ConditionCode.UGT, instrCur.op1, instrCur.op2); break;

                case Opcode.cmovbe: RewriteConditionalMove(ConditionCode.ULE, instrCur.op1, instrCur.op2); break;

                case Opcode.cmovc: RewriteConditionalMove(ConditionCode.ULT, instrCur.op1, instrCur.op2); break;

                case Opcode.cmovge: RewriteConditionalMove(ConditionCode.GE, instrCur.op1, instrCur.op2); break;

                case Opcode.cmovg: RewriteConditionalMove(ConditionCode.GT, instrCur.op1, instrCur.op2); break;

                case Opcode.cmovl: RewriteConditionalMove(ConditionCode.LT, instrCur.op1, instrCur.op2); break;

                case Opcode.cmovle: RewriteConditionalMove(ConditionCode.LE, instrCur.op1, instrCur.op2); break;

                case Opcode.cmovnc: RewriteConditionalMove(ConditionCode.UGE, instrCur.op1, instrCur.op2); break;

                case Opcode.cmovno: RewriteConditionalMove(ConditionCode.NO, instrCur.op1, instrCur.op2); break;

                case Opcode.cmovns: RewriteConditionalMove(ConditionCode.NS, instrCur.op1, instrCur.op2); break;

                case Opcode.cmovnz: RewriteConditionalMove(ConditionCode.NE, instrCur.op1, instrCur.op2); break;

                case Opcode.cmovo: RewriteConditionalMove(ConditionCode.OV, instrCur.op1, instrCur.op2); break;

                case Opcode.cmovpe: RewriteConditionalMove(ConditionCode.PE, instrCur.op1, instrCur.op2); break;

                case Opcode.cmovpo: RewriteConditionalMove(ConditionCode.PO, instrCur.op1, instrCur.op2); break;

                case Opcode.cmovs: RewriteConditionalMove(ConditionCode.SG, instrCur.op1, instrCur.op2); break;

                case Opcode.cmovz: RewriteConditionalMove(ConditionCode.EQ, instrCur.op1, instrCur.op2); break;

                case Opcode.cmpxchg: RewriteCmpxchg(); break;

                case Opcode.cmp: RewriteCmp(); break;

                case Opcode.cmps: RewriteStringInstruction(); break;

                case Opcode.cmpsb: RewriteStringInstruction(); break;

                case Opcode.cpuid: RewriteCpuid(); break;

                case Opcode.cvtpi2ps: RewriteCvtPackedToReal(PrimitiveType.Real32); break;

                case Opcode.cvtsi2sd:
                case Opcode.vcvtsi2sd: RewriteCvtToReal(PrimitiveType.Real64); break;

                case Opcode.cvtsi2ss:
                case Opcode.vcvtsi2ss: RewriteCvtToReal(PrimitiveType.Real32); break;

                case Opcode.cvttsd2si: RewriteCvtts2si(PrimitiveType.Real64); break;

                case Opcode.cvttss2si: RewriteCvtts2si(PrimitiveType.Real32); break;

                case Opcode.cvttps2pi: RewriteCvttps2pi(); break;

                case Opcode.cwd: RewriteCwd(); break;

                case Opcode.daa: EmitDaaDas("__daa"); break;

                case Opcode.das: EmitDaaDas("__das"); break;

                case Opcode.dec: RewriteIncDec(-1); break;

                case Opcode.div: RewriteDivide(m.UDiv, Domain.UnsignedInt); break;

                case Opcode.divps: RewritePackedBinop("__divps", PrimitiveType.Real32); break;

                case Opcode.divsd: RewriteScalarBinop(m.FDiv, PrimitiveType.Real64); break;

                case Opcode.divss: RewriteScalarBinop(m.FDiv, PrimitiveType.Real32); break;

                case Opcode.f2xm1: RewriteF2xm1(); break;

                case Opcode.enter: RewriteEnter(); break;

                case Opcode.fabs: RewriteFabs(); break;

                case Opcode.fadd: EmitCommonFpuInstruction(m.FAdd, false, false); break;

                case Opcode.faddp: EmitCommonFpuInstruction(m.FAdd, false, true); break;

                case Opcode.fbld: RewriteFbld(); break;

                case Opcode.fbstp: RewriteFbstp(); break;

                case Opcode.fchs: EmitFchs(); break;

                case Opcode.fclex: RewriteFclex(); break;

                case Opcode.fcom: RewriteFcom(0); break;

                case Opcode.fcomp: RewriteFcom(1); break;

                case Opcode.fcompp: RewriteFcom(2); break;

                case Opcode.fcos: RewriteFUnary("cos"); break;

                case Opcode.fdecstp: RewriteFdecstp(); break;

                case Opcode.fdiv: EmitCommonFpuInstruction(m.FDiv, false, false); break;

                case Opcode.fdivp: EmitCommonFpuInstruction(m.FDiv, false, true); break;

                case Opcode.ffree: RewriteFfree(); break;

                case Opcode.fiadd: EmitCommonFpuInstruction(m.FAdd, false, false, PrimitiveType.Real64); break;

                case Opcode.ficom: RewriteFicom(false); break;

                case Opcode.ficomp: RewriteFicom(true); break;

                case Opcode.fimul: EmitCommonFpuInstruction(m.FMul, false, false, PrimitiveType.Real64); break;

                case Opcode.fisub: EmitCommonFpuInstruction(m.FSub, false, false, PrimitiveType.Real64); break;

                case Opcode.fisubr: EmitCommonFpuInstruction(m.FSub, true, false, PrimitiveType.Real64); break;

                case Opcode.fidiv: EmitCommonFpuInstruction(m.FDiv, false, false, PrimitiveType.Real64); break;

                case Opcode.fidivr: EmitCommonFpuInstruction(m.FDiv, true, false, PrimitiveType.Real64); break;

                case Opcode.fdivr: EmitCommonFpuInstruction(m.FDiv, true, false); break;

                case Opcode.fdivrp: EmitCommonFpuInstruction(m.FDiv, true, true); break;

                case Opcode.fild: RewriteFild(); break;

                case Opcode.fincstp: RewriteFincstp(); break;

                case Opcode.fist: RewriteFist(false); break;

                case Opcode.fistp: RewriteFist(true); break;

                case Opcode.fld: RewriteFld(); break;

                case Opcode.fld1: RewriteFldConst(1.0); break;

                case Opcode.fldcw: RewriteFldcw(); break;

                case Opcode.fldenv: RewriteFldenv(); break;

                case Opcode.fldl2e: RewriteFldConst(Constant.LgE()); break;

                case Opcode.fldl2t: RewriteFldConst(Constant.Lg10()); break;

                case Opcode.fldlg2: RewriteFldConst(Constant.Log2()); break;

                case Opcode.fldln2: RewriteFldConst(Constant.Ln2()); break;

                case Opcode.fldpi: RewriteFldConst(Constant.Pi()); break;

                case Opcode.fldz: RewriteFldConst(0.0); break;

                case Opcode.fmul: EmitCommonFpuInstruction(m.FMul, false, false); break;

                case Opcode.fmulp: EmitCommonFpuInstruction(m.FMul, false, true); break;

                case Opcode.fninit: RewriteFninit(); break;

                case Opcode.fpatan: RewriteFpatan(); break;

                case Opcode.fprem: RewriteFprem(); break;

                case Opcode.fptan: RewriteFptan(); break;

                case Opcode.frndint: RewriteFUnary("__rndint"); break;

                case Opcode.frstor: RewriteFrstor(); break;

                case Opcode.fsave: RewriteFsave(); break;

                case Opcode.fscale: RewriteFscale(); break;

                case Opcode.fsin: RewriteFUnary("sin"); break;

                case Opcode.fsincos: RewriteFsincos(); break;

                case Opcode.fsqrt: RewriteFUnary("sqrt"); break;

                case Opcode.fst: RewriteFst(false); break;

                case Opcode.fstenv: RewriteFstenv(); break;

                case Opcode.fstcw: RewriterFstcw(); break;

                case Opcode.fstp: RewriteFst(true); break;

                case Opcode.fstsw: RewriteFstsw(); break;

                case Opcode.fsub: EmitCommonFpuInstruction(m.FSub, false, false); break;

                case Opcode.fsubp: EmitCommonFpuInstruction(m.FSub, false, true); break;

                case Opcode.fsubr: EmitCommonFpuInstruction(m.FSub, true, false); break;

                case Opcode.fsubrp: EmitCommonFpuInstruction(m.FSub, true, true); break;

                case Opcode.ftst: RewriteFtst(); break;

                case Opcode.fucomi: RewrteFucomi(false); break;

                case Opcode.fucomip: RewrteFucomi(true); break;

                case Opcode.fucompp: RewriteFcom(2); break;

                case Opcode.fxam: RewriteFxam(); break;

                case Opcode.fxch: RewriteExchange(); break;

                case Opcode.fyl2x: RewriteFyl2x(); break;

                case Opcode.fyl2xp1: RewriteFyl2xp1(); break;

                case Opcode.hlt: RewriteHlt(); break;

                case Opcode.idiv: RewriteDivide(m.SDiv, Domain.SignedInt); break;

                case Opcode.@in: RewriteIn(); break;

                case Opcode.imul: RewriteMultiply(Operator.SMul, Domain.SignedInt); break;

                case Opcode.inc: RewriteIncDec(1); break;

                case Opcode.insb: RewriteStringInstruction(); break;

                case Opcode.ins: RewriteStringInstruction(); break;

                case Opcode.@int: RewriteInt(); break;

                case Opcode.into: RewriteInto(); break;

                case Opcode.iret: RewriteIret(); break;

                case Opcode.jmp: RewriteJmp(); break;

                case Opcode.ja: RewriteConditionalGoto(ConditionCode.UGT, instrCur.op1); break;

                case Opcode.jbe: RewriteConditionalGoto(ConditionCode.ULE, instrCur.op1); break;

                case Opcode.jc: RewriteConditionalGoto(ConditionCode.ULT, instrCur.op1); break;

                case Opcode.jcxz: RewriteJcxz(); break;

                case Opcode.jge: RewriteConditionalGoto(ConditionCode.GE, instrCur.op1); break;

                case Opcode.jg: RewriteConditionalGoto(ConditionCode.GT, instrCur.op1); break;

                case Opcode.jl: RewriteConditionalGoto(ConditionCode.LT, instrCur.op1); break;

                case Opcode.jle: RewriteConditionalGoto(ConditionCode.LE, instrCur.op1); break;

                case Opcode.jnc: RewriteConditionalGoto(ConditionCode.UGE, instrCur.op1); break;

                case Opcode.jno: RewriteConditionalGoto(ConditionCode.NO, instrCur.op1); break;

                case Opcode.jns: RewriteConditionalGoto(ConditionCode.NS, instrCur.op1); break;

                case Opcode.jnz: RewriteConditionalGoto(ConditionCode.NE, instrCur.op1); break;

                case Opcode.jo: RewriteConditionalGoto(ConditionCode.OV, instrCur.op1); break;

                case Opcode.jpe: RewriteConditionalGoto(ConditionCode.PE, instrCur.op1); break;

                case Opcode.jpo: RewriteConditionalGoto(ConditionCode.PO, instrCur.op1); break;

                case Opcode.js: RewriteConditionalGoto(ConditionCode.SG, instrCur.op1); break;

                case Opcode.jz: RewriteConditionalGoto(ConditionCode.EQ, instrCur.op1); break;

                case Opcode.lahf: RewriteLahf(); break;

                case Opcode.lds: RewriteLxs(Registers.ds); break;

                case Opcode.lea: RewriteLea(); break;

                case Opcode.leave: RewriteLeave(); break;

                case Opcode.les: RewriteLxs(Registers.es); break;

                case Opcode.lfence: RewriteLfence(); break;

                case Opcode.lfs: RewriteLxs(Registers.fs); break;

                case Opcode.lgs: RewriteLxs(Registers.gs); break;

                case Opcode.@lock: RewriteLock(); break;

                case Opcode.lods: RewriteStringInstruction(); break;

                case Opcode.lodsb: RewriteStringInstruction(); break;

                case Opcode.loop: RewriteLoop(0, ConditionCode.EQ); break;

                case Opcode.loope: RewriteLoop(FlagM.ZF, ConditionCode.EQ); break;

                case Opcode.loopne: RewriteLoop(FlagM.ZF, ConditionCode.NE); break;

                case Opcode.lss: RewriteLxs(Registers.ss); break;

                case Opcode.mfence: RewriteMfence(); break;

                case Opcode.mov: RewriteMov(); break;

                case Opcode.movapd:
                case Opcode.movaps:
                case Opcode.vmovapd:
                case Opcode.vmovaps: RewriteMov(); break;

                case Opcode.movd: RewriteMovzx(); break;

                case Opcode.movdqa: RewriteMov(); break;

                case Opcode.movlhps: RewriteMovlhps(); break;

                case Opcode.movq: RewriteMov(); break;

                case Opcode.movs: RewriteStringInstruction(); break;

                case Opcode.movsb: RewriteStringInstruction(); break;

                case Opcode.movsd:
                case Opcode.vmovsd:  RewriteMovssd(PrimitiveType.Real64); break;

                case Opcode.movss:
                case Opcode.vmovss: RewriteMovssd(PrimitiveType.Real32); break;

                case Opcode.movsx: RewriteMovsx(); break;

                case Opcode.movups: RewriteMov(); break;

                case Opcode.movupd: RewriteMov(); break;

                case Opcode.movzx: RewriteMovzx(); break;

                case Opcode.mul: RewriteMultiply(Operator.UMul, Domain.UnsignedInt); break;

                case Opcode.mulpd: RewritePackedBinop("__mulpd", PrimitiveType.Real64); break;

                case Opcode.mulps: RewritePackedBinop("__mulps", PrimitiveType.Real32); break;

                case Opcode.mulss: RewriteScalarBinop(m.FMul, PrimitiveType.Real32); break;

                case Opcode.mulsd: RewriteScalarBinop(m.FMul, PrimitiveType.Real64); break;

                case Opcode.neg: RewriteNeg(); break;

                case Opcode.nop: m.Nop(); break;

                case Opcode.not: RewriteNot(); break;

                case Opcode.or: RewriteLogical(BinaryOperator.Or); break;

                case Opcode.@out: RewriteOut(); break;

                case Opcode.@outs: RewriteStringInstruction(); break;

                case Opcode.@outsb: RewriteStringInstruction(); break;

                case Opcode.pause: RewritePause(); break;

                case Opcode.palignr: RewritePalignr(); break;

                case Opcode.pcmpeqb: RewritePcmpeqb(); break;

                case Opcode.pop: RewritePop(); break;

                case Opcode.popa: RewritePopa(); break;

                case Opcode.popf: RewritePopf(); break;

                case Opcode.prefetchnta: RewritePrefetch("__prefetchnta"); break;

                case Opcode.prefetcht0: RewritePrefetch("__prefetcht0"); break;

                case Opcode.prefetcht1: RewritePrefetch("__prefetcht1"); break;

                case Opcode.prefetcht2: RewritePrefetch("__prefetcht2"); break;

                case Opcode.pshufd: RewritePshufd(); break;

                case Opcode.punpcklbw: RewritePunpcklbw(); break;

                case Opcode.punpcklwd: RewritePunpcklwd(); break;

                case Opcode.push: RewritePush(); break;

                case Opcode.pusha: RewritePusha(); break;

                case Opcode.pushf: RewritePushf(); break;

                case Opcode.pxor: RewritePxor(); break;

                case Opcode.rcl: RewriteRotation(PseudoProcedure.RolC, true, true); break;

                case Opcode.rcr: RewriteRotation(PseudoProcedure.RorC, true, false); break;

                case Opcode.rol: RewriteRotation(PseudoProcedure.Rol, false, true); break;

                case Opcode.ror: RewriteRotation(PseudoProcedure.Ror, false, false); break;

                case Opcode.rdtsc: RewriteRdtsc(); break;

                case Opcode.ret: RewriteRet(); break;

                case Opcode.retf: RewriteRet(); break;

                case Opcode.sahf: m.Assign(orw.FlagGroup(X86Instruction.DefCc(instrCur.code)), orw.AluRegister(Registers.ah)); break;

                case Opcode.sar: RewriteBinOp(Operator.Sar); break;

                case Opcode.sbb: RewriteAdcSbb(m.ISub); break;

                case Opcode.scas: RewriteStringInstruction(); break;

                case Opcode.scasb: RewriteStringInstruction(); break;

                case Opcode.seta: RewriteSet(ConditionCode.UGT); break;

                case Opcode.setc: RewriteSet(ConditionCode.ULT); break;

                case Opcode.setbe: RewriteSet(ConditionCode.ULE); break;

                case Opcode.setg: RewriteSet(ConditionCode.GT); break;

                case Opcode.setge: RewriteSet(ConditionCode.GE); break;

                case Opcode.setl: RewriteSet(ConditionCode.LT); break;

                case Opcode.setle: RewriteSet(ConditionCode.LE); break;

                case Opcode.setnc: RewriteSet(ConditionCode.UGE); break;

                case Opcode.setno: RewriteSet(ConditionCode.NO); break;

                case Opcode.setns: RewriteSet(ConditionCode.NS); break;

                case Opcode.setnz: RewriteSet(ConditionCode.NE); break;

                case Opcode.setpe: RewriteSet(ConditionCode.PE); break;

                case Opcode.setpo: RewriteSet(ConditionCode.PO); break;

                case Opcode.seto: RewriteSet(ConditionCode.OV); break;

                case Opcode.sets: RewriteSet(ConditionCode.SG); break;

                case Opcode.setz: RewriteSet(ConditionCode.EQ); break;

                case Opcode.shl: RewriteBinOp(BinaryOperator.Shl); break;

                case Opcode.shld: RewriteShxd("__shld"); break;

                case Opcode.shr: RewriteBinOp(BinaryOperator.Shr); break;

                case Opcode.shrd: RewriteShxd("__shrd"); break;

                case Opcode.stc: RewriteSetFlag(FlagM.CF, Constant.True()); break;

                case Opcode.std: RewriteSetFlag(FlagM.DF, Constant.True()); break;

                case Opcode.sti: RewriteSti(); break;

                case Opcode.stos: RewriteStringInstruction(); break;

                case Opcode.stosb: RewriteStringInstruction(); break;

                case Opcode.sub: RewriteAddSub(BinaryOperator.ISub); break;

                case Opcode.subsd: RewriteScalarBinop(m.FSub, PrimitiveType.Real64); break;

                case Opcode.subss: RewriteScalarBinop(m.FSub, PrimitiveType.Real32); break;

                case Opcode.subps: RewritePackedBinop("__subps", PrimitiveType.Real32); break;

                case Opcode.ucomiss: RewriteComis(PrimitiveType.Real32); break;

                case Opcode.ucomisd: RewriteComis(PrimitiveType.Real64); break;

                case Opcode.test: RewriteTest(); break;

                case Opcode.wait: RewriteWait(); break;

                case Opcode.xadd: RewriteXadd(); break;

                case Opcode.xchg: RewriteExchange(); break;

                case Opcode.xgetbv: RewriteXgetbv(); break;

                case Opcode.xsetbv: RewriteXsetbv(); break;

                case Opcode.xlat: RewriteXlat(); break;

                case Opcode.xor: RewriteLogical(BinaryOperator.Xor); break;

                case Opcode.xorpd:
                case Opcode.vxorpd: RewritePackedBinop("__xorpd", PrimitiveType.Word64); break;

                case Opcode.xorps: RewritePackedBinop("__xorps", PrimitiveType.Word32); break;

                case Opcode.BOR_exp: RewriteFUnary("exp"); break;

                case Opcode.BOR_ln: RewriteFUnary("log"); break;
                }
                yield return(new RtlInstructionCluster(addr, len, rtlInstructions.ToArray())
                {
                    Class = rtlc
                });
            }
        }