private static int DoOpConst() {//количество байт, выделенных под данные int byteCount = TableInstruction.GetByName(TableLexeme.MnemName()).ByteCount; int result = byteCount; int value; if (TableSentence.Item.Operands[1, 0] != 0) // есть второй операнд { Errors.Add(20); //@error слишком много операндов } if (TableSentence.Item.Operands[0, 1] == 1) //константа { TableLexeme lex = TableLexeme.GetByNumber(TableSentence.Item.Operands[0, 0]); //первая лексема первого операнда value = lex.NumberDex(); double f = Math.Pow(2, 8 * byteCount) - 1; uint j = Convert.ToUInt32(f); if (value > j) { Errors.Add(2);//@error too big number } TableOperand.GetByNumbers(10, isFirst).Modify(value, byteCount); } else//выражение { int FirstLex = TableSentence.Item.Operands[0, 0]; int LastLex = FirstLex + TableSentence.Item.Operands[0, 1] - 1; int Const = Calc.DoCalc(FirstLex, LastLex); result = LastLex - FirstLex; TableOperand.GetByNumbers(10, isFirst).Modify(Const, byteCount); } AnalysisGrammar.AddTableUser(byteCount); return(result); }
private static string CreateBytes(int ByteCount) { int FirstOpNum = TableSentence.Item.Operands[0, 0]; TableLexeme Lexeme = TableLexeme.GetByNumber(FirstOpNum); string result = ""; switch (TableOperand.TypeFirst) { case TableOperand.Types.Мітка: result = Lexeme.Type == TableAsmWords.Types.seg ? "----" : CreateUser(Lexeme, ByteCount); break; case TableOperand.Types.Константа: result = CreateNumber(ByteCount); break; case TableOperand.Types.Текст: result = CreateText(Lexeme); break; default: break; } return(result); }
private static void ReadOperands()//записуєм номери і довжину операндів у таблицю { int iter = MnemNumber > 0 ? MnemNumber + 1 : NameOrLabelNumber + 1; int i = 0; while ((iter <= TableLexeme.Count) && (i < 6)) { Operands[i, 0] = iter; for (int j = iter; j <= TableLexeme.Count; j++) { if (TableLexeme.GetByNumber(j).Name == ",") { Operands[i, 1] = j - Operands[i, 0]; iter = j + 1; IsComa = true; break; } else { IsComa = false; } } if (!IsComa)//last operand { Operands[i, 1] = TableLexeme.Count - Operands[i, 0] + 1; break; } i++; if ((iter <= TableLexeme.Count) && (i >= 6)) { Errors.Add(20);//@error слишком много операндов } } }
private static string CreateUser(TableLexeme Lexeme, int ByteCount) { TableUser User = TableUser.GetByName(Lexeme.Name); string result = Convert.ToString(Convert.ToInt32(User.Offset), 16).ToUpper(); result = CheckCharCount(result, ByteCount); return(result); }
public static void GoFirst(int StopNumber) { IsGoFirst = true; IsEnd = false; ClearTables(); string line = ""; Result.Count = 0; if (Result.FileLength > 0) { for (int LineNumber = 0; LineNumber < Result.FileLength; LineNumber++) { line = File.ReadAllLines(Result.FilePath)[LineNumber]; Result result = new Result(LineNumber + 1, line); Result.Count++; AnalysisLexy.FormLexyTable(line); if (TableLexeme.Count > 0) { AnalysisSyntaxy.FormSentenceTable(); if (TableSentence.Item.Type != TableAsmWords.Types.пусто) { int CurrentOffset = AnalysisGrammar.CalculateOffset(); TableSegment.IncOffset(CurrentOffset); result.ModifyOffset(CurrentOffset); } if (TableLexeme.MnemName() == "END") { IsEnd = true; break; } } else//пустая строка { Result.Table.Rows.RemoveAt(Result.Items.Count - 1); Result.Items.RemoveAt(Result.Items.Count - 1); result = null; Result.Count--; } if (LineNumber == StopNumber) { LineNumber += 0;//@error: doesn't do anything } } } if (Result.Count == 0) { Errors.Add(16);//@error пустой исходный файл } else if (!IsEnd) { Errors.Add(17);//@error end is missing } }
private static void DoOpSeg(TableLexeme Lexeme) { TableLexeme LexemeNext = TableLexeme.GetByNumber(Lexeme.Number + 1); if (LexemeNext.Type != TableAsmWords.Types.мітка && LexemeNext.Type != TableAsmWords.Types.користувач) { Errors.Add(10);//@error неправильный агрумент у Seg } TableOperand.GetByNumbers(9, isFirst).Modify(LexemeNext.Number, -1); }
private static string CreateText(TableLexeme Lexeme) { byte[] resBytes; string result = ""; resBytes = Encoding.GetEncoding(1251).GetBytes(Lexeme.Name);//@error неправильные коды for (int i = 0; i < resBytes.Length; i++) { result += Convert.ToString(resBytes[i], 16).ToUpper() + " "; } return(result); }
private static void DoAssume() { int i = 0; Result.Current().isOffset = false; while (TableSentence.Item.Operands[i, 0] != 0) { string reg = TableLexeme.GetByNumber(TableSentence.Item.Operands[i, 0]).Name; string name = TableLexeme.GetByNumber(TableSentence.Item.Operands[i, 0] + 2).Name; TableAssume.Modify(reg, name); i++; } }
public static int DoCalc(int FirstLex, int LastLex) { DataStek.Clear(); int i = FirstLex; while (i <= LastLex) { TableLexeme CurrLex = TableLexeme.Items[i - 1]; if (CurrLex.Type == TableAsmWords.Types.число) { DataStek.Add(CurrLex.NumberDex()); i++; } else if (CurrLex.Type == TableAsmWords.Types.символ) { if (OpStek.Count == 0 || CurrLex.Name == "(" || Prior(CurrLex.Name) > Prior(OpStek[OpStek.Count - 1])) { OpStek.Add(CurrLex.Name); i++; } else if (CurrLex.Name == ")") { while (DoCount() != "(") { ; } i++; } else { DoCount(); } } else { i++; } } while (OpStek.Count > 0) { DoCount(); } if (DataStek.Count > 1) { Errors.Add(11);//@error невірний абсолютний вираз } return(DataStek[0]); }
private static void DoLabel() { TableLexeme LabelLex = TableLexeme.Label(); // int i = TableSentence.Item.Operands[0, 0]; TableLexeme LabelType = TableLexeme.GetByNumber(TableLexeme.Label().Number + 2); if (LabelType != null && LabelType.Name == "FAR") { AddTableUser(5); } else { Errors.Add(12);//@error Label type is wrong or missing } }
public static void IncOffset(int num) { if (ActiveSegmentNumber != 0) { ActiveSegment().Offset += num; if (num > 0) { Table.Rows[ActiveSegmentNumber - 1][3] = ActiveSegment().Offset; } } else if (!(TableLexeme.MnemName() == ".386") && !(TableLexeme.MnemName() == "ENDS") && !(TableLexeme.MnemName() == "END")) { Errors.Add(4); //@error данные/команда вне сегмента } }
private static void DoOpText() { TableLexeme lex = TableLexeme.GetByNumber(TableSentence.Item.Operands[0, 0]);//первая лексема первого операнда int byteCount = TableInstruction.GetByName(TableLexeme.MnemName()).ByteCount; if (byteCount == 1) { byteCount *= lex.Length; } else { Errors.Add(14);//@error недопустимий аргумент директиви } TableOperand.GetByNumbers(11, isFirst).Modify(byteCount, -1); AnalysisGrammar.AddTableUser(1); }
// СЧИТАЕМ КОЛИЧЕСТВО БАЙТ В ДИРЕКТИВЕ ****************************************************** public static int CountDirective() { int result = 0; AnalysisSyntaxy.DoOperands(); if (Result.Current().Error != null) { return(0); } switch (TableSentence.Item.Mnem) { case "SEGMENT": DoSegment(TableLexeme.Label().Name); break; case "ASSUME": DoAssume(); break; case "ENDS": TableSegment.ActiveSegmentNumber = 0; break; case "DB": result += CountData(); break; case "DW": result += 2; break; case "DD": result += 4; break; case "LABEL": DoLabel(); break; default: Result.Current().isOffset = false; break; } return(result); }
public static void AddTableUser(int byteCount) {//if username present if (TableSentence.Item.NameOrLabelNumber != 0 && LookOver.IsGoFirst && TableSegment.ActiveSegment() != null) { string userName = TableLexeme.Label().Name; int userOffset = TableSegment.ActiveSegment().Offset; if (TableUser.GetByName(userName) != null) { Errors.Add(13);//@error user name already exists in the table } else { new TableUser(userName, userOffset, TableSegment.ActiveSegmentNumber, byteCount); } } }
private static int DoOpSymbols(TableLexeme Lexeme) { switch (Lexeme.Name) { case "[": isAdress = true; break; case "]": isAdress = false; break; case "*": int EndOfConst = Lexeme.Number; while (TableLexeme.GetByNumber(EndOfConst + 1).Name != "]") { EndOfConst++; } int RegNumber; if (TableOperand.GetByNumbers(7, isFirst).IsLexemePresent) { RegNumber = TableOperand.GetByNumbers(7, isFirst).MainAttr; } else { RegNumber = TableOperand.GetByNumbers(6, isFirst).MainAttr; } int ConstValue = Calc.DoCalc(Lexeme.Number + 1, EndOfConst); if (ConstValue == 1 || ConstValue == 2 || ConstValue == 4 || ConstValue == 8) { TableOperand.GetByNumbers(8, isFirst).Modify(RegNumber, ConstValue); } else { Errors.Add(9); //@error wrong multiplier } return(EndOfConst - Lexeme.Number); //прыгаем в конец конст. выражения default: break; } return(0); }
private static void DoOpRegister(TableLexeme Lexeme) { int RegNum = TableRegister.GetByName(Lexeme.Name).Number; if (isAdress) { if (!TableOperand.GetByNumbers(6, isFirst).IsLexemePresent) { TableOperand.GetByNumbers(6, isFirst).Modify(RegNum, 32); } else { TableOperand.GetByNumbers(7, isFirst).Modify(RegNum, 32); } } else { TableOperand.GetByNumbers(1, isFirst).Modify(RegNum, 32); } }
private static void DoOpName(TableLexeme Lexeme) { TableUser user = TableUser.GetByName(Lexeme.Name); if (user != null) { TableOperand.GetByNumbers(4, isFirst).Modify(user.Number, -1); } else { TableOperand.GetByNumbers(5, isFirst).Modify(-1, -1); } if (TableLexeme.MnemName() == "DD") { AnalysisGrammar.AddTableUser(4); } else { AnalysisGrammar.AddTableUser(-1); } }
private static void DoOpType(TableLexeme Lexeme) { switch (Lexeme.Name) { case "DWORD": if (!TableOperand.GetByNumbers(2, isFirst).IsLexemePresent) { TableOperand.GetByNumbers(2, isFirst).Modify(4, -1); } break; case "FWORD": if (!TableOperand.GetByNumbers(2, isFirst).IsLexemePresent) { TableOperand.GetByNumbers(2, isFirst).Modify(6, -1); } break; case "FAR": if (!TableOperand.GetByNumbers(2, isFirst).IsLexemePresent) { TableOperand.GetByNumbers(2, isFirst).Modify(5, -1); } break; case "PTR": if (!TableOperand.GetByNumbers(2, isFirst).IsLexemePresent) { Errors.Add(8); //@error type is missing } break; default: Errors.Add(5); //@error какая-то хрень break; } }
private static void DoOpSegRegister(TableLexeme Lexeme) { int RegNum = TableRegister.GetByName(Lexeme.Name).Number; TableOperand.GetByNumbers(3, isFirst).Modify(RegNum, -1); }
private static string CreateUser(TableLexeme Lexeme, int ByteCount) { TableUser User = TableUser.GetByName(Lexeme.Name); string result = Convert.ToString(Convert.ToInt32(User.Offset), 16).ToUpper(); result = CheckCharCount(result, ByteCount); return result; }
private static void DoOpType(TableLexeme Lexeme) { switch (Lexeme.Name) { case "DWORD": if (!TableOperand.GetByNumbers(2, isFirst).IsLexemePresent) TableOperand.GetByNumbers(2, isFirst).Modify(4, -1); break; case "FWORD": if (!TableOperand.GetByNumbers(2, isFirst).IsLexemePresent) TableOperand.GetByNumbers(2, isFirst).Modify(6, -1); break; case "FAR": if (!TableOperand.GetByNumbers(2, isFirst).IsLexemePresent) TableOperand.GetByNumbers(2, isFirst).Modify(5, -1); break; case "PTR": if (!TableOperand.GetByNumbers(2, isFirst).IsLexemePresent) Errors.Add(8);//@error type is missing break; default: Errors.Add(5);//@error какая-то хрень break; } }
private static int DoOpSymbols(TableLexeme Lexeme) { switch (Lexeme.Name) { case "[": isAdress = true; break; case "]": isAdress = false; break; case "*": int EndOfConst = Lexeme.Number; while (TableLexeme.GetByNumber(EndOfConst + 1).Name != "]") EndOfConst++; int RegNumber; if (TableOperand.GetByNumbers(7, isFirst).IsLexemePresent) RegNumber = TableOperand.GetByNumbers(7, isFirst).MainAttr; else RegNumber = TableOperand.GetByNumbers(6, isFirst).MainAttr; int ConstValue = Calc.DoCalc(Lexeme.Number + 1, EndOfConst); if (ConstValue == 1 || ConstValue == 2 || ConstValue == 4 || ConstValue == 8) TableOperand.GetByNumbers(8, isFirst).Modify(RegNumber, ConstValue); else Errors.Add(9);//@error wrong multiplier return EndOfConst - Lexeme.Number;//прыгаем в конец конст. выражения default: break; } return 0; }
private static void DoOpSeg(TableLexeme Lexeme) { TableLexeme LexemeNext = TableLexeme.GetByNumber(Lexeme.Number + 1); if (LexemeNext.Type != TableAsmWords.Types.мітка && LexemeNext.Type != TableAsmWords.Types.користувач) Errors.Add(10);//@error неправильный агрумент у Seg TableOperand.GetByNumbers(9, isFirst).Modify(LexemeNext.Number, -1); }
public static void DoOperands()//обробка операндів { string mnemName = TableSentence.Item.Mnem; int opCount; if (TableInstruction.GetByName(mnemName) != null)//у директиви або інструкції є операнди { opCount = TableInstruction.GetByName(mnemName).OperandCount; } else//інші директиви { opCount = 0; } if (mnemName != "ASSUME" && opCount != TableSentence.Item.OpCount) { Errors.Add(6);//@error Невірна кількість операндів } else { for (int i = 0; i < TableSentence.Item.OpCount; i++)//для каждого операнда { isFirst = (i == 0) ? true : false; int j = 0; while (j < TableSentence.Item.Operands[i, 1]) { TableLexeme Lexeme = TableLexeme.GetByNumber(TableSentence.Item.Operands[i, 0] + j); switch (Lexeme.Type) { case TableAsmWords.Types.регістр: DoOpRegister(Lexeme); break; case TableAsmWords.Types.сегментний_регістр: DoOpSegRegister(Lexeme); break; case TableAsmWords.Types.тип: DoOpType(Lexeme); break; case TableAsmWords.Types.користувач: DoOpName(Lexeme); break; case TableAsmWords.Types.символ: j += DoOpSymbols(Lexeme); break; case TableAsmWords.Types.seg: DoOpSeg(Lexeme); break; case TableAsmWords.Types.число: j += DoOpConst(); break; case TableAsmWords.Types.текст: DoOpText(); break; default: break; } j++; } TableOperand.IdentifyOperands(isFirst); } } bool result = opCount > 0 ? TableOperand.VerifyOperands(mnemName) : true; if (!result) { Errors.Add(15);//@error Помилкові операнди } }
private static void DoOpName(TableLexeme Lexeme) { TableUser user = TableUser.GetByName(Lexeme.Name); if (user != null) TableOperand.GetByNumbers(4, isFirst).Modify(user.Number, -1); else TableOperand.GetByNumbers(5, isFirst).Modify(-1, -1); if (TableLexeme.MnemName() == "DD") AnalysisGrammar.AddTableUser(4); else AnalysisGrammar.AddTableUser(-1); }
private static void DoOpRegister(TableLexeme Lexeme) { int RegNum = TableRegister.GetByName(Lexeme.Name).Number; if (isAdress) if (!TableOperand.GetByNumbers(6, isFirst).IsLexemePresent) TableOperand.GetByNumbers(6, isFirst).Modify(RegNum, 32); else TableOperand.GetByNumbers(7, isFirst).Modify(RegNum, 32); else TableOperand.GetByNumbers(1, isFirst).Modify(RegNum, 32); }
private static string CreateText(TableLexeme Lexeme) { byte[] resBytes; string result = ""; resBytes = Encoding.GetEncoding(1251).GetBytes(Lexeme.Name);//@error неправильные коды for (int i = 0; i < resBytes.Length; i++) result += Convert.ToString(resBytes[i], 16).ToUpper() + " "; return result; }