0

因此,我正在尝试完成一个程序,该程序创建一个可以将汇编语言转换为机器代码的 GUI。该程序需要 7 个类,但我遇到问题的部分是当按下“Assemble”按钮时,让程序 Assemble816 在 ASMEditor 的 actionlistener 中运行。每当我尝试不同的事情时,我都会遇到一百个不同的错误。几乎卡住了。

ASM 编辑器:

    public class ASMEditor extends JPanel {
        private JTextArea editArea;
        private JButton assembleButton;
        private JButton clearButton;
        private Assemble816 asm;
        private InstructionMemory iMem;


    public ASMEditor() {
        super( new BorderLayout() );
        setBackground( Color.white );
        Border blackLine = BorderFactory.createLineBorder(Color.black);
        setBorder(
            BorderFactory.createTitledBorder(blackLine, "Assembler"));

        editArea = new JTextArea();
        assembleButton = new JButton( "Assemble" );
        assembleButton.setBackground( getBackground() );
        assembleButton.addActionListener( new ActionListener() {
            public void actionPerformed( ActionEvent evt ) {
                System.out.println( editArea.getText() );
                try{
                    Assemble816 asm = new Assemble816();
                    //this is all I have

                }
                catch(Exception ex)
                {
                    JOptionPane.showMessageDialog(null, ex.getMessage());
                }

            }
        });
        clearButton = new JButton( "Clear" );
        clearButton.setBackground( getBackground() );
        clearButton.addActionListener( new ActionListener() {
            public void actionPerformed( ActionEvent evt ) {
                editArea.setText("");
            }
        });


        JPanel buttons = new JPanel( new FlowLayout(FlowLayout.LEFT, 5, 5 )); 
        buttons.setBackground( Color.white );
        buttons.add( assembleButton );
        buttons.add( clearButton );
        add( buttons, BorderLayout.NORTH );

        Border blueLine = BorderFactory.createLineBorder(Color.blue);
        editArea.setBorder( blueLine );
        editArea.setBackground( new Color( 205, 255, 255) );
        editArea.setFont(new Font("monospaced", Font.PLAIN, 14 ));
        add( editArea, BorderLayout.CENTER );
    }

   }

和组装816:

    public class Assemble816 {
    private InstructionMemory im;

    private static String[] twoOperand = {
        "add", "adc", "sub", "xor", "and", "or", "lshift", "ashift"
    };

    private static int lookupTwoOp( String op ) {
        int opcode = 0;
        for( String o : twoOperand ) {
            if ( o.equals( op ) ) {
                return opcode;
            }
            opcode++;
        }
        return -1;
    }

    private static String[] oneOperand = {
        "inc", "dec", "asr", "lsl"
    };

    private static int lookupOneOp( String op ) {
        int opcode = 0;
        for( String o : oneOperand ) {
            if ( o.equals( op ) ) {
                return opcode;
            }
            opcode++;
        }
        return -1;
    }

    private static String[] skip = {
        "skipeq", "skipne", "skipge", "skiplt"
    };

    private static int lookupSkip( String op ) {
        int opcode = 0;
        for( String o : skip ) {
            if ( o.equals( op ) ) {
                return opcode;
            }
            opcode++;
        }
        return -1;
    }

    private static String[] wordConstant = {
        "ldc", "ldd", "std"
    };

    private static int lookupConstant( String op ) {
        int opcode = 0;
        for( String o : wordConstant ) {
            if ( o.equals( op ) ) {
                return opcode;
            }
            opcode++;
        }
        return -1;
    }

    public Assemble816( final InstructionMemory im ){
        this.im = im;
    }

    private static void parseTwoArgs( Scanner sc, String [] words  )
    throws SyntaxError
    {
        String rest = sc.nextLine();
        String[] ws = rest.split(",");
        if ( ws.length != 2 ) {
            throw new SyntaxError("Missing words");
        }
        words[0] = ws[0].trim();
        words[1] = ws[1].trim();
    }

    private static int parseRegister( String reg ) throws SyntaxError {
        if ( reg.equals("r0") ) {
            return 0;
        }
        else if ( reg.equals("r1") ) {
            return 1;
        }
        else if ( reg.equals("r2") ) {
            return 2;
        }
        else if ( reg.equals("r3") ) {
            return 3;
        }
        else {
            throw new SyntaxError("Not a register: " + reg );
        }
    }

    private static int parseInteger( String i ) throws SyntaxError {
        String ii = i;
        try {
            int sign = 1;
            if ( i.charAt(0) == '-' ) {
                i = i.substring(1);
                sign = -1;
            }
            int radix = 10;
            if ( i.startsWith("0x") ) {
                radix = 16;
                i = i.substring(2);
            }
            else if ( i.charAt(0) == '0' ) {
                radix = 8;
            }
            return Integer.parseInt(i, radix ) * sign;
        }
        catch( NumberFormatException ex ) {
            throw new SyntaxError("Not a number: " + ii );
        }
    }

    private static String stripComments( String line ) {
        int split = line.indexOf(';');
        if ( split == -1 ) {
            return line;
        }
        else {
            return line.substring(0, split );
        }
    }

    private void printIM( int address, int length ) {
        int dataPerLine = 0;
        for (int a = address; a < (address+length); a++ ) {
            if ( dataPerLine == 0 ) {
                System.out.printf("%04x", a&0xffff );
                dataPerLine = 16;
            }
            System.out.printf(" %02x", im.fetch(a) & 0xff );
            dataPerLine--;
            if ( dataPerLine == 0 ) {
                System.out.println();
            }
        }
        if ( dataPerLine != 0 ) {
            System.out.println();
        }
    }

    // added for project, not part of assignment
    public void assemble( File f ) throws IOException, SyntaxError {
        byte[] buf = new byte[(int) f.length()];
        FileInputStream fis = new FileInputStream( f );
        fis.read( buf );
        fis.close();
        assemble( new String( buf ) );
    }

    /**
     * Assemble the file, f.
     */
    public void assemble( String str) throws SyntaxError {
        int currentPC = 0;
        int opcode = 0;
        String[] args = new String[2];

        Scanner sc = new Scanner( str );
        while( sc.hasNextLine() ) {
            Scanner parse = new Scanner(stripComments(sc.nextLine()) );
            if ( !parse.hasNext() ) continue; // skip empty line
            String cmd = parse.next();
            if ( cmd.equals(".org") ) {
                if ( !parse.hasNext() ) {
                    throw new SyntaxError(".org excepting integer");
                }
                currentPC = parseInteger( parse.next() );
            }
            else if ( cmd.equals(".dump") ) {
                parseTwoArgs( parse, args );
                int start = parseInteger( args[0] );
                int length = parseInteger( args[1] );
                printIM( start, length );
            }
            else if ( (opcode=lookupConstant(cmd)) != -1 ) {
                parseTwoArgs( parse, args );
                int reg = parseRegister( args[0] );
                int k = parseInteger( args[1] );
                im.set( currentPC, (opcode<<2) | reg );
                currentPC++;
                im.set( currentPC, (k >> 8) & 0xff );
                currentPC++;
                im.set( currentPC, (k >> 0) & 0xff );
                currentPC++;
            }
            else if ( (opcode=lookupTwoOp(cmd)) != -1) {
                parseTwoArgs( parse, args );
                int dst = parseRegister( args[0] );
                int src = parseRegister( args[1] );
                im.set( currentPC, 0x80 | (opcode<<4) | dst << 2 | src );
                currentPC++;
            }
            else if ( cmd.equals( "br" ) ) {
                if ( !parse.hasNext() ) {
                    throw new SyntaxError("br excepting integer");
                }
                int branch = parseInteger( parse.next() );
                im.set( currentPC, 0x40 | (branch & 0x3f) );
                currentPC++;
            }
            else if ( (opcode=lookupOneOp(cmd)) != -1) {
                if ( !parse.hasNext() ) {
                    throw new SyntaxError(cmd + " excepting register");
                }
                int ds = parseRegister( parse.next() );
                im.set( currentPC, 0x20 | (opcode<<2) | ds );
                currentPC++;
            }
            else if ( (opcode=lookupSkip(cmd)) != -1) {
                if ( !parse.hasNext() ) {
                    throw new SyntaxError(cmd + " excepting register");
                }
                int ds = parseRegister( parse.next() );
                im.set( currentPC, 0x30 | (opcode<<2) | ds );
                currentPC++;
            }
            else if ( cmd.equals( "ld" ) ) {
                parseTwoArgs( parse, args );
                int index = parseRegister( args[0] );
                if ( index != 0 && index != 1 ) {
                    throw new SyntaxError("index register must be r0 or r1");
                }
                int ds = parseRegister( args[1] );
                im.set( currentPC, 0x10 | (0<<3) | (index<<2) | ds );
                currentPC++;
            }
            else if ( cmd.equals( "st" ) ) {
                parseTwoArgs( parse, args );
                int index = parseRegister( args[0] );
                if ( index != 0 && index != 1 ) {
                    throw new SyntaxError("index register must be r0 or r1");
                }
                int ds = parseRegister( args[1] );
                im.set( currentPC, 0x10 | (1<<3) | (index<<2) | ds );
                currentPC++;
            }
            else if ( cmd.equals( "jl" ) ) {
                if ( !parse.hasNext() ) {
                    throw new SyntaxError("jl excepting register");
                }
                int link = parseRegister( parse.next() );
                im.set( currentPC, 0x0c | link );
                currentPC++;
            }
            else {
                throw new SyntaxError("unknown instruction: " + cmd );
            }
        }
        sc.close();
    }

    /**
     * main - accepts the name of the file to assemble on the command line.
     */
    public static void main( String[] args ) {
        if ( args.length != 1 ) {
             System.out.println("usage: java Assemble816 file");
             return;
        }
        try {
            InstructionMemory im = new InstructionMemory();
            Assemble816 asm = new Assemble816( im );
            asm.assemble( new File( args[0] ) );
        }
        catch( IOException ex ) {
            System.out.println("io: " + ex.getMessage() );
        }
        catch( SyntaxError ex ) {
            System.out.println("syntax: " + ex.getMessage() );
        }
    }
}
4

3 回答 3

2

Assemble816只有一个构造函数,它需要一个参数InstructionMemory

assembleButton.addActionListener( new ActionListener() {
    public void actionPerformed( ActionEvent evt ) {
        System.out.println( editArea.getText() );
        try{
            InstructionMemory im = new InstructionMemory();
            Assemble816 asm = new Assemble816(im);
            asm.assemble(editArea.getText());
        } catch(Exception ex) {
            // I'd probably dump the stack trace here as well,
            // seen as you're not logging it anywhere
            JOptionPane.showMessageDialog(null, ex.getMessage());
        }

    }
});
于 2013-02-21T23:01:46.580 回答
0

这是在 10,00 英尺处,但不是 try/catch 阻塞语句吗?我认为最好的方法是创建一个线程 Runnable 并在非阻塞线程上运行 Assemble816。否则,ASMEditor 将在 Assemble816 运行时挂起。

此外,仅初始化程序不会自动触发 main ..因此线程可能有助于从超级编辑器类中调用您的 assemble 方法..

线程

于 2013-02-21T21:31:41.570 回答
0

您制作了两个 Assemble816 实例,只需要一个。

在 main() 中,您创建了一个带有参数的实例。

您必须将此实例作为参数传递给您的类 ASMEditor,修改构造函数。

public class ASMEditor extends JPanel {
    private JTextArea editArea;
    private JButton assembleButton;
    private JButton clearButton;
    private Assemble816 asm;
    private InstructionMemory iMem;

    public ASMEditor( Assemble816 a ) {
       super( new BorderLayout() );
       asm = a;
       ...

不需要实例化两次,所以事件驱动的代码变成:

assembleButton.addActionListener( new ActionListener() {
   public void actionPerformed( ActionEvent evt ) {
      try{
         asm.assemble(editArea.getText());
         ...
于 2013-02-21T21:39:02.607 回答