Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import java.io.BufferedReader;
- import java.io.FileOutputStream;
- import java.io.FileReader;
- import java.io.IOException;
- import java.io.PrintWriter;
- import java.io.File;
- import java.util.ArrayList;
- import java.util.regex.Pattern;
- import java.util.StringTokenizer;
- /**
- * @author Selden
- *
- */
- public class MyKurs {
- // абсолютные пути ко всем файлам
- static String File_name_and_Path = "D:\\program.asm"; // "/media/Data/program.asm";
- static String Listing_name_and_Path = "D:\\listing.txt"; // "/media/Data/listing.txt";
- static String Obj_name_and_Path = "D:\\program.obj"; // "/media/Data/listing.txt";
- // настройка режима вывода ошибок (true - выводить все ошибки, false - останавливаться на первой ошибке)
- static boolean errorMode=false;
- // Настройка режима отладки: писать отладочную инфо в терминал(debugMode=true), или нет(debugMode=false).
- static boolean debugMode=true;
- static boolean error=false; // признак наличия ошибок в исходном тексте программы
- static BufferedReader in=null;
- static FileOutputStream bin=null;
- static PrintWriter out=null;
- static String Line;
- static String []Lines; // array with lines of current text file
- static ArrayList<String> RawLines=new ArrayList<String>(); // массив, содержащий все строки текстового файла
- static ArrayList<String> сommandLines=new ArrayList<String>(); // массив, содержащий все строки области команд
- static ArrayList<String> dataLines=new ArrayList<String>(); // массив, содержащий все строки области данных
- static ArrayList<String> MetkiTemp=new ArrayList<String>();
- // каждый элемент данного массива - "<имя метки> адрес"
- static ArrayList<String> ConstTemp=new ArrayList<String>();
- // каждый элемент данного массива - "<имя константы> адрес"
- static String [][]TSI; // таблица символических имен
- static int Schak; // ну а это самое страшное - счетчик адреса команды =)
- static String CSName; // имя области команд (Задается директивой SEGMENT)
- static String DSName; // имя области команд (Задается первым появившимся DB, который идет с именем сегмента ТОЛЬКО в одной строке)
- static int startAddress ; // адрес, указанный в ORG
- static int linecount; // указатель текущей обрабатываемой строки
- static String RegT[][] = { // имена регистров (код регистра==поле reg или r/m - при записи в бинарник равен индексу j колонки)
- {"AL","CL","DL","BL","AH","CH","DH","BH"}, // w=0
- {"AX","CX","DX","BX","SP","BP","SI","DI"} // w=1
- };
- static String Reg =" AL CL DL BL AH CH DH BH AX CX DX BX SP BP SI DI ";
- static String Reg8 =" AL CL DL BL AH CH DH BH ";
- static String Reg16 = " AX CX DX BX SP BP SI DI ";
- static String MnemoT[]={"MOV","SBB","MUL","JA", "DB", "INT"};
- static int NumOfOperands[]={ 2, 1, 1, 1, 1, 1};
- static String [] Types = {"Com","Com","Com","Com","Dir", "Com"};
- static String FormatOfOp[]={
- // MOV
- " R8,R8 R16,R16 R8,IMM8 R16,IMM16 R16,IMM8 R8,O8 R8,O16 R16,O8 R16,O16 O8,R8 O16,R8 O8,R16 O16,R16 R8,M R16,M ",//O8,IMM8 O16,IMM8 O8,IMM16 O16,IMM16 O8,M O16,M ",
- // SBB
- " R8,R8 R16,R16 R8,IMM8 R16,IMM16 R16,IMM8 R8,O8 R8,O16 R16,O8 R16,O16 O8,R8 O16,R8 O8,R16 O16,R16 R8,M R16,M ", //SBB
- " R16 R8 ", //MUL
- " M ", //JA
- " IMM8 ", //DB
- " IMM8 "}; //INT 20h
- static String ByteSizeOp []={
- "2 2 2 3 2 4 4 4 4 4 4 4 4 2 2", //6 6 6 6 6 6", // MOV
- "2 2 2 3 2 4 4 4 4 4 4 4 4 2 2",
- "2 2", //MUL
- "2", //JA
- "1", //DB
- "2"}; //INT 20h
- // static String FormatOfOperands[][]= { // длина команды в оп
- // { "R8,R8", // 2
- // "R16,R16", // 2
- // "R8,IMM8", // 2
- // "R16,IMM16", // 3
- // "R16,IMM8", // 2
- // "R8,O8", // 4
- // "R8,O16", // 4
- // "R16,O8", // 4
- // "R16,O16", // 4
- // "O8,R8", // 4
- // "O16,R8", // 4
- // "O8,R16", // 4
- // "O16,R16", // 4
- // "R8,M", // 2
- // "R16,M"}, // 2
- // "O8,IMM8" // 6
- // "O16,IMM8" // 6
- // "O8,IMM16" // 6
- // "O16,IMM16"// 6
- // "O8,M" // 6
- // "O16,M" // 6 MOV
- //
- // {"R16", // 2
- // "R8"}, // 2 //MUL
- //
- // {"M"}, // 2 //JA
- // {"IMM8"}, // 1 //DB
- // {"IMM8"}, // 2 //INT 20h
- //};
- static String commands_in_line=" MOV ORG DB OFFSET MUL JA SEGMENT END ENDS INT "; //все команды и директивы в одной строке
- static String [][] commandsToWrite;
- static ArrayList<String> ToWrite=new ArrayList<String>();
- public static void main(String[] args) throws IOException {
- initFile();
- checkForErrors(); // выйдет с помощью return если найдет любую ошибку в исходном коде и тогда просмотров не будет, а в листинг запишет ся ближайшая ошибка
- if(error){ return; } // если была найдена хотя бы одна ошибка, компиляцию надо остановить
- firstPass();
- //secondPass();
- }
- private static void initFile() throws IOException { try {
- File file=new File(File_name_and_Path);
- double InputFileSize=(double)(file.length())/1048576; // получаем размер исходного файла в мегабайтах
- if(InputFileSize>=0.5){error(14); if(!errorMode)return; }
- in = new BufferedReader(new FileReader(file));
- while ((Line = in.readLine()) != null) {
- if (Line.contains(";")) {Line = Line.substring(0, Line.indexOf(";"));}
- if(!Del_spaces(Line).equals(""))RawLines.add(Line.toUpperCase());
- }
- if(RawLines.size()==0){ // если входной файл пуст
- error(4); if(!errorMode)return;
- }
- Lines = new String[RawLines.size()];
- int currentItem = 0;
- for(String temp:RawLines){
- Lines[currentItem]=temp;
- currentItem++;
- }
- } catch (Exception e) {
- } finally { if (in!=null)in.close();
- System.out.println("Входные данные:");
- if(RawLines.size()!=0){for(int i=0; i<Lines.length;i++)System.out.println((i+1)+"). "+delFirstSpaces(Lines[i]));}
- System.out.println();
- }
- }
- private static void firstPass() {
- String []tmp=null;
- commandsToWrite=new String[ToWrite.size()][4]; // массив полей программы
- for(int i=0;i<ToWrite.size();i++){ // для каждой строки
- tmp=tokenize(ToWrite.get(i)," "); // разбили на слова
- for(int j=0;j<=3;j++){
- if(j==2&tmp[j].endsWith("H")&!Reg.contains(tmp[j])){
- tmp[j]=hex2dec(tmp[j])+""; }
- commandsToWrite[i][j]=tmp[j]; }}
- // печать вспомогательного массива
- if(debugMode){System.out.println("\nМассив для первого проcмотра:");
- for(int i=0;i<commandsToWrite.length;i++){for(int j=0;j<commandsToWrite[0].length;j++)System.out.print("{"+commandsToWrite[i][j]+"},");
- System.out.println(); }
- //System.out.println("ArrayList меток"+MetkiTemp);
- }
- // собственно погнали творить чудеса
- TSI=new String[MetkiTemp.size()+ConstTemp.size()][3]; // массив для проверки меток
- int k=0;
- for(int i=0; i<MetkiTemp.size();i++,k++){
- TSI[i][0]=tokenize(MetkiTemp.get(i)," ")[0];
- TSI[i][1]=tokenize(MetkiTemp.get(i)," ")[1];
- TSI[i][2]=tokenize(MetkiTemp.get(i)," ")[2];
- k=i;
- }
- for(int i=0; i<ConstTemp.size();i++){
- TSI[k+i][0]=tokenize(ConstTemp.get(i)," ")[0];
- TSI[k+i][1]=tokenize(ConstTemp.get(i)," ")[1];
- TSI[k+i][2]=tokenize(ConstTemp.get(i)," ")[2];
- }
- if(debugMode){
- System.out.println("\nТаблица символических имен:");
- for(int i=0;i<TSI.length;i++){
- for(int j=0;j<TSI[0].length;j++){
- System.out.print("{"+TSI[i][j]+"}");}System.out.println();
- }}
- }
- private static void secondPass() {
- }
- private static void checkForErrors() { try{
- Schak=0;
- startAddress=0;
- linecount=0;
- CSName="";
- DSName="";
- if(Lines.length==0){ error(4); if(!errorMode)return; } // если в файле нет ничего, кроме пустых строк или файл вообще пуст
- //анализ первой строки
- String []temp=Lines[linecount].trim().split("\\s+"); // получаем массив из слов первой строки
- if(temp.length==2){ // в первой строке должно быть 2 слова и никак иначе
- if("SEGMENT".equals(temp[1])){ // если директива "SEGMENT" на своем месте (вторым словом в строке)
- if(goodName(temp[0])){ //если имя сегмента соответствует формату,
- CSName=temp[0]; // копируем его в переменную,
- } else {error(3); if(!errorMode)return;} // если имя сегмента не соответствует формату (первой не может быть цифра)
- } else {error(2); if(!errorMode)return;} // иначе ошибка =)
- } else {error(1); if(!errorMode)return;} // и иначе, сука, тоже ошибка =)
- linecount++; // анализ второй строки
- temp=Lines[linecount].trim().split("\\s+"); // получаем массив из слов второй строки
- if(temp.length==2){
- if("ORG".equals(temp[0])){ // если директива ORG на месте
- if(is2_byte_unsigned_Const(temp[1])==2){ // если выражение после ORG - нормальная 2-х байтная беззнаковая константа
- // копируем адрес при ORG в переменную в десятеричном виде
- if(temp[1].endsWith("H"))startAddress=hex2dec(temp[1]); else Integer.parseInt(temp[1]);
- } else { // константа содержит ошибку
- if(is2_byte_unsigned_Const(temp[1])==1){error(8);} // если константа выходит за пределы 2 байт
- else error(5);if(!errorMode)return;}} // если константа записана неверно
- else {error(6);if(!errorMode)return;}} // если во второй строке нет директивы ORG
- else {error(7);if(!errorMode)return;} // если в строке №2 не 2 слова
- linecount++; // старт собственно анализа команд
- if(linecount>=Lines.length){ // если после ORG ничего нет
- error(9); if(!errorMode)return;
- }
- boolean hasINT20H=false;
- int tempLinecount=linecount;
- while(tempLinecount<Lines.length&&!(Lines[tempLinecount].contains("INT 20H"))){
- сommandLines.add(Lines[tempLinecount]); // получаем arrayList из строк области команд
- try{if(delFirstSpaces(delLastSpaces(Lines[tempLinecount+1])).equals("INT 20H")){hasINT20H=true;}} catch (Exception m){}
- tempLinecount++;
- }
- if(!hasINT20H){error(26); if(!errorMode)return;}
- // и проверяем, содержится ли вообще в файле "INT 20H". Если его нет - ошибка.
- // создаем массив, который будет содержать поля области команд 4 столбца на n строк
- // commandsToWrite = new String[сommandLines.size()][3];
- String Metka,Mnemo,OP1,OP2; // temp-поля
- if(debugMode)System.out.println("\nОбласть команд");
- for(String str: сommandLines){// для каждой строки области команд
- // задача - разбить каждую строку области команд на 4 поля: метку, мнемокод, Оп1, Оп2.
- Metka=Mnemo=OP1=OP2=null; // обнуление temp-полей
- if(str.contains(":")){
- Metka=str.substring(0,str.lastIndexOf(":")); // отрезаем все до последнего двоеточия в строке, как метку
- if((Del_spaces(Metka+":")).equals(Del_spaces(str))){ // если в строке нет ничего, кроме метки - ошибка
- error(31); if(!errorMode)return;
- }
- while(Metka.endsWith(" "))Metka=Metka.substring(0,Metka.length()-1); // удаляем все пробелы В КОНЦЕ отрезанного куска
- while(Metka.startsWith(" "))Metka=Metka.substring(1); // удаляем все пробелы В НАЧАЛЕ отрезанного куска
- //а вдруг метка состоит не из одного слова, или ее имя начинается с цифры? Проверим...
- if(!goodName(Metka)){ // если метка задана неверно
- error(11); if(!errorMode)return; } else { // если же с меткой все в порядке
- str=str.substring(str.lastIndexOf(":")+1); // отрезать ее из строки к чертям, она уже есть у нас в переменной
- }
- if(debugMode)System.out.println("Встречена метка: "+Metka);
- for(String h:MetkiTemp){
- if((tokenize(h," ")[0]).equals(Metka)){error(32);if(!errorMode)return;}
- }
- MetkiTemp.add(Metka+" "+Schak+" Label");
- }
- // остаток строки делим на слова по пробелам и запятой.
- String []tempCommandLine=tokenize(str," ,\t");
- if(commands_in_line.contains(" "+tempCommandLine[0]+" ")){ // если первое слово является допустимым мнемокодом команды
- Mnemo=tempCommandLine[0];
- //System.out.print("Мнемокод: "+Mnemo+" ");
- } else {error(12);if(!errorMode)return;}
- int num=0;
- for(int i=0;i<MnemoT.length;i++){if(MnemoT[i].equals(Mnemo))num=NumOfOperands[i];} // определяем количество операндов текущей команды по ее мнемокоду
- if(tempCommandLine.length!=num+1){ // проверка на количество операндов
- error(13); System.out.println(" для команды "+Mnemo+"."); if(!errorMode)return;} // если у комады не может быть столько операндов
- // определяем тип операндов и в кодированном виде проверяем то ТФК, могут ли у данной команды быть такие типы операндов
- String opCodes="";
- for(int i=0;i<num;i++){ // для всех операндов команды
- String op=tempCommandLine[i+1];
- if(Reg8.contains(" "+op+" ")) { opCodes+="R8,";} else // если операнд - регистр
- if(Reg16.contains(" "+op+" ")) { opCodes+="R16,";} else
- if(goodName(op)){ // если операция == допустимое имя константы
- opCodes+="M,";
- } else
- if(is_Imm8(op)==2){ // если операнд - Imm8
- tempCommandLine[i+1]=hex2dec(op)+""; // дальше будем работать с 10-ричным представлением этого числа
- opCodes+="IMM8,";} else // если не Imm8
- if(is_Imm16(op)==2){ // если операнд - Imm16
- tempCommandLine[i+1]=hex2dec(op)+""; // дальше будем работать с 10-ричным представлением этого числа
- opCodes+="IMM16,";} else
- // или может, это память (базовая адресация вида [BX+5h] или просто [BX] )?
- if(checkBaseAddressing(op)>1) { // если операнд - адрес памяти с базовой адресацией
- // перевести метку в 10 - ричную систему
- if(checkBaseAddressing(op)==3)opCodes+="O16,"; else // с 2-байтным смещением
- if(checkBaseAddressing(op)==4|checkBaseAddressing(op)==2)opCodes+="O8,"; // без смещения или с 1-байтным смещением
- String smeshenie=tokenize(op,"[]BXP \t+-")[0]; // отрезаем число, на которое идет смещение
- if(smeshenie.endsWith("H")){
- op=op.substring(0,op.indexOf(smeshenie))+hex2dec(smeshenie)+"]"; // если смещение задано в 16-ричном виде, переводим его в 10-ричный формат
- }
- }
- else{ // если формат операнда не опознан - проверяем возможные ошибки пользователя
- // проверка содержимого квадратных скобок, если это адрес
- if(checkBaseAddressing(op)==1){error(15); if(!errorMode)return;} // если смещение вышло за пределы 2-х байт
- if(checkBaseAddressing(op)==-1){error(17); if(!errorMode)return;} // в базовой адресации неверно указан регистр
- if(is_Imm16(op)==1){error(18); if(!errorMode)return;} // непосредственный операнд вышел за пределы 2-х байт
- error(16); if(!errorMode)return; // ошибка "неизвестный формат операнда"
- }
- if(i==0)OP1=op; else OP2=op; // пишем проверенные операнды в подготовленные поля
- }
- while(opCodes.endsWith(","))opCodes=opCodes.substring(0,opCodes.length()-1); // убираем запятую в конце формируемой строки
- if(debugMode)System.out.print("Строка "+(linecount+1)+": мнемокод - "+Mnemo+", операнды: {"+opCodes+"}, длина команды - ");
- // теперь строчка opCodes содержит порядок операндов в команде или один операнд в
- for(int i=0;i<MnemoT.length;i++){if(MnemoT[i].equals(tempCommandLine[0])){ // для текущей команды
- if(!FormatOfOp[i].contains(" "+opCodes+" ")){ // если у текущей команды не может быть такого порядка операндов
- error(19); if(!errorMode)return;}
- // если у текущей команды могут быть такие операнды,
- // проверка, сколько занимает команда с такими операндами в объектном файле и выполним увеличение СчАК
- String tmp[]=FormatOfOp[i].trim().split("\\s+");
- for(int j=0;j<tmp.length;j++){
- if(tmp[j].equals(opCodes)){
- int g=Integer.parseInt(ByteSizeOp[i].split("\\s+")[j]);
- Schak+=g;
- if(debugMode){System.out.println(g); System.out.println("Счак="+Schak);}}
- }}}
- String toWrite="";
- if(Metka!=null)Metka+=":";
- ToWrite.add(Metka+" "+Mnemo+" "+OP1+" "+OP2); // добавляем команду, не содержащую ошибок в ArrayList. К метке в конце приписываем ":"
- if(debugMode){System.out.print("To write: "); System.out.println(Metka+" "+Mnemo+" "+OP1+" "+OP2);}
- //System.out.println("Строка "+(linecount+1)+": мнемокод - "+Mnemo+", операнды: {"+opCodes+"}");
- linecount++;
- }
- // теперь мы находимся в строке, где был встречен INT 20H (просто встречен в составе строки, он еще может быть неверно записан)
- if(!delFirstSpaces(delLastSpaces(Lines[linecount])).equals("INT 20H")){ // если кроме "INT 20H" и пробелов есть какой-то лишний мусор из символов
- error(25); if(!errorMode)return;
- } else { linecount++; // если ошибки нет переход к следующей строке
- if(debugMode)System.out.println("Строка "+linecount+": мнемокод - INT 20h, операнды: {IMM8}, длина команды - 2.");
- ToWrite.add("null INT 20H null"); // добавляем INT 20h в ArrayList.
- Schak+=2; // добавляем к Счак длину команды INT 20h
- if(debugMode){
- System.out.println("Счак="+Schak);
- System.out.print("To write: ");
- System.out.println("null INT 20H null");
- System.out.println("Конец области команд.");
- }
- }
- // теперь мы находимся в строке, где находится первый DB
- if(debugMode)System.out.println("\nОбласть данных");
- while(linecount<Lines.length&&!Lines[linecount].contains("END")){ // для всех строк области данных, от "INT 20H" без него до ближайшего ENDS или, если ENDS не встречен - до конца файла
- Metka=Mnemo=OP1=OP2=null; // обнуление temp-полей для каждой строки
- dataLines.add(Lines[linecount]); // сохраняем строки в ArrayList
- String []DataLine=Lines[linecount].trim().split("\\s+"); // получаем массив из слов этой строки
- if(!goodName(DataLine[0])){error(20);if(!errorMode)return;} else {Metka=DataLine[0];} // если у объявляемой переменной неверное имя
- if(DataLine.length>3){error(21);if(!errorMode)return;} // если в строке с DB больше, чем 3 слова
- if(DataLine.length<3){error(22);if(!errorMode)return;} // или меньше 2-х слов
- if(is_Imm8(DataLine[2])==0){error(23);if(!errorMode)return;} else {OP1=DataLine[2];} // неверно задана константа в DB
- if(is_Imm8(DataLine[2])==1){error(24);if(!errorMode)return;} // константа в DB вышла за пределы
- Mnemo=DataLine[1]; // !!!!!!!! DW ?
- ToWrite.add(Metka+" "+Mnemo+" "+OP1+" "+OP2);
- if(debugMode){System.out.print("To write: "); System.out.println(Metka+" "+Mnemo+" "+OP1+" "+OP2);}
- if(OP1.endsWith("H"))OP1=hex2dec(OP1)+"";
- ConstTemp.add(Metka+" "+OP1+" VAR");
- Schak+=1; // продвигаем Счак на 1 байт
- if(debugMode)System.out.println("Счак="+Schak);
- linecount++;
- }
- if(debugMode)System.out.println();
- // проверки наличия конца сегмента (<имя сегмента> ENDS) и команды END
- //если мы находимся в конце файла, но слово "ENDS" вообще не было встречено
- try{
- if(Lines[linecount]!=null){ // если есть хотя бы сама строка, которая должна содержать <Имя сегмента> "ENDS"
- // проверка правильности строки с директивой <Имя сегмента> ENDS
- if(!delFirstSpaces(delLastSpaces(Lines[linecount])).equals(CSName+" ENDS")){ // если неверно указано имя сегмента в директиве ENDS или в строке есть всякий левый мусор
- error(29); if(!errorMode)return;
- }
- if(Lines[linecount+1]!=null){ // если есть еще и строка, которая должна содержит "END" в любом виде
- // проверка правильности строки с директивой END
- if(!delFirstSpaces(delLastSpaces(Lines[linecount+1])).equals("END")){ // если неверно задана директива END
- error(30); if(!errorMode)return;}
- } else { error(28);if(!errorMode)return; } // ошибка "После директивы конца сегмента должна следовать директива END."
- }
- } catch(Exception m){ // исключение сработает, если уже конец файла, но еще не было "ENDS" и "END"
- error(27);if(!errorMode)return;} // ошибка "отутствует конец сегмента" // неверный конец программы
- } catch(Exception r){System.out.println("Ошибка в работе программы. "+r);}
- } // конец обработки всех строк
- private static void error(int code) { System.out.println("\nОшибка ["+code+"] в строке "+(linecount+1)+"."); error=true;
- switch(code){
- case 1: System.out.println("Первая строка должна иметь формат: <segment name> SEGMENT\nи не может содержать других директив, меток, команд или лишних сиволов."); break;
- case 2: System.out.println("Первая строка должна содержать директиву \"SEGMENT\"."); break;
- case 3: System.out.println("Неверное имя сегмента кода."); break;
- case 4: System.out.println("Исходный файл не содержит данных."); break;
- case 5: System.out.println("Неверно задан адрес при директиве ORG."); break;
- case 6: System.out.println("Отсутствует директива ORG."); break;
- case 7: System.out.println("Вторая строка должна иметь формат: <ORG выражение> \nи не может содержать других директив, меток, команд или лишних сиволов."); break;
- case 8: System.out.println("Константа при ORG выходит за пределы 2-х байт."); break;
- case 9: System.out.println("Отсутствует директива конца сегмента "+CSName+"."); break;
- case 10: System.out.println("Неверный формат строки, содержащей команду."); break;
- case 11: System.out.println("Неверное имя метки."); break;
- case 12: System.out.println("Недопустимый мнемокод команды."); break;
- case 13: System.out.print ("Неверное количество операндов"); break;
- case 14: System.out.println("Размер исходного файла слишком велик. Выберите другой файл."); break;
- case 15: System.out.println("Смещение вышло за пределы 2-х байт."); break;
- case 16: System.out.println("Неверный формат операнда. "); break;
- case 17: System.out.println("Неверно указан регистр для базовой адресации. "); break;
- case 18: System.out.println("Непосредственный операнд вышел за допустимые пределы. "); break;
- case 19: System.out.println("Неверное задание операндов."); break;
- case 20: System.out.println("Неверное имя переменной."); break;
- case 21: System.out.println("Строка определения данных не может содержать ничего, кроме метки, директивы DB и задаваемой константы."); break;
- case 22: System.out.println("Неверный формат строки определения данных."); break;
- case 23: System.out.println("Константа задана неверно."); break;
- case 24: System.out.println("Константа вышла за допустимые пределы."); break;
- case 25: System.out.println("Данная строка долна иметь формат: <INT 20h>"); break;
- case 26: System.out.println("Программа должна содержать область команд и строку <INT 20h>."); break;
- case 27: System.out.println("Отсутствует директива конца сегмента кода или директива END."); break;
- case 28: System.out.println("После директивы конца сегмента должна следовать директива END."); break;
- case 29: System.out.println("Директива ENDS, либо имя сегмента не заданы, или указано неверно."); break;
- case 30: System.out.println("Неверно указана директива END."); break;
- case 31: System.out.println("В строке с меткой должна присутствовать команда."); break;
- case 32: System.out.println("Использовано дублирующееся имя метки."); break;
- default: stopWork(); break;
- }
- }
- private static void stopWork() { try{
- if (in!=null)in.close();
- if (out!=null)out.close();
- System.exit(0);
- } catch(Exception e){}}
- private static void WriteBin() throws IOException { }
- static String Del_spaces(String line) {
- String[] a=line.trim().split("\\s+");
- String result="";
- for (String temp:a){result+=temp;}
- return result;
- }
- static String delFirstSpaces(String line){ try{
- while(line.startsWith(" "))line=line.substring(1);} catch (Exception m){}
- return line; }
- static String delLastSpaces(String line){ try{
- while(line.endsWith(" "))line=line.substring(0,(line.length()-1));} catch (Exception m){}
- return line; }
- private static int hex2dec(String s) {
- String digits="0123456789ABCDEF";
- s=s.toUpperCase();
- if(s.endsWith("H"))s=s.substring(0,s.indexOf("H"));
- int val=0;
- for (int i=0; i<s.length(); i++) {
- char c=s.charAt(i);
- int d=digits.indexOf(c);
- val=16*val+d;
- }
- return val;
- }
- private static String dec2hex(int d) {
- String digits = "0123456789ABCDEF";
- if (d==0)
- return "0";
- String hex = "";
- while (d>0) {
- int digit=d%16;
- hex=digits.charAt(digit)+hex;
- d=d/16;
- }
- return hex;
- }
- static int checkBaseAddressing(String what){ // соответствует ли строка базовой адресации (со смещением, но без масштабирования)
- // На выходе:
- // -1 - все плохо, встретилось недопустимое имя регистра
- // 0 - все плохо, входая строка однозначно не катит, как базовая адресация
- // 1 - есть смещение, но оно выходит за пределы двух байт
- // 2 - все отлично, вх. строка соответствует правильной базовой адресации без смещения
- // 3 - все отлично, вх. строка соответствует правильной базовой адресации со смещением в пределах 2 байт(от 0 до +65536)
- // 4 - все отлично, вх. строка соответствует правильной базовой адресации со смещением в пределах 1 байт(от 0 до +255)
- String temp1=what.split("\\s+")[0];
- if(!" BX BP ".contains(" "+temp1.substring(1,3)+" ")&what.startsWith("["))return -1; // если используется недопустимое имя регистра
- if(Pattern.compile("\\[B(P|X){1}\\]").matcher(what).matches()){ return 2;} else // без смещения
- if(Pattern.compile("\\[B(P|X){1}[\\+|-]\\d{1,}H{0,1}\\]").matcher(what).matches()){ // есть смещение
- try{ String smeshenie=tokenize(what,"[]BXP \t+-")[0]; // отрезаем число, на которое идет смещение
- if(smeshenie.endsWith("H"))smeshenie=hex2dec(smeshenie)+""; // если смещение задано в 16-ричном виде, переводим в 10-ричный формат
- if(is1_byte_unsigned_Const(smeshenie)==2) return 4; else
- if(is2_byte_unsigned_Const(smeshenie)==2) return 3; //смещение в пределах 2 байт(от 0 до +65536), т.е. - является беззнаковой константой
- else return 1; // выход смещения за пределы
- } catch (Exception r){} } else {
- if(Pattern.compile("\\[B(P|X){1}\\]").matcher(what).matches()){ return 2; }} //правильная базовая адресация без смещения
- return 0; } // неправильная базовая адресация
- static int checkIndexBaseAddressing(String what){ // соответствует ли строка базово-индексной адресации (со смещением, но без масштабирования)
- // На выходе:
- // 0 - все плохо, входая строка однозначно не катит, как базово-индексная адресация
- // 1 - есть смещение, но оно выходит за пределы двух байт
- // 2 - все отлично, вх. строка соответствует правильной базово-индексной адресации без смещения
- // 3 - все отлично, вх. строка соответствует правильной базово-индексной адресации со смещением в пределах 2 байт(от 0 до +65536)
- // 4 - все отлично, вх. строка соответствует правильной базово-индексной адресации со смещением в пределах 1 байт(от 0 до +255)
- if(Pattern.compile("\\[(B(P|X)){1}\\+{1}((D|S)I){1}\\]").matcher(what).matches()){ return 2;} else // без смещения
- if(Pattern.compile("\\[(B(P|X)){1}\\+{1}((D|S)I){1}[\\+|-]\\d{1,}H{0,1}\\]").matcher(what).matches()){ // есть смещение
- try{ String smeshenie=tokenize(what,"[]BXPDSI \t+-")[0]; // отрезаем число, на которое идет смещение
- if(smeshenie.endsWith("H"))smeshenie=hex2dec(smeshenie)+""; // если смещение задано в 16-ричном виде, переводим в 10-ричный формат
- if(is1_byte_unsigned_Const(smeshenie)==2) return 4; else
- if(is2_byte_unsigned_Const(smeshenie)==2) return 3; //смещение в пределах 2 байт(от 0 до +65536), т.е. - является беззнаковой константой
- else return 1; // выход смещения за пределы
- } catch (Exception r){} } else {
- if(Pattern.compile("\\[B(P|X){1}\\]").matcher(what).matches()){ return 2; }} //правильная базовая адресация без смещения
- return 0; } // неправильная базовая адресация
- private static boolean isRegistry(String what){ // проверка, является ли строка верным обозначением регистра
- if(Reg.contains(" "+what+" "))return true; return false;}
- private static int is2_byte_signed_Const(String what) { // проверка, является ли число 2-байтной знаковой константой (HEX или DEC в пределах от -32768 до +32767)
- int start=-32768; int end=32767;
- // На выходе:
- // 0 - все плохо, входая строка однозначно не константа
- // 1 - выход за пределы двух байт
- // 2 - все отлично, вх. данные - 2-байтная знаковая константа
- if(Pattern.compile("((\\d|[ABCDEF]){1,}H{1})").matcher(what).matches()){ // 16 - ричное число
- if(hex2dec(what.substring(0,what.length()-1))<=end & hex2dec(what.substring(0,what.length()-1))>=start)return 2;else{return 1;}}
- if(Pattern.compile("-{0,1}\\d{1,}").matcher(what).matches()){ // 10 - ричное число
- if(Integer.parseInt(what)<=end & Integer.parseInt(what)>=start)return 2;else{return 1;}}
- return 0;
- }
- private static int is_Imm8(String what) { // проверка, является ли число 1-байтной знаковой константой (HEX или DEC в пределах от -127 до +255)
- int start=-127; int end=255;
- // На выходе:
- // 0 - все плохо, входая строка - не Imm8
- // 1 - выход за пределы
- // 2 - все отлично, вх. строка - Imm8
- if(Pattern.compile("((\\d|[ABCDEF]){1,}H{1})").matcher(what).matches()){ // 16 - ричное число
- if(hex2dec(what.substring(0,what.length()-1))<=end & hex2dec(what.substring(0,what.length()-1))>=start)return 2;else{return 1;}}
- if(Pattern.compile("-{0,1}\\d{1,}").matcher(what).matches()){ // 10 - ричное число
- if(Integer.parseInt(what)<=end&Integer.parseInt(what)>=start)return 2;else{return 1;}}
- return 0;
- }
- static int is_Imm16(String what) { // проверка, является ли число 1-байтной знаковой константой (HEX или DEC в пределах от -32768 до +65536)
- int start=-32768; int end=65536;
- // На выходе:
- // 0 - все плохо, входая строка - не Imm16
- // 1 - выход за пределы
- // 2 - все отлично, вх. строка - Imm16
- if(Pattern.compile("((\\d|[ABCDEF]){1,}H{1})").matcher(what).matches()){ // 16 - ричное число
- if(hex2dec(what.substring(0,what.length()-1))<=end & hex2dec(what.substring(0,what.length()-1))>=start)return 2;else{return 1;}}
- if(Pattern.compile("-{0,1}\\d{1,}").matcher(what).matches()){ // 10 - ричное число
- if(Integer.parseInt(what)<=end&Integer.parseInt(what)>=start)return 2;else{return 1;}}
- return 0;
- }
- static boolean goodName(String what){ // проверка на то, чтобы в строке первой не была цифра
- return Pattern.compile("[\\D&&[\\w]][\\w]*").matcher(what).matches();
- }
- private static int is2_byte_unsigned_Const(String what) { // проверка, является ли число беззнаковой 2-байтной константой (HEX или DEC в пределах 0..65536(FFFFH))
- int start=0; int end=65536;
- // На выходе:
- // 0 - все плохо, входая строка однозначно не беззнаковая константа
- // 1 - выход беззнаковой константы за пределы двух байт
- // 2 - все отлично, вх. данные - 2-байтная беззнаковая константа
- if(Pattern.compile("((\\d|[ABCDEF]){1,}H{1})").matcher(what).matches()){ // 16 - ричное число
- if(hex2dec(what.substring(0,what.length()-1))>=start & hex2dec(what.substring(0,what.length()-1))<=end)return 2;else{return 1;}}
- if(Pattern.compile("\\d{1,}").matcher(what).matches()){ // 10 - ричное число
- if(Integer.parseInt(what)>=start & Integer.parseInt(what)<=end)return 2;else{return 1;}}
- return 0;
- }
- private static int is1_byte_unsigned_Const(String what) { // проверка, является ли число беззнаковой 2-байтной константой (HEX или DEC в пределах 0..65536(FFFFH))
- int start=0; int end=255;
- // На выходе:
- // 0 - все плохо, входая строка однозначно не беззнаковая константа
- // 1 - выход беззнаковой константы за пределы двух байт
- // 2 - все отлично, вх. данные - 2-байтная беззнаковая константа
- if(Pattern.compile("((\\d|[ABCDEF]){1,}H{1})").matcher(what).matches()){ // 16 - ричное число
- if(hex2dec(what.substring(0,what.length()-1))>=start & hex2dec(what.substring(0,what.length()-1))<=end)return 2;else{return 1;}}
- if(Pattern.compile("\\d{1,}").matcher(what).matches()){ // 10 - ричное число
- if(Integer.parseInt(what)>=start & Integer.parseInt(what)<=end)return 2;else{return 1;}}
- return 0;
- }
- static int getAdressFromName(String name) {
- int adress = 9999;
- for (int i = 0; i < TSI.length; i++) {
- if (TSI[i][0].equals(name)) {
- try {
- return Integer.parseInt(TSI[i][1]);
- } catch (Exception m) {
- }
- }
- }
- // метки - в массиве Metki, массив для записи - commandsToWrite
- return adress;
- }
- private static String[] tokenize(String what, String razdeliteli){ // разделение токенайзером строки на массив String по поступившим разделителям
- StringTokenizer st=new StringTokenizer(what,razdeliteli);
- String []mas=new String[st.countTokens()]; int i=0;
- while (st.hasMoreElements()) { mas[i] = st.nextElement().toString(); i++;}
- return mas;
- }
- private static void printMas(String [][]Mas){
- for (int i = 0; i < Mas.length; i++) {
- for (int j = 0; j < Mas[0].length; j++)
- System.out.printf("%8s ", "{"+Mas[i][j]+"},");
- System.out.println();
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement