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 string CreateOffset(TableCurrInstruct CurrInstr) { string Offset = ""; int UserNumber = 0; if (TableOperand.TypeFirst >= TableOperand.Types.Мітка && TableOperand.TypeFirst <= TableOperand.Types.Адресний_вираз) { UserNumber = TableOperand.GetByNumbers(4, true).MainAttr; } if (TableOperand.TypeSecond >= TableOperand.Types.Мітка && TableOperand.TypeSecond <= TableOperand.Types.Адресний_вираз) { UserNumber = TableOperand.GetByNumbers(4, false).MainAttr; } if (UserNumber > 0) { Offset = Convert.ToString(TableUser.GetByNumber(UserNumber).Offset, 16); Offset = CheckCharCount(Offset, 8); if (CurrInstr.Name == "JMP" && !CurrInstr.IsModRm) { Offset += " ----"; } } return(Offset.ToUpper()); }
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 CountSib(TableCurrInstruct CurrInstr) { if (CurrInstr.IsModRm && (TableOperand.TypeFirst == TableOperand.Types.Адресний_вираз || TableOperand.TypeSecond == TableOperand.Types.Адресний_вираз)) { CurrInstr.IncByteCount(1, TableCurrInstruct.Types.сіб); } }
private static void CountOffset(TableCurrInstruct CurrInstr) { if ((TableOperand.TypeFirst >= TableOperand.Types.Мітка && TableOperand.TypeFirst <= TableOperand.Types.Адресний_вираз) || (TableOperand.TypeSecond >= TableOperand.Types.Мітка && TableOperand.TypeSecond <= TableOperand.Types.Адресний_вираз)) { CurrInstr.IncByteCount(4, TableCurrInstruct.Types.зміщення); } if (CurrInstr.Name == "JMP" && !CurrInstr.IsModRm) { CurrInstr.IncByteCount(2, TableCurrInstruct.Types.зміщення); } }
private static void CountPrefix(TableCurrInstruct CurrInstr) { if (CurrInstr.Name != "PUSH" && CurrInstr.Name != "CMP" && CurrInstr.Name != "MOV" && CurrInstr.Name != "JMP") { return;//префикса быть не может } bool isFirstOp = CurrInstr.Name == "MOV" ? false : true; int DefaultRegisterNum = 3;//ds int MultipliedRegister = TableOperand.GetByNumbers(8, isFirstOp).MainAttr; int FirstAdressRegister = TableOperand.GetByNumbers(6, isFirstOp).MainAttr; int SecondAdressRegister = TableOperand.GetByNumbers(7, isFirstOp).MainAttr; if (MultipliedRegister != 4 && MultipliedRegister != 5) //множитель не при ebp esp { if (FirstAdressRegister == 4 || FirstAdressRegister == 5 || //ebp или esp есть SecondAdressRegister == 4 || SecondAdressRegister == 5) { DefaultRegisterNum = 2;//ss } } if (TableOperand.GetByNumbers(3, isFirstOp).IsLexemePresent) { int PrefReg = TableOperand.GetByNumbers(3, isFirstOp).MainAttr; if (PrefReg != DefaultRegisterNum) { CurrInstr.IncByteCount(1, TableCurrInstruct.Types.префікс); //префикс задан явно и не совпадает по умолчанию } } else //префикс не задан явно if (TableOperand.GetByNumbers(4, isFirstOp).IsLexemePresent) //є ідентиф користувача { int userNumber = TableOperand.GetByNumbers(4, isFirstOp).MainAttr; //номер рядка в таблиці користувача string logicSegment = TableUser.GetByNumber(userNumber).ActiveSeg; //ім'я логічного сегменту string userRegister = TableAssume.GetByName(logicSegment); //имя регистра логического сегмента var Register = TableRegister.GetByName(userRegister); //сам регистр if (Register != null && Register.Number != DefaultRegisterNum) { CurrInstr.IncByteCount(1, TableCurrInstruct.Types.префікс); //нужно генерировать незаданный префикс } } }
private static string CreatePrefix(TableCurrInstruct CurrInstr) { bool isFirstOp = CurrInstr.Name == "MOV" ? false : true; int DefaultRegisterNum = 3;//ds int MultipliedRegister = TableOperand.GetByNumbers(8, isFirstOp).MainAttr; int FirstAdressRegister = TableOperand.GetByNumbers(6, isFirstOp).MainAttr; int SecondAdressRegister = TableOperand.GetByNumbers(7, isFirstOp).MainAttr; if (MultipliedRegister != 4 && MultipliedRegister != 5) //множитель не при ebp esp { if (FirstAdressRegister == 4 || FirstAdressRegister == 5 || //ebp или esp есть SecondAdressRegister == 4 || SecondAdressRegister == 5) { DefaultRegisterNum = 2;//ss } } string Prefix = ""; TableOperand OperPref = TableOperand.GetByNumbers(3, isFirstOp); if (OperPref.IsLexemePresent) //задан явно == не совпадает по умолчанию { Prefix = TableRegister.GetByNumbers(OperPref.MainAttr, 2).PrefixString; //нужный префикс // CurrInstr.Prefix = Prefix; } else //префикс не задан явно { int userNumber = TableOperand.GetByNumbers(4, isFirstOp).MainAttr;//номер рядка в таблиці користувача string logicSegment = TableUser.GetByNumber(userNumber).ActiveSeg; //ім'я логічного сегменту string userRegister = TableAssume.GetByName(logicSegment); //имя регистра логического сегмента var Register = TableRegister.GetByName(userRegister); //сам регистр if (Register != null && Register.Number != DefaultRegisterNum) //нужно генерировать незаданный префикс { Prefix = Register.PrefixString; // CurrInstr.Prefix = Prefix; } } return(Prefix); }
// СЧИТАЕМ КОЛИЧЕСТВО БАЙТ В ИНСТРУКЦИИ ****************************************************** 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); }
// ФОРМИРУЕМ КОМАНДУ **************************************************************************** private static string CreateInstruction() { TableCurrInstruct CurrInstruct = TableCurrInstruct.Items[TableCurrInstruct.Items.Count - 1]; string result = ""; if (CurrInstruct.IsPrefix) { result += CreatePrefix(CurrInstruct) + ":"; } result = Result.CheckSpaceCount(result, 4); result += CreateOpCode(CurrInstruct) + " "; if (CurrInstruct.IsModRm) { result += CreateModRm(); if (CurrInstruct.IsSib) { result += CreateSib(); } result += " "; } if (CurrInstruct.IsOffset) { result += CreateOffset(CurrInstruct) + " "; } if (CurrInstruct.IsImmediate) { result += CreateImmediate(CurrInstruct); } return(result); }
// СЧИТАЕМ КОЛИЧЕСТВО БАЙТ В ИНСТРУКЦИИ ****************************************************** 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; }
private static void CountPrefix(TableCurrInstruct CurrInstr) { if (CurrInstr.Name != "PUSH" && CurrInstr.Name != "CMP" && CurrInstr.Name != "MOV" && CurrInstr.Name != "JMP") return;//префикса быть не может bool isFirstOp = CurrInstr.Name == "MOV" ? false : true; int DefaultRegisterNum = 3;//ds int MultipliedRegister = TableOperand.GetByNumbers(8, isFirstOp).MainAttr; int FirstAdressRegister = TableOperand.GetByNumbers(6, isFirstOp).MainAttr; int SecondAdressRegister = TableOperand.GetByNumbers(7, isFirstOp).MainAttr; if (MultipliedRegister != 4 && MultipliedRegister != 5)//множитель не при ebp esp if (FirstAdressRegister == 4 || FirstAdressRegister == 5 || //ebp или esp есть SecondAdressRegister == 4 || SecondAdressRegister == 5) DefaultRegisterNum = 2;//ss if (TableOperand.GetByNumbers(3, isFirstOp).IsLexemePresent) { int PrefReg = TableOperand.GetByNumbers(3, isFirstOp).MainAttr; if (PrefReg != DefaultRegisterNum) CurrInstr.IncByteCount(1, TableCurrInstruct.Types.префікс); //префикс задан явно и не совпадает по умолчанию } else //префикс не задан явно if (TableOperand.GetByNumbers(4, isFirstOp).IsLexemePresent)//є ідентиф користувача { int userNumber = TableOperand.GetByNumbers(4, isFirstOp).MainAttr;//номер рядка в таблиці користувача string logicSegment = TableUser.GetByNumber(userNumber).ActiveSeg;//ім'я логічного сегменту string userRegister = TableAssume.GetByName(logicSegment);//имя регистра логического сегмента var Register = TableRegister.GetByName(userRegister);//сам регистр if (Register != null && Register.Number != DefaultRegisterNum) CurrInstr.IncByteCount(1, TableCurrInstruct.Types.префікс);//нужно генерировать незаданный префикс } }
private static void CountSib(TableCurrInstruct CurrInstr) { if (CurrInstr.IsModRm && (TableOperand.TypeFirst == TableOperand.Types.Адресний_вираз || TableOperand.TypeSecond == TableOperand.Types.Адресний_вираз)) CurrInstr.IncByteCount(1, TableCurrInstruct.Types.сіб); }
private static string CreateImmediate(TableCurrInstruct CurrInstr) { return ""; }
private static string CreateOffset(TableCurrInstruct CurrInstr) { string Offset = ""; int UserNumber = 0; if (TableOperand.TypeFirst >= TableOperand.Types.Мітка && TableOperand.TypeFirst <= TableOperand.Types.Адресний_вираз) UserNumber = TableOperand.GetByNumbers(4, true).MainAttr; if (TableOperand.TypeSecond >= TableOperand.Types.Мітка && TableOperand.TypeSecond <= TableOperand.Types.Адресний_вираз) UserNumber = TableOperand.GetByNumbers(4, false).MainAttr; if (UserNumber > 0) { Offset = Convert.ToString(TableUser.GetByNumber(UserNumber).Offset, 16); Offset = CheckCharCount(Offset, 8); if (CurrInstr.Name == "JMP" && !CurrInstr.IsModRm) Offset += " ----"; } return Offset.ToUpper(); }
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 CountOffset(TableCurrInstruct CurrInstr) { if ((TableOperand.TypeFirst >= TableOperand.Types.Мітка && TableOperand.TypeFirst <= TableOperand.Types.Адресний_вираз) || (TableOperand.TypeSecond >= TableOperand.Types.Мітка && TableOperand.TypeSecond <= TableOperand.Types.Адресний_вираз)) CurrInstr.IncByteCount(4, TableCurrInstruct.Types.зміщення); if (CurrInstr.Name == "JMP" && !CurrInstr.IsModRm) CurrInstr.IncByteCount(2, TableCurrInstruct.Types.зміщення); }
private static string CreatePrefix(TableCurrInstruct CurrInstr) { bool isFirstOp = CurrInstr.Name == "MOV" ? false : true; int DefaultRegisterNum = 3;//ds int MultipliedRegister = TableOperand.GetByNumbers(8, isFirstOp).MainAttr; int FirstAdressRegister = TableOperand.GetByNumbers(6, isFirstOp).MainAttr; int SecondAdressRegister = TableOperand.GetByNumbers(7, isFirstOp).MainAttr; if (MultipliedRegister != 4 && MultipliedRegister != 5)//множитель не при ebp esp if (FirstAdressRegister == 4 || FirstAdressRegister == 5 || //ebp или esp есть SecondAdressRegister == 4 || SecondAdressRegister == 5) DefaultRegisterNum = 2;//ss string Prefix = ""; TableOperand OperPref = TableOperand.GetByNumbers(3, isFirstOp); if (OperPref.IsLexemePresent)//задан явно == не совпадает по умолчанию { Prefix = TableRegister.GetByNumbers(OperPref.MainAttr, 2).PrefixString;//нужный префикс // CurrInstr.Prefix = Prefix; } else //префикс не задан явно { int userNumber = TableOperand.GetByNumbers(4, isFirstOp).MainAttr;//номер рядка в таблиці користувача string logicSegment = TableUser.GetByNumber(userNumber).ActiveSeg;//ім'я логічного сегменту string userRegister = TableAssume.GetByName(logicSegment);//имя регистра логического сегмента var Register = TableRegister.GetByName(userRegister);//сам регистр if (Register != null && Register.Number != DefaultRegisterNum)//нужно генерировать незаданный префикс { Prefix = Register.PrefixString; // CurrInstr.Prefix = Prefix; } } return Prefix; }
private static string CreateImmediate(TableCurrInstruct CurrInstr) { return(""); }
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.модрм); }