예제 #1
0
 public MachineInstructionRendererOptions(
     string?syntax = "",
     MachineInstructionRendererFlags flags = MachineInstructionRendererFlags.None,
     string?operandSeparator = ",",
     IPlatform?platform      = null)
 {
     this.Syntax           = syntax;
     this.Flags            = flags;
     this.OperandSeparator = operandSeparator;
     this.Platform         = platform;
 }
예제 #2
0
        protected void RenderMemory(
            MemoryOperand mem,
            MachineInstructionRenderer renderer,
            MachineInstructionRendererFlags flags)
        {
            if ((flags & MachineInstructionRendererFlags.ExplicitOperandSize) != 0)
            {
                var s = ExplicitOperandPrefix(mem.Width);
                renderer.WriteString(s);
            }

            if (mem.SegOverride != RegisterStorage.None)
            {
                RenderRegister(mem.SegOverride.Name, renderer);
                renderer.WriteString(":");
            }
            renderer.WriteString("[");
            if (mem.Base != RegisterStorage.None)
            {
                RenderRegister(mem.Base.Name, renderer);
            }
            else
            {
                var s = FormatUnsignedValue(mem.Offset !.ToUInt64(), "{0:X4}");
                renderer.WriteAddress(s, Address.FromConstant(mem.Offset !));
            }

            if (mem.Index != RegisterStorage.None)
            {
                renderer.WriteString("+");
                RenderRegister(mem.Index.Name, renderer);
                if (mem.Scale > 1)
                {
                    renderer.WriteString("*");
                    renderer.WriteUInt32(mem.Scale);
                }
            }
            if (mem.Base != RegisterStorage.None && mem.Offset != null && mem.Offset.IsValid)
            {
                if (mem.Offset.DataType == PrimitiveType.Byte || mem.Offset.DataType == PrimitiveType.SByte)
                {
                    renderer.WriteString(FormatSignedValue(mem.Offset.ToInt64(), true));
                }
                else
                {
                    var off = mem.Offset.ToInt32();
                    if (off == Int32.MinValue)
                    {
                        renderer.WriteString("-80000000h");
                    }
                    else
                    {
                        var absOff = Math.Abs(off);
                        if (mem.Offset.DataType.Size > 2 && off < 0 && absOff < 0x10000)
                        {
                            // Special case for negative 32-bit offsets whose
                            // absolute value < 0x10000 (GitHub issue #252)
                            renderer.WriteString("-");
                            renderer.WriteFormat(FormatUnsignedValue((ulong)absOff));
                        }
                        else
                        {
                            renderer.WriteString("+");
                            renderer.WriteString(FormatUnsignedValue(mem.Offset.ToUInt64()));
                        }
                    }
                }
            }
            renderer.WriteString("]");
        }
예제 #3
0
        protected virtual void RenderOperand(MachineOperand operand, X86Instruction instr, MachineInstructionRenderer renderer, MachineInstructionRendererFlags flags)
        {
            switch (operand)
            {
            case RegisterOperand reg:
                RenderRegister(reg.Register.Name, renderer);
                break;

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

            case MemoryOperand memOp:
                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);
            }
        }