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 FirstPass(TwoPassAssembler tpa)
        {
            BlockLocation = tpa.CurrentBlockName;
            Location = tpa.CurrentAddress;
            if (_label != null && _label != "")
            {
                tpa.BlockSymbolTable[_label] = new Tuple<string, int>(BlockLocation, Location);
            }
            tpa.CurrentAddress += _length;

            if (_arguments.Count > 0)
            {
                foreach (string s in _arguments)
                {
                    if (s[0] == '=')
                    {
                        if (!tpa.LiteralTable.Contains(s))
                        {
                            tpa.LiteralTable.Add(s);
                        }
                    }
                }
            }
        }
        public override void SecondPass(TwoPassAssembler tpa)
        {
            base.SecondPass(tpa);
            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'),
                                        tpa.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.RemoveAt(0);
                                }
                                else
                                {
                                    opcode <<= 1;
                                    opcode = (opcode << 12) + result;
                                    _code[_code.Count - 1] += string.Format("{0:X}", opcode).PadLeft(6, '0');
                                }
                                break;
                            }
                            else
                            {
                                if (_length == 4 && tpa.EquTable.Contains(_arguments[0]))
                                {
                                    _relocation = null;
                                }
                            }
                        }
                        else if (_arguments[0][0] == '@')
                        {
                            opcode += 2;
                            _arguments[0] = _arguments[0].Substring(1);
                        }
                        else opcode += 3;
                        opcode = (opcode << 1) + x;
                        if (_length == 4)
                        {
                            if (tpa.RefTable.Contains(_arguments[0]))
                            {
                                opcode = (opcode << 3) + 1;
                                opcode <<= 20;
                                _relocation.RemoveAt(0);
                                _relocation.Add("M" + string.Format("{0:X}", Location + 1).PadLeft(6, '0') + "05+" + _arguments[0]);
                            }
                            else
                            {
                                opcode = (opcode << 3) + 1;
                                opcode = (opcode << 20) + tpa.SymbolTable[_arguments[0]];
                            }
                            _code[_code.Count - 1] += string.Format("{0:X}", opcode).PadLeft(8, '0');
                        }
                        else
                        {
                            if (tpa.RefTable.Contains(_arguments[0])) throw new Error("Can't use extref with format 3.");
                            if (tpa.SymbolTable[_arguments[0]] - (Location + Length) <= 2047 &&
                                tpa.SymbolTable[_arguments[0]] - (Location + Length) >= -2048)
                            {
                                opcode = (opcode << 3) + 2;
                                opcode = (opcode << 12) + tpa.SymbolTable[_arguments[0]] - (Location + Length);
                                if (tpa.SymbolTable[_arguments[0]] - (Location + Length) < 0)
                                    opcode += (1 << 12);
                            }
                            else if (tpa.BaseAddress != Assembler.NoAddress)
                            {
                                if (tpa.SymbolTable[_arguments[0]] - tpa.BaseAddress <= 4095 &&
                                    tpa.SymbolTable[_arguments[0]] - tpa.BaseAddress >= 0)
                                {
                                    opcode = (opcode << 3) + 4;
                                    opcode = (opcode << 12) + tpa.SymbolTable[_arguments[0]] - tpa.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
                    {
                        opcode += 3;
                        if (_length == 4)
                        {
                            opcode <<= 24;
                            _code[_code.Count - 1] += string.Format("{0:X}", opcode).PadLeft(8, '0');
                        }
                        else
                        {
                            opcode <<= 16;
                            _code[_code.Count - 1] += string.Format("{0:X}", opcode).PadLeft(6, '0');
                        }
                    }
                    break;
                default:
                    throw new Error("!?");
            }
        }
 public virtual void SecondPass(TwoPassAssembler tpa)
 {
     Location = tpa.BlockTable[BlockLocation].Item1 + Location;
 }
 public abstract void FirstPass(TwoPassAssembler tpa);
 public override void FirstPass(TwoPassAssembler tpa)
 {
     BlockLocation = tpa.CurrentBlockName;
     Location = tpa.CurrentAddress;
     switch (_type.Mnemonic)
     {
         case "START": case "CSECT":
             if (_arguments.Count >= 1)
             {
                 tpa.StartAddress = Convert.ToInt32(_arguments[0], 16);
             }
             else tpa.StartAddress = 0;
             tpa.CurrentAddress = tpa.StartAddress;
             Location = tpa.CurrentAddress;
             if (_label != null && _label != "")
             {
                 tpa.CodeName = _label;
             }
             break;
         case "END":
             for (int i = 0; i < tpa.Code.Count; i++)
             {
                 if (ReferenceEquals(tpa.Code[i], this))
                 {
                     int index = i;
                     foreach (string s in tpa.LiteralTable)
                     {
                         List<string> temp = new List<string>();
                         temp.Add(s.Substring(1));
                         tpa.Code.Insert(index, Assembler.StatementTypeTable["BYTE"].Create(s, "BYTE", temp));
                         tpa.Code[index].FirstPass(tpa);
                         ++index;
                     }
                     tpa.LiteralTable.Clear();
                 }
             }
             tpa.BlockTable[tpa.CurrentBlockName] = new Tuple<int, int>(tpa.BlockTable[tpa.CurrentBlockName].Item1, tpa.CurrentAddress);
             Location = tpa.CurrentAddress;
             break;
         case "LTORG":
             for (int i = 0; i < tpa.Code.Count; i++ )
             {
                 if (ReferenceEquals(tpa.Code[i], this))
                 {
                     int index = i+1;
                     foreach (string s in tpa.LiteralTable)
                     {
                         List<string> temp = new List<string>();
                         temp.Add(s.Substring(1));
                         tpa.Code.Insert(index,Assembler.StatementTypeTable["BYTE"].Create(s, "BYTE", temp));
                         tpa.Code[index].FirstPass(tpa);
                         ++index;
                     }
                     tpa.LiteralTable.Clear();
                 }
             }
             break;
         case "EQU":
             if (_arguments[0] == "*")
             {
                 BlockLocation = BlockLocation;
                 Location = Location;
             }
             else if (_arguments[0].Contains("-"))
             {
                 string arg1 = _arguments[0].Split('-')[0], arg2 = _arguments[0].Split('-')[1];
                 Location = (tpa.BlockSymbolTable[arg1].Item2 - tpa.BlockSymbolTable[arg2].Item2);
                 tpa.EquTable.Add(_label);
             }
             else
             {
                 BlockLocation = tpa.BlockSymbolTable[_arguments[0]].Item1;
                 Location = tpa.BlockSymbolTable[_arguments[0]].Item2;
             }
             break;
         case "USE":
             tpa.BlockTable[tpa.CurrentBlockName] = new Tuple<int, int>(tpa.BlockTable[tpa.CurrentBlockName].Item1, tpa.CurrentAddress);
             if (_arguments.Count >= 1)
             {
                 if (tpa.BlockTable.ContainsKey(_arguments[0]))
                 {
                     tpa.CurrentBlockName = _arguments[0];
                     tpa.CurrentAddress = tpa.BlockTable[tpa.CurrentBlockName].Item2;
                 }
                 else
                 {
                     tpa.BlockTable[_arguments[0]] = new Tuple<int, int>(0, 0);
                     tpa.CurrentBlockName = _arguments[0];
                     tpa.CurrentAddress = tpa.BlockTable[tpa.CurrentBlockName].Item2;
                 }
             }
             else
             {
                 tpa.CurrentBlockName = "(default)";
                 tpa.CurrentAddress = tpa.BlockTable[tpa.CurrentBlockName].Item2;
             }
             BlockLocation = tpa.CurrentBlockName;
             Location = tpa.CurrentAddress;
             break;
         case "EXTREF":
             tpa.RefTable.AddRange(_arguments);
             foreach (string s in _arguments)
             {
                 tpa.SymbolTable[s] = 0;
             }
             break;
         default:
             break;
     }
     tpa.CurrentAddress += _length;
     if (_label != null && _label != "")
     {
         tpa.BlockSymbolTable[_label] = new Tuple<string,int>(BlockLocation, Location);
     }
 }
 public override void SecondPass(TwoPassAssembler tpa)
 {
     base.SecondPass(tpa);
     _code.Add("");
     switch (_type.Mnemonic)
     {
         case "START": case "CSECT":
             _code[_code.Count - 1] += ("H" + tpa.CodeName.PadRight(6) +
                 string.Format("{0:X}",tpa.StartAddress).PadLeft(6,'0') +
                 string.Format("{0:X}", tpa.Length).PadLeft(6, '0'));
             break;
         case "END":
             if (_arguments.Count >= 1)
             {
                 _code[_code.Count - 1] += ("E" + string.Format("{0:X}", tpa.SymbolTable[_arguments[0]]).PadLeft(6, '0'));
             }
             else
             {
                 _code[_code.Count - 1] += "E";
             }
             break;
         case "BASE":
             tpa.BaseAddress = tpa.SymbolTable[_arguments[0]];
             break;
         case "NOBASE":
             tpa.BaseAddress = Assembler.NoAddress;
             break;
         case "BYTE":
             _code[_code.Count - 1] += "T";
             if (_arguments[0][0] == 'X')
             {
                 _code[_code.Count - 1] += _arguments[0].Substring(1).Trim('\'');
             }
             else if (_arguments[0][0] == 'C')
             {
                 string arg = _arguments[0].Substring(1).Trim('\'');
                 foreach (char c in arg)
                 {
                     _code[_code.Count - 1] += string.Format("{0:X}", (int)c).PadLeft(2, '0');
                 }
             }
             break;
         case "WORD":
             if (_arguments[0].Contains("-"))
             {
                 string arg1 = _arguments[0].Split('-')[0], arg2 = _arguments[0].Split('-')[1];
                 if (tpa.RefTable.Contains(arg1) || tpa.RefTable.Contains(arg2))
                 {
                     _code[_code.Count - 1] += "000000";
                     _relocation.Add("M" + string.Format("{0:X}", Location).PadLeft(6, '0') + "06+" + arg1);
                     _relocation.Add("M" + string.Format("{0:X}", Location).PadLeft(6, '0') + "06-" + arg2);
                 }
                 else
                 {
                     _code[_code.Count - 1] += string.Format("{0:X}",tpa.SymbolTable[arg1]-tpa.SymbolTable[arg2]).PadLeft(6, '0');
                 }
             }
             else
             {
                 _code[_code.Count - 1] += string.Format("{0:X}", Convert.ToInt32(_arguments[0])).PadLeft(6, '0');
             }
             break;
         case "EXTDEF":
             _code[0] += "D";
             foreach (string s in _arguments)
             {
                 _code[0] += s + string.Format("{0:X}", tpa.SymbolTable[s]).PadLeft(6, '0');
             }
             break;
         case "EXTREF":
             _code[0] += "R";
             foreach (string s in tpa.RefTable)
             {
                 _code[0] += s.PadRight(6, ' ');
             }
             break;
     }
 }