Example #1
0
 private AssembledSegment GetSymbolSegmentReference(Symbol sym)
 {
     AssembledSegment seg;
     if (symbolSegments.TryGetValue(sym, out seg))
         return seg;
     seg = new AssembledSegment(emitter, null);
     symbolSegments.Add(sym, seg);
     return seg;
 }
Example #2
0
 private void ReferToSymbol(Symbol psym, int off, DataType width)
 {
     if (psym.fResolved)
     {
         Emitter.PatchBe(off, psym.offset, width);
     }
     else
     {
         psym.AddForwardReference(off, width, 1);
     }
 }
Example #3
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);
 }
Example #4
0
 private void EmitReferenceToSymbolSegment(Symbol sym)
 {
     var seg = GetSymbolSegmentReference(sym);
     seg.Relocations.Add(new AssembledSegment.Relocation { Segment=currentSegment, Offset=(uint) emitter.Length });
     emitter.EmitLeUInt16(0);            // make space for the segment selector, will be overwritten at relocation time.
 }
Example #5
0
		public Symbol DefineSymbol(string s, int off)
		{
			Symbol	sym;
			if (symbols.ContainsKey(s))
			{
				sym = symbols[s];
				if (sym.fResolved || sym.offset != 0)
					throw new ApplicationException("symbol '" + s + "' redefined");
			}
			else
			{
				sym = new Symbol(s);
				symbols[s] = sym;
			}
			sym.fResolved = true;
			sym.offset = off;
			return sym;
		}
Example #6
0
 private void ResolveSegmentForwardReferences(Symbol sym)
 {
     AssembledSegment tempSeg;
     if (symbolSegments.TryGetValue(sym, out tempSeg))
     {
         currentSegment.Relocations.AddRange(tempSeg.Relocations);
     }
 }
Example #7
0
 public AssembledSegment(IEmitter emitter, Symbol sym)
 {
     this.Emitter = emitter;
     this.Symbol = sym;
     this.Relocations = new List<Relocation>();
 }
Example #8
0
		public Symbol CreateSymbol(string s)
		{
			Symbol sym;
            if (!symbols.TryGetValue(s, out sym))
			{
				// Forward reference to a symbol. 
				sym = new Symbol(s);
				symbols.Add(s, sym);
			}
			return sym;
		}
Example #9
0
		public ParsedOperand(MachineOperand op, Symbol sym)
		{
			this.op = op;
			this.Symbol = sym;
		}
Example #10
0
		public ParsedOperand(MachineOperand op, Symbol sym, bool longJmp)
		{
			this.op = op;
			this.Symbol = sym;
			this.longJmp = longJmp;
		}
Example #11
0
        public ParsedOperand ParseOperand()
        {
            sym = null;
            totalInt = 0;
            segOverride = RegisterStorage.None;
            Token token = lexer.GetToken();
            switch (token)
            {
            default:
                OnError(string.Format("Unexpected token '{0}'", token));
                return null;
            case Token.BRA:
                return ParseMemoryOperand(RegisterStorage.None);
            case Token.MINUS:
                Expect( Token.INTEGER );
                totalInt -= lexer.Integer;
                return IntegerCommon();
            case Token.INTEGER:
                totalInt += lexer.Integer;
                return IntegerCommon();
            case Token.REGISTER:
            {
                RegisterStorage reg = lexer.Register;
                switch (lexer.PeekToken())
                {
                case Token.COLON:		// Segment override of the form "es:" usually precedes a memory operand.
                    if (!(reg is SegmentRegister))
                        throw new ApplicationException(reg.ToString() + " is not a segment register.");
                    Expect(Token.COLON);			// Discard ':'
                    Expect(Token.BRA);
                    return ParseMemoryOperand(reg);
                default:
                    return new ParsedOperand(new RegisterOperand(reg));
                }
            }
            case Token.OFFSET:
                Expect(Token.ID);
                return new ParsedOperand(
                    new ImmediateOperand(Constant.Create(defaultWordWidth, addrBase.Offset)),
                    symtab.CreateSymbol(lexer.StringLiteral));

            case Token.ID:
            {
                int v;
                if (symtab.Equates.TryGetValue(lexer.StringLiteral.ToLower(), out v))
                {
                    totalInt += lexer.Integer;
                    return IntegerCommon();
                }
                return new ParsedOperand(
                               new MemoryOperand(addrWidth, Constant.Create(defaultWordWidth, addrBase.Offset)),
                               symtab.CreateSymbol(lexer.StringLiteral));
            }
            case Token.WORD:
                return ParsePtrOperand(PrimitiveType.Word16);
            case Token.BYTE:
                return ParsePtrOperand(PrimitiveType.Byte);
            case Token.DWORD:
                return ParsePtrOperand(PrimitiveType.Word32);
            case Token.QWORD:
                return ParsePtrOperand(PrimitiveType.Word64);
            case Token.ST:
                return new ParsedOperand(ParseFpuOperand(), null);
            }
        }
Example #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");
            }
        }
Example #13
0
 public ParsedOperand(MachineOperand op)
 {
     this.op = op;
     this.sym = null;
 }