Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: Общие вопросы > Дизассемблер арифметических команд под x86


Автор: mycodeurnightmare 31.3.2016, 23:58
Доброго времени суток!
Вот всё задание:
Задан двоичный код, представляющий программу процес¬сора 8088/86. Составить программу дизассемблирования этого двоичного кода. Результат дизассемблирования должен содержать следующую информацию:
- мнемонический код машинной команды (в формате отладчика типа АТ 86),
- устанавливаемые машинной командой флаги,
Исходный двоичный код должен быть введен в режиме ASCII (либо с помощью любого текстового редактора, либо с помощью блока ввода в составляемой программе) и сох¬ранен в виде текстового файла). Для дальнейшего дизассемблирования исходного кода он должен быть преобразован
в битовый код, сохраняемый либо в ОЗУ либо в виде файла.
Ограничения:
В исходный двоичный код должны быть включены только арифметические команды.
Я накодил, невероятно коряво, но работало.
Показал преподавателю(лучше бы не показывал). Теперь она хочет, чтобы все кодировки регистров, адресации памяти и опкоды считывались из файла, можно ли из файла считать в мапу и ключи и значения? Но это ещё пол беды, ещё она хочет, чтобы, в зависимости от опкода, вызывался метод его обрабатывающий. Было бы замечательно создать какой-нибудь Map<опкод,"что-то, что будет вызывать метод">, но ума не приложу, как это сделать и можно ли сделать вообще.
Заранее огромное спасибо за любую помощь.
Вот сам код(не весь). 
Код

    package spo_1;
     
    import java.util.Map;
    import java.util.Scanner;
    import java.util.TreeMap;
     
    public class SPO_1 {
     
        public static void main(String[] args) {
            Map<String, String> NewNames = new TreeMap<>();
            Map DirectAddr8 = new TreeMap();
            Map DirectAddr16 = new TreeMap();
            Map LinkedAddr = new TreeMap();
    //=====================================================
            DirectAddr8.put("000", "AL");
            DirectAddr8.put("001", "CL");
            DirectAddr8.put("010", "DL");
            DirectAddr8.put("011", "BL");
            DirectAddr8.put("100", "AH");
            DirectAddr8.put("101", "CH");
            DirectAddr8.put("110", "DH");
            DirectAddr8.put("111", "BH");
    //=====================================================        
            DirectAddr16.put("000", "AX");
            DirectAddr16.put("001", "CX");
            DirectAddr16.put("010", "DX");
            DirectAddr16.put("011", "BX");
            DirectAddr16.put("100", "SP");
            DirectAddr16.put("101", "BP");
            DirectAddr16.put("110", "SI");
            DirectAddr16.put("111", "DI");
     
    //=====================================================
            LinkedAddr.put("000", "[BX+SI+");
            LinkedAddr.put("001", "[BX+DI+");
            LinkedAddr.put("010", "[BP+SI+");
            LinkedAddr.put("011", "[BP+DI+");
            LinkedAddr.put("100", "[SI+");
            LinkedAddr.put("101", "[DI+");
            LinkedAddr.put("110", "[BP+");
            LinkedAddr.put("111", "[BX+");
    //=====================================================
     
    //--------------------------------------------------------------
            NewNames.put("00000100", "ADD ");//AX/AL,DATA
            NewNames.put("00000101", "ADD ");//----------
            NewNames.put("10000000000", "ADD ");//R/M,DATA 1
            NewNames.put("10000001000", "ADD ");//
            NewNames.put("10000010000", "ADD WORD PTR ");//-------
            NewNames.put("00000010", "ADD ");//REG,R/M
            NewNames.put("00000011", "ADD ");//----------
            NewNames.put("00000000", "ADD ");//R/M, REG
            NewNames.put("00000001", "ADD ");//----------
    //---------------------------------------------------------------
            NewNames.put("00010100", "ADC ");
            NewNames.put("00010101", "ADC ");
            NewNames.put("10000000010", "ADC ");//R/M,DATA 1
            NewNames.put("10000001010", "ADC ");//
            NewNames.put("10000010010", "ADC WORD PTR ");//-------
            NewNames.put("00010010", "ADC ");//REG,R/M
            NewNames.put("00010011", "ADC ");//----------
            NewNames.put("00010000", "ADC ");//R/M, REG
            NewNames.put("00010001", "ADC ");//----------
    //---------------------------------------------------------------
            NewNames.put("00101100", "SUB ");
            NewNames.put("00101101", "SUB ");
            NewNames.put("10000000101", "SUB ");//R/M,DATA 1
            NewNames.put("10000001101", "SUB ");//
            NewNames.put("10000010101", "SUB WORD PTR ");//-------
            NewNames.put("00101010", "SUB ");//REG,R/M
            NewNames.put("00101011", "SUB ");//----------
            NewNames.put("00101000", "SUB ");//R/M, REG
            NewNames.put("00101001", "SUB ");//----------
     
    //---------------------------------------------------------------
            NewNames.put("00011100", "SBB ");
            NewNames.put("00011101", "SBB ");
            NewNames.put("10000000011", "SBB ");//R/M,DATA 1
            NewNames.put("10000001011", "SBB ");//
            NewNames.put("10000010011", "SBB WORD PTR ");//-------
            NewNames.put("00011010", "SBB ");//REG,R/M
            NewNames.put("00011011", "SBB ");//----------
            NewNames.put("00011000", "SBB ");//R/M, REG
            NewNames.put("00011001", "SBB ");//----------
    //---------------------------------------------------------------
            NewNames.put("00111100", "CMP ");
            NewNames.put("00111101", "CMP ");
            NewNames.put("10000000111", "CMP ");//R/M,DATA 1
            NewNames.put("10000001111", "CMP ");//
            NewNames.put("10000010111", "CMP WORD PTR ");//-------
            NewNames.put("00111010", "CMP ");//REG,R/M
            NewNames.put("00111011", "CMP ");//----------
            NewNames.put("00111000", "CMP ");//R/M, REG
            NewNames.put("00111001", "CMP ");//----------
    //---------------------------------------------------------------
            NewNames.put("11110110110", "DIV ");//R/M
            NewNames.put("11110111110", "DIV ");//R/M
            NewNames.put("11110110111", "IDIV ");//R/M
            NewNames.put("11110111111", "IDIV ");//R/M
            NewNames.put("11110110011", "NEG ");//R/M
            NewNames.put("11110111011", "NEG ");//R/M
            NewNames.put("11110110100", "MUL ");//R/M
            NewNames.put("11110111100", "MUL ");//R/M
            NewNames.put("11110110110", "IMUL ");//R/M
            NewNames.put("11110111101", "IMUL ");//R/M
            NewNames.put("11111110000", "INC ");//R/M
            NewNames.put("11111111000", "INC ");//R/M
            NewNames.put("11111110001", "DEC ");//R/M
            NewNames.put("11111111001", "DEC ");//R/M
     
    //--------------------------------------------------------------
            NewNames.put("10011001", "CWD");
            NewNames.put("10011000", "CBW");
            NewNames.put("01000", "INC ");
            NewNames.put("01001", "DEC ");
     
    //--------------------------------------------------------------
        
            Scanner s1 = new Scanner(System.in);
            String S1;
            S1 = s1.nextLine();
            System.out.println(S1);
            String S10 = S1.substring(0, 5);//для inc и dec с кодом регистра в опкоде
            String S11 = S1.substring(0, 8);
            String S21 = S1.substring(0, 8);
            String md = null;
            String rm = null;
     
            if (!(S11.equals("10011001") || S11.equals("10011000") || S10.equals("01000") || S10.equals("01001"))) {
                md = S1.substring(9, 11);//mod
                rm = S1.substring(14, 17);
                S21 += S1.substring(11, 14);
            }
     
            //однобайтные команды-----------------------------------------------------//
            if (S11.equals("10011001") || S11.equals("10011000")) {
                System.out.println(NewNames.get(S11) + " | O,S,Z,A,P,C");
                return;
            }
            //inc и dec с кодом регистра в опкоде-----------------------------------//
            if (S10.equals("01000") || S10.equals("01001")) {
                System.out.println(NewNames.get(S10) + DirectAddr8.get(S1.substring(5, 8)) + " | O,S,Z,A,P,C");
                return;
            }
     
     //команды c непосредственным операндом------------------------------------//
            //---------------mod=null----------------//
            if (S11.equals("00000100") || S11.equals("00010100") || S11.equals("00101100") || S11.equals("00011100") || S11.equals("00111100")) {
                System.out.println(NewNames.get(S11) + DirectAddr8.get("000") + "," + Integer.toHexString(Integer.parseInt(S1.substring(9, 17), 2)) + " | O,S,Z,A,P,C");
                return;
            }
     
            if (S11.equals("00000101") || S11.equals("00010101") || S11.equals("00101101") || S11.equals("00011101") || S11.equals("00111101")) {
                System.out.println(NewNames.get(S11) + DirectAddr16.get("000") + "," + Integer.toHexString(Integer.parseInt(S1.substring(9, 17), 2)) + Integer.toHexString(Integer.parseInt(S1.substring(18, 26), 2)) + " | O,S,Z,A,P,C");
                return;
            }
            //---------------mod=11----------------//
            if (md.equals("11")) {//проверка mod
                //команды c непосредственным операндом------------------------------------//
                if (S21.equals("10000000000") || S21.equals("10000000010") || S21.equals("10000000101") || S21.equals("10000000011") || S21.equals("10000000111")) {
                    System.out.println(NewNames.get(S21) + DirectAddr8.get(S1.substring(14, 17)) + "," + Integer.toHexString(Integer.parseInt(S1.substring(18, 26), 2)) + " | O,S,Z,A,P,C");
                    return;
     
                }
     
                if (S21.equals("10000001000") || S21.equals("10000001010") || S21.equals("10000001101") || S21.equals("10000001011") || S21.equals("10000001111")) {
                    System.out.println(NewNames.get(S21) + DirectAddr16.get(S1.substring(14, 17)) + "," + Integer.toHexString(Integer.parseInt(S1.substring(18, 26), 2)) + Integer.toHexString(Integer.parseInt(S1.substring(27, 35), 2)) + " | O,S,Z,A,P,C");
                    return;
                }
     
                if (S21.equals("10000010000") || S21.equals("10000010010") || S21.equals("10000010101") || S21.equals("10000010011") || S21.equals("10000010111")) {
                    System.out.println(NewNames.get(S21) + DirectAddr16.get(S1.substring(14, 17)) + "," + Integer.toHexString(Integer.parseInt(S1.substring(18, 26), 2)) + " | O,S,Z,A,P,C");
                    return;
                }
                //-----------------команды reg,r/m-----------------------------------------------------//
                if (S11.equals("00000010") || S11.equals("00010010") || S11.equals("00101010") || S11.equals("00011010") || S11.equals("00111010") || S11.equals("00000000") || S11.equals("00010000") || S11.equals("00101000") || S11.equals("00011000") || S11.equals("00111000")) {
                    System.out.println(NewNames.get(S11) + DirectAddr8.get(S1.substring(11, 14)) + ", " + DirectAddr8.get(S1.substring(14, 17)) + " | O,S,Z,A,P,C");
                    return;
                }
                if (S11.equals("00000010") || S11.equals("00010010") || S11.equals("00101010") || S11.equals("00011010") || S11.equals("00111011") || S11.equals("00000001") || S11.equals("00010001") || S11.equals("00101001") || S11.equals("00011001") || S11.equals("00111001")) {
                    System.out.println(NewNames.get(S11) + DirectAddr16.get(S1.substring(11, 14)) + ", " + DirectAddr16.get(S1.substring(14, 17)) + " | O,S,Z,A,P,C");
                    return;
                }
                //-----------------команды r/m-----------------------------------------------------//
                if (S21.equals("11110110110") || S21.equals("11110110111") || S21.equals("11110110011") || S21.equals("11110110100") || S21.equals("11110110101") || S21.equals("11111110000") || S21.equals("11111110001")) {
                    System.out.println(NewNames.get(S21) + DirectAddr8.get(S1.substring(14, 17)) + " | O,S,Z,A,P,C");
                    return;
                }
                if (S21.equals("11110111110") || S21.equals("11110111111") || S21.equals("11110111011") || S21.equals("11110111100") || S21.equals("11110111101") || S21.equals("11111111000") || S21.equals("11111111001")) {
                    System.out.println(NewNames.get(S21) + DirectAddr16.get(S1.substring(14, 17)) + " | O,S,Z,A,P,C");
                    return;
                }
            }
     
            //---------------mod=01----------------//
            if (md.equals("01")) {//проверка mod
                //команды c непосредственным операндом------------------------------------//
                if (S21.equals("10000000000") || S21.equals("10000000010") || S21.equals("10000000101") || S21.equals("10000000011") || S21.equals("10000000111") || S21.equals("10000010000") || S21.equals("10000010010") || S21.equals("10000010101") || S21.equals("10000010011") || S21.equals("10000010111")) {
                    System.out.println(NewNames.get(S21) + LinkedAddr.get(S1.substring(14, 17)) + Integer.toHexString(Integer.parseInt(S1.substring(18, 26), 2)) + "], " + Integer.toHexString(Integer.parseInt(S1.substring(27, 35), 2)) + " | O,S,Z,A,P,C");
                    return;
                }
                if (S21.equals("10000001000") || S21.equals("10000001010") || S21.equals("10000001101") || S21.equals("10000001011") || S21.equals("10000001111")) {
                    System.out.println(NewNames.get(S21) + LinkedAddr.get(S1.substring(14, 17)) + Integer.toHexString(Integer.parseInt(S1.substring(18, 26), 2)) + "], " + Integer.toHexString(Integer.parseInt(S1.substring(27, 35), 2)) + Integer.toHexString(Integer.parseInt(S1.substring(36, 44), 2)) + " | O,S,Z,A,P,C");
                    return;
                }
                //-----------------команды reg,r/m-----------------------------------------------------//
                if (S11.equals("00000010") || S11.equals("00010010") || S11.equals("00101010") || S11.equals("00011010") || S11.equals("00111010")) {
                    System.out.println(NewNames.get(S11) + DirectAddr8.get(S1.substring(11, 14)) + ", " + LinkedAddr.get(S1.substring(14, 17)) + Integer.toHexString(Integer.parseInt(S1.substring(18, 26), 2)) + "]" + " | O,S,Z,A,P,C");
                    return;
                }
                if (S11.equals("00000010") || S11.equals("00010010") || S11.equals("00101010") || S11.equals("00011010") || S11.equals("00111010")) {
                    System.out.println(NewNames.get(S11) + DirectAddr16.get(S1.substring(11, 14)) + ", " + LinkedAddr.get(S1.substring(14, 17)) + Integer.toHexString(Integer.parseInt(S1.substring(18, 26), 2)) + "]" + " | O,S,Z,A,P,C");
                    return;
                }
                //-----------------команды r/m,reg-----------------------------------------------------//
                if (S11.equals("00000000") || S11.equals("00010000") || S11.equals("00101000") || S11.equals("00011000") || S11.equals("00111000")) {
                    System.out.println(NewNames.get(S11) + LinkedAddr.get(S1.substring(14, 17)) + Integer.toHexString(Integer.parseInt(S1.substring(18, 26), 2)) + "]" + ", " + DirectAddr8.get(S1.substring(11, 14)) + " | O,S,Z,A,P,C");
                    return;
                }
                if (S11.equals("00000001") || S11.equals("00010001") || S11.equals("00101001") || S11.equals("00011001") || S11.equals("00111001")) {
                    System.out.println(NewNames.get(S11) + LinkedAddr.get(S1.substring(14, 17)) + Integer.toHexString(Integer.parseInt(S1.substring(18, 26), 2)) + "]" + ", " + DirectAddr16.get(S1.substring(11, 14)) + " | O,S,Z,A,P,C");
                    return;
                }
                
            }

Автор: LSD 1.4.2016, 17:12
Цитата(mycodeurnightmare @  1.4.2016,  00:58 Найти цитируемый пост)
можно ли из файла считать в мапу и ключи и значения?

Элементарно:
Код

    public static Map<String, String> readFromFile(String fileName, String separator) throws IOException {
        Map<String, String> map = new HashMap<>();
        try (BufferedReader reader = new BufferedReader(new FileReader(fileName))) {
            String[] split = reader.readLine().split(separator);
            if (split.length == 2) {
                map.put(split[0].trim(), split[1].trim());
            }
        }
        return map;
    }



Цитата(mycodeurnightmare @  1.4.2016,  00:58 Найти цитируемый пост)
Было бы замечательно создать какой-нибудь Map<опкод,"что-то, что будет вызывать метод">, но ума не приложу, как это сделать и можно ли сделать вообще.

В целом тоже несложно, создаешь интрейфейс наподобие:
Код

    public interface OpcodeParser {
        String getOpcode();
        String proccessOpcode(String opcode);
    }

Дальше пишешь реализацию. Можно на каждый опкод реализовывать свой, но лучше написать несколько стандартных реализаций и инициализировать их значениями.

Автор: mycodeurnightmare 1.4.2016, 18:53
Цитата(LSD @ 1.4.2016,  17:12)
Цитата(mycodeurnightmare @  1.4.2016,  00:58 Найти цитируемый пост)
можно ли из файла считать в мапу и ключи и значения?

Элементарно:
Код

    public static Map<String, String> readFromFile(String fileName, String separator) throws IOException {
        Map<String, String> map = new HashMap<>();
        try (BufferedReader reader = new BufferedReader(new FileReader(fileName))) {
            String[] split = reader.readLine().split(separator);
            if (split.length == 2) {
                map.put(split[0].trim(), split[1].trim());
            }
        }
        return map;
    }



Цитата(mycodeurnightmare @  1.4.2016,  00:58 Найти цитируемый пост)
Было бы замечательно создать какой-нибудь Map<опкод,"что-то, что будет вызывать метод">, но ума не приложу, как это сделать и можно ли сделать вообще.

В целом тоже несложно, создаешь интрейфейс наподобие:
Код

    public interface OpcodeParser {
        String getOpcode();
        String proccessOpcode(String opcode);
    }

Дальше пишешь реализацию. Можно на каждый опкод реализовывать свой, но лучше написать несколько стандартных реализаций и инициализировать их значениями.

Спасибо огромное! =3

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)