Esempio n. 1
0
        public static OpcodeEncoder AppendConditionalDisplacement(this OpcodeEncoder encoder, Operand displacement, bool include)
        {
            if (!include)
                return encoder;

            if (Is8BitDisplacement(displacement))
                return encoder.AppendByteValue((byte)displacement.ConstantUnsignedInteger);

            return encoder.AppendIntegerValue(displacement.ConstantUnsignedInteger);
        }
Esempio n. 2
0
        public static OpcodeEncoder AppendInteger(this OpcodeEncoder encoder, Operand operand, InstructionSize size)
        {
            if (size == InstructionSize.Size32)
                return encoder.AppendIntegerValue(operand.ConstantUnsignedInteger);
            if (size == InstructionSize.Size8)
                return encoder.AppendByteValue((byte)operand.ConstantUnsignedInteger);
            if (size == InstructionSize.Size16)
                return encoder.AppendShortValue((ushort)operand.ConstantUnsignedInteger);

            throw new InvalidCompilerException("Instruction size invalid");
        }
Esempio n. 3
0
        public static OpcodeEncoder ModRegRMSIBDisplacement(this OpcodeEncoder encoder, bool offsetDestination, Operand destination, Operand source, Operand offset)
        {
            if (offsetDestination && source.IsConstant)
            {
                var baseEBP = destination.Register == GeneralPurposeRegister.EBP;
                if (baseEBP)
                {
                    if (offset.IsCPURegister || Is8BitDisplacement(offset))
                    {
                        encoder.AppendMod(Bits.b01);                                    // 2:mod
                    }
                    else
                    {
                        encoder.AppendMod(Bits.b10);                                    // 2:mod
                    }
                }
                else
                {
                    encoder.AppendMod(true, offset);                                    // 2:mod
                }

                encoder.AppendRegister(Bits.b000);                                      // 3:register (destination)

                if (offset.IsCPURegister)
                {
                    encoder.AppendRM(Bits.b100);                                        // 3:r/m (source)
                    encoder.AppendSIB(1, offset.Register, destination.Register);        // 8:sib (scale, index, base)
                    if (baseEBP)
                    {
                        encoder.AppendByteValue(0x0);                                   // 8:displacement value
                    }
                }
                else if (destination.Register == GeneralPurposeRegister.ESP)
                {
                    // When destination is ESP we must use SIB
                    encoder.AppendRM(Bits.b100);                                        // 3:r/m (source)
                    encoder.AppendSIB(1, destination.Register, destination.Register);   // 8:sib (scale, index, base)
                    encoder.AppendConditionalDisplacement(offset);                      // 8/32:displacement value
                }
                else
                {
                    encoder.AppendRM(destination);                                      // 3:r/m (source)
                    if (baseEBP)
                    {
                        encoder.AppendConditionalDisplacement(true, offset);                     // 8/32:displacement value
                    }
                    else
                    {
                        encoder.AppendConditionalDisplacement(offset);                  // 8/32:displacement value
                    }
                }
            }
            else if (offset.IsConstant)
            {
                // When source is ESP we must use SIB
                encoder.AppendMod(true, offset);                                        // 2:mod
                encoder.AppendRegister(destination.Register);                           // 3:register (destination)
                if (source.Register == GeneralPurposeRegister.ESP)
                {
                    encoder.AppendRM(Bits.b100);                                        // 3:r/m (source)
                    encoder.AppendSIB(1, source.Register, source.Register);             // 8:sib (scale, index, base)
                }
                else
                {
                    encoder.AppendRM(source);                                           // 3:r/m (source)
                }
                encoder.AppendConditionalDisplacement(offset);                          // 8/32:displacement value
            }
            else
            {
                // When EBP is the base we must set the mod to either:
                // b01 with a 1 byte displacement
                // b10 with a 4 byte displacement
                var @base = offsetDestination ? destination : source;
                var baseEBP = @base.Register == GeneralPurposeRegister.EBP;

                encoder.AppendMod(baseEBP ? Bits.b01 : Bits.b00);                       // 2:mod
                encoder.AppendRegister(destination.Register);                           // 3:register (destination)
                encoder.AppendRM(Bits.b100);                                            // 3:r/m (source)
                encoder.AppendSIB(1, offset.Register, @base.Register);                  // 8:sib (scale, index, base)
                if (baseEBP)
                {
                    encoder.AppendByteValue(0x0);                                       // 8:displacement value
                }
            }

            return encoder;
        }