private static string CreateOpCode(TableCurrInstruct CurrInstr) { string Code = TableInstruction.GetByName(CurrInstr.Name).OpCommand; if (Code != "opt")//команда завжди однакова { return(Code); } if (CurrInstr.Name == "JMP") { if (CurrInstr.IsModRm) { Code = "FF"; } else { Code = "EA"; } } if (CurrInstr.Name == "MOV") { if (CurrInstr.IsModRm) { Code = "8B"; } else { Code = "A1"; } } return(Code); }
private static void CountModRm(TableCurrInstruct CurrInstr) { if (CurrInstr.Name == "MOV") { if (TableOperand.GetByNumbers(1, true).MainAttr != 0) { CurrInstr.IncByteCount(1, TableCurrInstruct.Types.модрм); } else if (TableOperand.TypeSecond == TableOperand.Types.Адресний_вираз) { CurrInstr.IncByteCount(1, TableCurrInstruct.Types.модрм); } return; } if (CurrInstr.Name == "JMP") { if (TableOperand.GetByNumbers(4, true).IsLexemePresent)//визначений ідентифікатор { TableUser.Types userType = TableUser.GetByNumber(TableOperand.GetByNumbers(4, true).MainAttr).Type; if (userType != TableUser.Types.Far) { CurrInstr.IncByteCount(1, TableCurrInstruct.Types.модрм); } } return; } if (TableInstruction.GetByName(CurrInstr.Name).ModRM) { CurrInstr.IncByteCount(1, TableCurrInstruct.Types.модрм); } }
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 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 CountInstruction() { string MnemName = TableSentence.Item.Mnem; AnalysisSyntaxy.DoOperands(); if (Result.Current().Error != null) { return(0); } //if (TableSegment.ActiveSegmentNumber == 0 && !(MnemName == ".386") && !(MnemName == "ENDS") && !(MnemName == "END")) // Errors.Add(2);//@error команда вне сегмента TableCurrInstruct CurrInstr = new TableCurrInstruct(MnemName); CurrInstr.IncByteCount(TableInstruction.GetByName(MnemName).ByteCount, TableCurrInstruct.Types.пусто);//размер кода операции CountPrefix(CurrInstr); CountModRm(CurrInstr); CountSib(CurrInstr); CountOffset(CurrInstr); return(CurrInstr.ByteCount); }
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 Помилкові операнди } }