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; } }