public void X86Orw16_RewriteSegConst()
		{
			var m = new MemoryOperand(
				PrimitiveType.Byte,
				Registers.bx,
				Constant.Int32(32));
			var e = orw.CreateMemoryAccess(instr, m, state);
			Assert.AreEqual("Mem0[ds:bx + 0x0020:byte]", e.ToString());
		}
예제 #2
0
		private Constant EmitDirectAddress(int reg, MemoryOperand memOp)
		{
			Debug.Assert(memOp.Offset.IsValid);
			if (defaultWordSize == PrimitiveType.Word16)
			{
				reg |= 0x6;
				emitter.EmitByte(reg);
				return Constant.Create(PrimitiveType.Word16, memOp.Offset.ToUInt32());
			}
			else
			{
				reg |= 0x5;
				emitter.EmitByte(reg);
				return Constant.Word32(memOp.Offset.ToUInt32());
			}
		}
예제 #3
0
 public ExternalProcedure ImportedProcedureName(Address addrInstruction, PrimitiveType addrWidth, MemoryOperand mem)
 {
     if (mem != null && addrWidth == PrimitiveType.Word32 && mem.Base == RegisterStorage.None &&
         mem.Index == RegisterStorage.None)
     {
         return host.GetImportedProcedure(Address.Ptr32(mem.Offset.ToUInt32()), addrInstruction);
     }
     return null;
 }
예제 #4
0
        /// <summary>
        /// Memory accesses are translated into expressions.
        /// </summary>
        /// <param name="mem"></param>
        /// <param name="state"></param>
        /// <returns></returns>
        public Expression EffectiveAddressExpression(IntelInstruction 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;
        }
예제 #5
0
 public Expression CreateMemoryAccess(IntelInstruction instr, MemoryOperand memoryOperand, X86State state)
 {
     return CreateMemoryAccess(instr, memoryOperand, memoryOperand.Width, state);
 }
예제 #6
0
		public void X86Orw32_IndexedAccess()
		{
			MemoryOperand mem = new MemoryOperand(PrimitiveType.Word32, Registers.eax, Registers.edx, 4, Constant.Word32(0x24));
			Expression expr = orw.Transform(instr, mem, PrimitiveType.Word32, state);
			Assert.AreEqual("Mem0[eax + 0x00000024 + edx * 0x00000004:word32]", expr.ToString());
		}
예제 #7
0
        public void X86Orw32_MemAccess()
		{
			MemoryOperand mem = new MemoryOperand(PrimitiveType.Word32);
			mem.Base = Registers.ecx;
			mem.Offset = Constant.Word32(4);
			Expression expr = orw.Transform(instr, mem, PrimitiveType.Word32, state);
			Assert.AreEqual("Mem0[ecx + 0x00000004:word32]", expr.ToString());
		}	
예제 #8
0
 private ParsedOperand Mem(
     PrimitiveType width, 
     SegmentRegister seg, 
     RegisterStorage @base,  
     RegisterStorage index, 
     int scale, 
     string offset)
 {
     int val;
     MemoryOperand mem;
     Symbol sym = null;
     if (offset != null)
     {
         if (symtab.Equates.TryGetValue(offset, out val))
         {
             mem = new MemoryOperand(width, @base, IntegralConstant(val, @base.DataType));
             sym = null;
         }
         else
         {
             sym = symtab.CreateSymbol(offset);
             val = (int)this.addrBase.Offset;
             Constant off = Constant.Create(@base == null
                 ? seg != null ? PrimitiveType.Word16 : PrimitiveType.Word32
                 : @base.DataType,
                 val);
             mem = new MemoryOperand(width, @base ?? RegisterStorage.None, off);
         }
     }
     else
     {
         mem = new MemoryOperand(width)
         {
         };
     }
     if (seg != null)
     {
         mem.SegOverride = seg;
         this.SegmentOverride = seg;
     }
     mem.Scale = (byte)scale;
     if (scale > 1)
     {
         if (index == null)
         {
             mem.Index = mem.Base;
             mem.Base = RegisterStorage.None;
         }
         else
         {
             mem.Index = index;
             mem.Base = @base;
         }
     }
     return new ParsedOperand(mem, sym);
 }
예제 #9
0
		/// <summary>
		/// Emits the ModRM byte (and SIB byte if applicable)
		/// </summary>
		/// <param name="reg"></param>
		/// <param name="memOp"></param>
		/// <returns>The offset value to be emitted as the last piece of the instructon</returns>
		public Constant EmitModRMPrefix(int reg, MemoryOperand memOp)
		{
			offset = null;
			reg <<= 3;
			if (memOp.Base != RegisterStorage.None || memOp.Index != RegisterStorage.None)
			{
				PrimitiveType baseWidth = memOp.Base.DataType;
				PrimitiveType indexWidth = memOp.Index.DataType;
				if (memOp.Base != RegisterStorage.None && memOp.Index != RegisterStorage.None)
				{
					if (baseWidth != indexWidth)
					{
						OnError("mismatched base and index registers");
						return null;
					}
				}

				// Add the 'mod' bits

				if (memOp.Offset != null)
				{
					Debug.Assert(memOp.Offset.IsValid);
					if (memOp.Offset.DataType == PrimitiveType.SByte)
					{
						reg |= 0x40;
						offset = memOp.Offset;
					}
					else
					{
						reg |= 0x80;
						offset = Constant.Create(defaultWordSize, memOp.Offset.ToInt32());
					}
				}

				bool fNeedsSib = false;
				int sib = 0;
				if (baseWidth == PrimitiveType.Word16)
				{
					reg |= Get16AddressingModeMask(memOp);
				}
				else if (baseWidth == PrimitiveType.Word32 || indexWidth == PrimitiveType.Word32)
				{
					if (memOp.Index == RegisterStorage.None)
					{
						if (memOp.Base != Registers.esp)
						{
							reg |= X86Assembler.RegisterEncoding(memOp.Base);
							if (memOp.Offset == null && memOp.Base == Registers.ebp)
							{
								reg |= 0x40;
								offset = Constant.Byte(0);
							}
						}
						else
						{
							reg |= 0x04;
							fNeedsSib = true;
							sib = 0x24;
						}
					}
					else
					{
						reg |= 0x04;
						fNeedsSib = true;
						switch (memOp.Scale)
						{
						case 1: sib = 0; break;
						case 2: sib = 0x40; break;
						case 4: sib = 0x80; break;
						case 8: sib = 0xC0; break;
						default: OnError("Scale factor must be 1, 2, 4, or 8"); return Constant.Invalid;
						}

						if (memOp.Base == RegisterStorage.None)
						{
							sib |= 0x05;
							reg &= ~0xC0;			// clear mod part of modRM.

							if (memOp.Offset == null)
							{
								offset = Constant.Word32(0);
							}
						}
						else
						{
							sib |= X86Assembler.RegisterEncoding(memOp.Base);
						}

						if (memOp.Index != Registers.esp)
						{
							sib |= X86Assembler.RegisterEncoding(memOp.Index) << 3;
						}
						else
							throw new ApplicationException("ESP register can't be used as an index register");
					}
				}
				else
				{
					throw new ApplicationException("unexpected address width");
				}

				emitter.EmitByte(reg);
				if (fNeedsSib)
					emitter.EmitByte(sib);
				return offset;

			}
			else
				return EmitDirectAddress(reg, memOp);
		}
예제 #10
0
		private ParsedOperand ParseMemoryOperand(RegisterStorage segOver)
		{
            MemoryOperand memOp = new MemoryOperand(null);
			memOp.SegOverride = segOver;
			this.segOverride = segOver;

			ParseMemoryFactor(memOp);
			for (;;)
			{
				Token token = lexer.GetToken();
				switch (token)
				{
				default: 
					OnError("Unexpected token: " + token);
					return null;
				case Token.KET:
					if (totalInt != 0 || sym != null)
					{
						if (addrWidth == null || sym != null)
							memOp.Offset = Constant.Create(defaultAddressWidth, totalInt);
						else
							memOp.Offset = X86Assembler.IntegralConstant(totalInt, addrWidth);
					}
					return new ParsedOperand(memOp, sym);
				case Token.PLUS:
					break;
				case Token.MINUS:
					Expect(Token.INTEGER);
					totalInt -= lexer.Integer;
					continue;
				case Token.ID:
					break;
				}
				ParseMemoryFactor(memOp);
			} 
		}
예제 #11
0
		public int Get16AddressingModeMask(MemoryOperand memOp)
		{
			int mask = (1 << memOp.Base.Number);
			if (memOp.Index != RegisterStorage.None)
			{
				mask |= (1 << memOp.Index.Number);
			}
			if (mask == ((1<<Registers.bx.Number)|(1<<Registers.si.Number)))
				return 0;
			if (mask == ((1<<Registers.bx.Number)|(1<<Registers.di.Number)))
				return 1;
			if (mask == ((1<<Registers.bp.Number)|(1<<Registers.si.Number)))
				return 2;
			if (mask == ((1<<Registers.bp.Number)|(1<<Registers.di.Number)))
				return 3;
			if (mask == 1<<Registers.si.Number)
				return 4;
			if (mask == 1<<Registers.di.Number)
				return 5;
			if (mask == 1<<Registers.bp.Number)
			{
				mask = 6;
				if (memOp.Offset == null || !memOp.Offset.IsValid)
				{
					mask |= 0x40;
					offset = Constant.Byte(0);
				}
				return mask;
			}
			if (mask == 1<<(int) Registers.bx.Number)
				return 7;
			OnError(string.Format("Illegal 16-bit addressing mode: {0} ", memOp.ToString()));
			return 0;
		}
예제 #12
0
		private void ParseMemoryFactor(MemoryOperand memOp)
		{
			Token token = lexer.GetToken();
			RegisterStorage reg = RegisterStorage.None;
			switch (token)
			{
			default:
				OnError("unexpected token: " + token);
				return;
			case Token.INTEGER:
				totalInt += lexer.Integer;
				break;
			case Token.REGISTER:
			{
				reg = lexer.Register;
 				PrimitiveType width = reg.DataType;
 				if (addrWidth == null)
 					addrWidth = width;
 				else if (addrWidth != width)
 					throw new ApplicationException("Conflicting address widths");
 				break;
			}
			case Token.ID:
			{
				int v;
                if (symtab.Equates.TryGetValue(lexer.StringLiteral.ToLower(), out v))
				{
                    totalInt += v;
				}
				else
				{
					sym = symtab.CreateSymbol(lexer.StringLiteral);
					totalInt += unchecked((int) addrBase.Offset);
				}
				break;
			}
			}

			if (lexer.PeekToken() == Token.TIMES)
			{
				if (reg == RegisterStorage.None)
					throw new ApplicationException("Scale factor must be preceded by a register");
				lexer.GetToken();
				if (memOp.Index != RegisterStorage.None)
					throw new ApplicationException("Scale can only be used once in an addressing form");
				Expect(Token.INTEGER, "Expected an integer scale");
				if (lexer.Integer != 1 && lexer.Integer != 2 && lexer.Integer != 4 && lexer.Integer != 8)
					throw new ApplicationException("Only scales 1, 2, 4, and 8 are supported");
				memOp.Scale = (byte) lexer.Integer;
				memOp.Index = reg;
			}
			else if (reg != RegisterStorage.None)
			{
				if (memOp.Base == RegisterStorage.None)
					memOp.Base = reg;
				else if (memOp.Index == RegisterStorage.None)
				{
					memOp.Index = reg;
					memOp.Scale = 1;
				}
				else
					throw new ApplicationException("Can't have more than two registers in an addressing form");
			}
		}
예제 #13
0
		public void ModRm16Memop()
		{
			MemoryOperand m;
			PrimitiveType w = PrimitiveType.Word16;
			ModRmBuilder mrm = new ModRmBuilder(w, null);
			m = new MemoryOperand(w, Registers.bx, Registers.si, 1, Constant.Invalid);
			Assert.AreEqual(0, mrm.Get16AddressingModeMask(m));
			m = new MemoryOperand(w, Registers.bx, Registers.di, 1, Constant.Invalid);
			Assert.AreEqual(1, mrm.Get16AddressingModeMask(m));
			m = new MemoryOperand(w, Registers.bp, Registers.si, 1, Constant.Invalid);
			Assert.AreEqual(2, mrm.Get16AddressingModeMask(m));
			m = new MemoryOperand(w, Registers.bp, Registers.di, 1, Constant.Invalid);
			Assert.AreEqual(3, mrm.Get16AddressingModeMask(m));
			m = new MemoryOperand(w, Registers.si, Constant.Invalid);
			Assert.AreEqual(4, mrm.Get16AddressingModeMask(m));
			m = new MemoryOperand(w, Registers.di, Constant.Invalid);
			Assert.AreEqual(5, mrm.Get16AddressingModeMask(m));
			m = new MemoryOperand(w, Registers.bp, Constant.Invalid);
			Assert.AreEqual(0x46, mrm.Get16AddressingModeMask(m));
			m = new MemoryOperand(w, Registers.bx, Constant.Invalid);
			Assert.AreEqual(7, mrm.Get16AddressingModeMask(m));
		}
예제 #14
0
 internal void EmitModRM(int reg, MemoryOperand memOp, byte b, Symbol sym)
 {
     Constant offset = modRm.EmitModRMPrefix(reg, memOp);
     emitter.EmitByte(b);
     int offsetPosition = emitter.Position;
     EmitOffset(offset);
     if (sym != null)
         ReferToSymbol(sym, emitter.Position, offset.DataType);
 }
예제 #15
0
        public Expression CreateMemoryAccess(IntelInstruction instr, MemoryOperand mem, DataType dt, X86State state)
        {
            var exp = ImportedProcedureName(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);
            }
        }
예제 #16
0
        private void RewriteLxs(RegisterStorage seg)
        {
            var reg = (RegisterOperand)instrCur.op1;
            MemoryOperand mem = (MemoryOperand)instrCur.op2;
            if (!mem.Offset.IsValid)
            {
                mem = new MemoryOperand(mem.Width, mem.Base, mem.Index, mem.Scale, Constant.Create(instrCur.addrWidth, 0));
            }

            var ass = emitter.Assign(
                frame.EnsureSequence(orw.AluRegister(seg), orw.AluRegister(reg.Register),
                PrimitiveType.Pointer32),
                SrcOp(mem, PrimitiveType.SegPtr32));
        }
예제 #17
0
 private TWord GetEffectiveAddress(MemoryOperand m)
 {
     TWord ea = 0;
     if (m.Offset.IsValid)
         ea += m.Offset.ToUInt32();
     if (m.Index != RegisterStorage.None)
         ea += ReadRegister(m.Index) * m.Scale;
     if (m.Base != null && m.Base != RegisterStorage.None)
     {
         ea += ReadRegister(m.Base);
     }
     return ea;
 }
예제 #18
0
 public ParsedOperand MemW(SegmentRegister seg, RegisterStorage @base, int offset)
 {
     var mem = new MemoryOperand(PrimitiveType.Word16);
     mem.Base = @base;
     mem.Offset = IntegralConstant(offset);
     mem.SegOverride = seg;
     return new ParsedOperand(mem);
 }