⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 assembler.java

📁 熟悉非常简单CPU模拟器 1、将所给模拟器的源程序编译成执行程序。 2、运行并观察非常简单CPU模拟器
💻 JAVA
字号:
import java.util.*;
import java.io.*;

public
class Assembler
{

   public static AssemblyResults assemble( String source, int location, Box box, CPU CPUBox, Memory memory )
   {
      AssemblySourceProgram code = new AssemblySourceProgram( source );
      int memoryCounter = location;
      Vector assemblyErrorVector = new Vector();
      int errorCount = 0;

      // Loop to check for valid code
      for ( int lineIndex = 1; lineIndex <= code.sourceLineLength();
         lineIndex++ )
      {
         box.showStatus( "Assembling . . . Checking line " + lineIndex );

         AssemblySourceLine line = code.getSourceLineByLineNumber(
            lineIndex );

         if ( ( line != null ) && ( line.sourceTokenLength() > 0 ) )
         {
            String[] tokens = line.getSourceTokenStringArray();
            
            int offset=0;
            if(IsLabel(tokens[0])){
                    offset=1;
            }

            if ( ORG.equalsIgnoreCase( tokens[ 0 + offset ] ) )
            {

               if ( tokens.length - offset < 2 )
               {
                  errorCount++;
                  assemblyErrorVector.addElement( new AssemblyError( 
                     lineIndex, "ORG expects one operand" ) );
               }
               else if ( tokens.length - offset > 2 )
               {
                  errorCount++;
                  assemblyErrorVector.addElement( new AssemblyError( 
                     lineIndex, "ORG does not accept more than one " +
                     "operand" ) );
               }
               else if ( ! AssemblyInstruction.isAddress( tokens[ 1 + offset ] ))
               {
                  errorCount++;
                  assemblyErrorVector.addElement( new AssemblyError( 
                     lineIndex, "Specified address is invalid" ) );
               }

            }
            else if ( DB.equalsIgnoreCase( tokens[ 0 + offset ] ) )
            {

               if ( tokens.length - offset < 2 )
               {
                  errorCount++;
                  assemblyErrorVector.addElement( new AssemblyError( 
                     lineIndex, "DB expects one operand" ) );
               }
               else if ( tokens.length - offset > 2 )
               {
                  errorCount++;
                  assemblyErrorVector.addElement( new AssemblyError( 
                     lineIndex, "DB does not accept more than one " +
                     "operand" ) );
               }
               else if ( AssemblyInstruction.toByteShort( tokens[ 1 + offset ] ) ==
                  -1 )
               {
                  errorCount++;
                  assemblyErrorVector.addElement( new AssemblyError( 
                     lineIndex, "Specified byte constant is invalid" ) );
               }

            }
            else if ( DW.equalsIgnoreCase( tokens[ 0 + offset ] ) )
            {

               if ( tokens.length - offset < 2 )
               {
                  errorCount++;
                  assemblyErrorVector.addElement( new AssemblyError( 
                     lineIndex, "DW expects one operand" ) );
               }
               else if ( tokens.length - offset > 2 )
               {
                  errorCount++;
                  assemblyErrorVector.addElement( new AssemblyError( 
                     lineIndex, "DW does not accept more than one " +
                     "operand" ) );
               }
               else if ( AssemblyInstruction.toWordInteger( tokens[ 1 + offset ] )
                  == -1 )
               {
                  errorCount++;
                  assemblyErrorVector.addElement( new AssemblyError( 
                     lineIndex, "Specified word constant is invalid" ) );
               }

            }
            else if ( AssemblyInstruction.isMnemonic( tokens[ 0 + offset ] ) )
            {

               if ( AssemblyInstruction.expectsOperands( tokens[ 0 + offset ] ) ==
                  1 )
               {

                  if ( tokens.length - offset < 2 )
                  {
                     errorCount++;
                     assemblyErrorVector.addElement( new AssemblyError( 
                        lineIndex, tokens[ 0 + offset ].toUpperCase() + " expects "
                        + "one operand" ) );
                  }
                  else if ( tokens.length - offset > 2 )
                  {
                     errorCount++;
                     assemblyErrorVector.addElement( new AssemblyError( 
                        lineIndex, tokens[ 0 + offset ].toUpperCase() + " does not "
                        + "accept more than one operand" ) );
                  }
                  else if ( !AssemblyInstruction.isAddress( tokens[
                     1 + offset ]) && (!LabelExists(tokens[ 1 + offset ],code)) )
                  {
                     errorCount++;
                     assemblyErrorVector.addElement( new AssemblyError( 
                        lineIndex, "Specified address is invalid" ) );
                  }

               }
               else
               {

                  if ( tokens.length - offset > 1 )
                  {
                     errorCount++;
                     assemblyErrorVector.addElement( new AssemblyError( 
                        lineIndex, tokens[ 0 + offset ].toUpperCase() + " does not "
                        + "accept any operands" ) );
                  }

               }

            }
            else
            {
               errorCount++;
               assemblyErrorVector.addElement( new AssemblyError( 
                  lineIndex, "Specified mnemonic is invalid" ) );
            }

         }

      }

      if ( errorCount != 0 )
      {
         box.showStatus( "Assembling . . . " + errorCount + " error(s) " +
            "encountered" );
      }
      else
      {
         // If no errors exist, assemble program

         // Places valid code in memory and temporary variables
         for ( int lineIndex = 1; lineIndex <= code.sourceLineLength();
            lineIndex++ )
         {
            box.showStatus( "Assembling . . . Assembling line " +
               lineIndex );
//            System.out.println( "DEBUG ==> Assembling line " + lineIndex );

            AssemblySourceLine line = code.getSourceLineByLineNumber(
               lineIndex );

            if ( ( line != null ) && ( line.sourceTokenLength() > 0 ) )
            {
               String[] tokens = line.getSourceTokenStringArray();
               
               int offset=0;
                if(IsLabel(tokens[0])){
                    offset=1;
                }

               if ( ORG.equalsIgnoreCase( tokens[ 0 + offset ] ) )
               {
                  memoryCounter = AssemblyInstruction.toAddressInteger(
                     tokens[ 1 ] );
               }
               else if ( DB.equalsIgnoreCase( tokens[ 0 + offset ] ) )
               {
                  short byteShort = AssemblyInstruction.toByteShort(
                     tokens[ 1 ] );

                  memory.write( memoryCounter, byteShort );

//                  String[] binaryNybble = toBinaryNybble( byteShort );
//                  memory[ memoryCounter ] = binaryNybble;

                  memoryCounter++;
               }
               else if ( DW.equalsIgnoreCase( tokens[ 0 + offset ] ) )
               {
                  short[] wordCode = AssemblyInstruction.toWordCode(
                     AssemblyInstruction.toWordInteger( tokens[ 1 + offset ] ) );

                  memory.write( memoryCounter, wordCode[ 0 ] );
                  memory.write( memoryCounter + 1, wordCode[ 1 ] );

//                  String[] binaryNybble = toBinaryNybble( wordCode[ 0 ] );
//                  memory[ memoryCounter ] = binaryNybble;

//                  binaryNybble = toBinaryNybble( wordCode[ 1 ] );
//                  memory[ memoryCounter + 1 ] = binaryNybble;

                  memoryCounter += 2;
               }
               else
               {
                  code.setSourceLineAddressByLineNumber( memoryCounter,
                     lineIndex );
//                  opcode[ memoryCounter ] = tokens[ 0 ].toUpperCase();

//                  String[] binaryNybble = toBinaryNybble(
//                     AssemblyInstruction.toMnemonicCode( tokens[ 0 ] ) );

                  

//                  memory[ memoryCounter ] = binaryNybble;

                  if ( AssemblyInstruction.expectsOperands( tokens[
                     0 + offset ] ) == 1 )
                  {
                     short[] addressCode;
                     
                     if(LabelExists(tokens[ 1 + offset ],code)){
                          addressCode = AssemblyInstruction.
                        toAddressCode(GetLabelAddress(tokens[ 1 + offset ],code));
                        }else{
                     addressCode = AssemblyInstruction.
                        toAddressCode( AssemblyInstruction.
                        toAddressInteger( tokens[ 1 + offset ] ) );
                        }

//                     String[] binaryNybbleAddress = toBinaryNybble(
//                        addressCode[ 0 ] );
                        short instr=AssemblyInstruction.toMnemonicCode( tokens[ 0 + offset ] );
                        if (instr != 0xff){
                                instr = (short) (instr << 6);
                        }

                
                     memory.write( memoryCounter,  (short) (instr | addressCode[ 0 ]) );

//                     memory[ memoryCounter + 1 ] = binaryNybbleAddress;

//                     binaryNybbleAddress = toBinaryNybble( addressCode[
//                        1 ] );

                     //memory.write( memoryCounter + 2, addressCode[ 1 ] );

//                     memory[ memoryCounter + 2 ] = binaryNybbleAddress;

                     //memoryCounter += 2;
                  }
                  else{
                          short instr=AssemblyInstruction.toMnemonicCode( tokens[ 0 + offset ] );
                        if (instr != 0xff){
                                instr = (short) (instr << 6);
                        }
                          memory.write( memoryCounter, instr );
                  }

                  memoryCounter++;
               }

            }

         }

      }
        box.showStatus( " ");                
      CPUBox.getMemory().repaint();

//      System.out.println( "DEBUG ==> Copying errors into array..." );

      AssemblyError[] assemblyErrors = new AssemblyError[
         assemblyErrorVector.size() ];

      assemblyErrorVector.copyInto( assemblyErrors );
      box.showStatus( "Assembly Complete");
      return ( new AssemblyResults( assemblyErrors, code ) );
   }

   
   //Needed in order to find a label
   private static boolean IsLabel(String token){
           if(token.indexOf(':')!=-1 && token.indexOf(':')==token.length()-1 && token.length()>1){
                   return true;
           }else{
                   return false;
           }
   }
   private static boolean LabelExists(String label,AssemblySourceProgram code){
      for ( int lineIndex = 1; lineIndex <= code.sourceLineLength(); lineIndex++ )
        {
            AssemblySourceLine line = code.getSourceLineByLineNumber(lineIndex);
            if(line != null && line.GetLabel().toLowerCase().equals(label.toLowerCase()+":")){
                    return true;
            }
        }
        return false;
   }
   private static int GetLabelAddress(String label,AssemblySourceProgram code){
           if(LabelExists(label,code)){
                   int memoryCounter=0;
      for ( int lineIndex = 1; lineIndex <= code.sourceLineLength();
            lineIndex++ )
         {

            AssemblySourceLine line = code.getSourceLineByLineNumber(
               lineIndex );
               
               if(line != null && line.GetLabel().toLowerCase().equals(label.toLowerCase()+":")){
                    return memoryCounter;//line.getAddress();
            }

            if ( ( line != null ) && ( line.sourceTokenLength() > 0 ) )
            {
               String[] tokens = line.getSourceTokenStringArray();
               
               int offset=0;
                if(IsLabel(tokens[0])){
                    offset=1;
                }

               if ( ORG.equalsIgnoreCase( tokens[ 0 + offset ] ) )
               {
                  memoryCounter = AssemblyInstruction.toAddressInteger(
                     tokens[ 1 ] );
               }
               else if ( DB.equalsIgnoreCase( tokens[ 0 + offset ] ) )
               {

                  memoryCounter++;
               }
               else if ( DW.equalsIgnoreCase( tokens[ 0 + offset ] ) )
               {

                  memoryCounter += 2;
               }
               else
               {

                  memoryCounter++;
               }

            }

         }
         }
        return -1;
   }
   
   
   public static String[] toBinaryNybble( short byteShort )
   {
      String upperNybble = Integer.toString( byteShort / 0x10, 2 );
      String lowerNybble = Integer.toString( byteShort % 0x10, 2 );

      while ( upperNybble.length() < 4 )
      {
         upperNybble = "0" + upperNybble;
      }

      while ( lowerNybble.length() < 4 )
      {
         lowerNybble = "0" + lowerNybble;
      }

      String[] binaryNybble = { upperNybble, lowerNybble };

      return ( binaryNybble );
   }

   // String constants for each assembly instruction
//   public static final String NOP = new String( "NOP" );
//   public static final String LDAC = new String( "LDAC" );
//   public static final String STAC = new String( "STAC" );
//   public static final String MVAC = new String( "MVAC" );
//   public static final String MOVR = new String( "MOVR" );
   public static final String JMP = new String( "JMP" );
//   public static final String JMPZ = new String( "JMPZ" );
//   public static final String JPNZ = new String( "JPNZ" );
   public static final String ADD = new String( "ADD" );
//   public static final String SUB = new String( "SUB" );
   public static final String INC = new String( "INC" );
//   public static final String CLAC = new String( "CLAC" );
   public static final String AND = new String( "AND" );
//   public static final String OR = new String( "OR" );
//   public static final String XOR = new String( "XOR" );
//   public static final String NOT = new String( "NOT" );
   public static final String END = new String( "END" );

   public static final String ORG = new String( "ORG" );
   public static final String DB = new String( "DB" );
   public static final String DW = new String( "DW" );
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -