public static void Main(string[] args)
        {
            string filename = "";
            string mode = "";
            if (args.Length < 1)
            {
                Console.Write("FileName: ");
                filename = Console.ReadLine();
                Console.Write("Mode: ");
                mode = Console.ReadLine();
            }
            else
            {
                filename = args[0];
            }
            using (StreamReader code = new StreamReader(filename))
            {
                try
                {
                    if (mode == "--onepass")
                    {
                        OnePassAssembler assembler = new OnePassAssembler(code);
                        assembler.Assemble();
                    }
                    else
                    {
                        TwoPassAssembler assembler = new TwoPassAssembler(code);
                        assembler.Assemble();
                    }

                }
                catch (Error e)
                {
                    Console.WriteLine(e.ErrorMessage);
                }
            }
        }
        public override void OnePass(OnePassAssembler opa)
        {
            Location = opa.CurrentAddress;
            if (_label != null && _label != "")
            {
                if (opa.SymbolTable.ContainsKey(_label))
                {
                    if (!opa.SymbolTable[_label].IsFinal)
                    {
                        foreach (Tuple<int, bool, int> i in opa.SymbolTable[_label].Location)
                        {
                            if (i.Item2)
                            {
                                _code.Add("T" + string.Format("{0:X}", i.Item1).PadLeft(6, '0') +
                                    "03" + string.Format("{0:X}", i.Item3 + Location).PadLeft(6, '0'));
                            }
                            else
                            {
                                if (Location - (i.Item1 + 2) <= 2047 &&
                                    Location - (i.Item1 + 2) >= -2048)
                                {
                                    _code.Add("T" + string.Format("{0:X}", i.Item1).PadLeft(6, '0') +
                                        "02" + string.Format("{0:X}", i.Item3 + (1 << 12) + Location - (i.Item1 + 2)).PadLeft(4, '0'));
                                }
                                else if (opa.BaseAddress != Assembler.NoAddress)
                                {
                                    if (Location - opa.BaseAddress <= 4095 &&
                                        Location - opa.BaseAddress >= 0)
                                    {
                                        _code.Add("T" + string.Format("{0:X}", i.Item1).PadLeft(6, '0') +
                                            "02" + string.Format("{0:X}", i.Item3 + (1 << 13) + Location - opa.BaseAddress).PadLeft(6, '0'));
                                    }
                                    else throw new Error("Address is not enough to store.");
                                }
                                else throw new Error("Address is not enough to store.");
                            }
                        }
                    }
                    else throw new Error("Repeating Label!");
                }

                Address address = new Address();
                address.IsFinal = true;
                address.Location.Add(new Tuple<int, bool, int>(Location, false, 0));
                opa.SymbolTable[_label] = address;
            }
            opa.CurrentAddress += _length;

            int x = 0;
            if (_arguments.Count != _type.ArgumentNum)
            {
                if (((InstructionType)_type).Size == InstructionType.Format.LONG)
                {
                    if (_arguments[_arguments.Count - 1] != "X")
                        throw new Error("Argument Error!");
                    else x = 1;
                }
                else
                {
                    throw new Error("Argument Error!");
                }
            }

            _code.Add("T");
            switch (((InstructionType)_type).Size)
            {
                case InstructionType.Format.SMALL:
                    _code[_code.Count - 1] += string.Format("{0:X}", ((InstructionType)_type).Opcode).PadLeft(2, '0');
                    break;
                case InstructionType.Format.MIDDLE:
                    _code[_code.Count - 1] += string.Format("{0:X}", ((InstructionType)_type).Opcode).PadLeft(2, '0');
                    int index;
                    for (index = 0; index < _type.ArgumentNum; index++)
                    {
                        _code[_code.Count - 1] += string.Format("{0:X}", Assembler.RegisterTable[_arguments[index]].ToString()).PadLeft(1, '0');
                    }
                    for (; index < 2; index++)
                    {
                        _code[_code.Count - 1] += "0";
                    }
                    break;
                case InstructionType.Format.LONG:
                    long opcode = ((InstructionType)_type).Opcode;

                    if (_length == 4)
                    {
                        _relocation.Add(string.Format("M{0}05+{1}",
                                        string.Format("{0:X}", Location + 1).PadLeft(6, '0'),
                                        opa.CodeName));
                    }
                    if (_type.ArgumentNum >= 1)
                    {
                        if (_arguments[0][0] == '#')
                        {
                            opcode += 1;
                            _arguments[0] = _arguments[0].Substring(1);

                            int result;
                            if (int.TryParse(_arguments[0], out result))
                            {
                                opcode <<= 2;
                                opcode = (opcode << 1) + x;
                                if (_length == 4)
                                {
                                    opcode = (opcode << 1) + 1;
                                    opcode = (opcode << 20) + result;
                                    _code[_code.Count - 1] += string.Format("{0:X}", opcode).PadLeft(8, '0');
                                    _relocation = null;
                                }
                                else
                                {
                                    opcode <<= 1;
                                    opcode = (opcode << 12) + result;
                                    _code[_code.Count - 1] += string.Format("{0:X}", opcode).PadLeft(6, '0');
                                }
                                break;
                            }
                        }
                        else if (_arguments[0][0] == '@')
                        {
                            opcode += 2;
                            _arguments[0] = _arguments[0].Substring(1);
                        }
                        else opcode += 3;
                        opcode = (opcode << 1) + x;
                        if (!opa.SymbolTable.ContainsKey(_arguments[0]))
                        {
                            opa.SymbolTable[_arguments[0]] = new Address();
                        }

                        if (_length == 4)
                        {
                            opcode = (opcode << 3) + 1;
                            if (!opa.SymbolTable[_arguments[0]].IsFinal)
                            {
                                opcode <<= 20;
                                opa.SymbolTable[_arguments[0]].Location.Add(
                                    new Tuple<int, bool, int>(Location+1, true, (int)(opcode % (1 << 24))));
                            }
                            else
                            {
                                opcode = (opcode << 20) + opa.SymbolTable[_arguments[0]].Location[0].Item1;
                            }
                            _code[_code.Count - 1] += string.Format("{0:X}", opcode).PadLeft(8, '0');
                        }
                        else
                        {
                            if (!opa.SymbolTable[_arguments[0]].IsFinal)
                            {
                                opcode <<= 15;
                                opa.SymbolTable[_arguments[0]].Location.Add(
                                    new Tuple<int, bool, int>(Location + 1, false, (int)(opcode % (1 << 16))));
                            }
                            else if (opa.SymbolTable[_arguments[0]].Location[0].Item1 - (Location + Length) <= 2047 &&
                                opa.SymbolTable[_arguments[0]].Location[0].Item1 - (Location + Length) >= -2048)
                            {
                                opcode = (opcode << 3) + 2;
                                opcode = (opcode << 12) + opa.SymbolTable[_arguments[0]].Location[0].Item1 - (Location + Length);
                            }
                            else if (opa.BaseAddress != Assembler.NoAddress)
                            {
                                if (opa.SymbolTable[_arguments[0]].Location[0].Item1 - opa.BaseAddress <= 4095 &&
                                    opa.SymbolTable[_arguments[0]].Location[0].Item1 - opa.BaseAddress >= 0)
                                {
                                    opcode = (opcode << 3) + 4;
                                    opcode = (opcode << 12) + opa.SymbolTable[_arguments[0]].Location[0].Item1 - opa.BaseAddress;
                                }
                                else throw new Error("Address is not enough to store.");
                            }
                            else throw new Error("Address is not enough to store.");
                            _code[_code.Count - 1] += string.Format("{0:X}", opcode).PadLeft(6, '0');
                        }
                    }
                    else
                    {
                        if (_length == 4)
                        {
                            opcode <<= 25;
                            _code[_code.Count - 1] += string.Format("{0:X}", opcode).PadLeft(8, '0');
                        }
                        else
                        {
                            opcode <<= 17;
                            _code[_code.Count - 1] += string.Format("{0:X}", opcode).PadLeft(6, '0');
                        }
                    }
                    break;
                default:
                    throw new Error("!?");
            }

            foreach (string s in _code)
            {
                Console.WriteLine(s);
            }
        }
 public abstract void OnePass(OnePassAssembler opa);
 public override void OnePass(OnePassAssembler opa)
 {
     Location = opa.CurrentAddress;
     switch (_type.Mnemonic)
     {
         case "START":
             opa.StartAddress = Convert.ToInt32(_arguments[0], 16);
             opa.CurrentAddress = opa.StartAddress;
             Location = opa.CurrentAddress;
             if (_label != null && _label != "")
             {
                 opa.CodeName = _label;
             }
             break;
         case "END":
             opa.Length = opa.CurrentAddress - opa.StartAddress;
             break;
         default:
             break;
     }
     opa.CurrentAddress += _length;
     if (_label != null && _label != "")
     {
     }
 }