Ejemplo n.º 1
0
		public static EffectiveAddress Indirect(
			AddressSize addressSize, SegmentRegister? segment,
			AddressBaseRegister @base, int displacement = 0)
			=> Indirect(addressSize, segment, @base, index: null, scale: 1, displacement: displacement);
Ejemplo n.º 2
0
		public static EffectiveAddress Indirect(
			AddressSize addressSize, SegmentRegister? segment, 
			AddressBaseRegister? @base, GprCode? index = null, byte scale = 1, int displacement = 0)
		{
			Contract.Requires(scale == 1 || scale == 2 || scale == 4 || scale == 8
				|| (scale == 0 && !index.HasValue));
			Contract.Requires(@base != AddressBaseRegister.Rip || (addressSize != AddressSize._16 && index.HasValue));
			if (addressSize == AddressSize._16)
			{
				Contract.Requires(!(@base >= AddressBaseRegister.R8));
				Contract.Requires(!(index >= GprCode.R8));
				Contract.Requires((short)displacement == displacement);
				if (@base.HasValue)
				{
					if (index.HasValue)
					{
						Contract.Requires(@base == AddressBaseRegister.B || @base == AddressBaseRegister.BP);
						Contract.Requires(index.Value == GprCode.SI || index.Value == GprCode.DI);
					}
					else
					{
						Contract.Requires(@base == AddressBaseRegister.SI || @base == AddressBaseRegister.DI
							|| @base == AddressBaseRegister.BP || @base == AddressBaseRegister.B);
					}
				}
				else
				{
					Contract.Requires(!index.HasValue);
				}
			}
			else
			{
				Contract.Requires(index != GprCode.Esp);
			}

			// Segment defaults to D, or S if we are using a stack-pointing register
			if (!segment.HasValue)
			{
				segment = (@base == AddressBaseRegister.SP || @base == AddressBaseRegister.BP)
					? SegmentRegister.SS : SegmentRegister.DS;
			}

			var flags = BaseFlags(addressSize, segment.Value);

			if (@base.HasValue) flags |= (Flags)(((int)@base + 1) << (int)Flags.BaseReg_Shift);
			if (index.HasValue)
			{
				// Swap eax and esp (esp meaning "none")
				if (index.Value == GprCode.Eax) flags |= Flags.IndexReg_Eax;
				else flags |= (Flags)((int)index.Value << (int)Flags.IndexReg_Shift);
			}

			if (scale == 2) flags |= Flags.Scale_2x;
			else if (scale == 4) flags |= Flags.Scale_4x;
			else if (scale == 8) flags |= Flags.Scale_8x;
			return new EffectiveAddress(flags, displacement);
		}