- •1 Постановка задачи
- •2 Форматы команд
- •3 Описание метода решения
- •4 Описание структур данных
- •5 Описание алгоритма
- •6 Описание программы
- •6.1 Назначение программы
- •6.2 Требования к программному и техническому обеспечению Программа разработана на языке Java.
- •6.6. Загрузка программы
- •7 Тестирование программы
- •Заключение
- •Литература
6.6. Загрузка программы
Запуск программы производится через запуск метода main класса ASM в eclipse, BlueJ или подобных редакторах, или напрямую используя JVM.
Исходные файлы – input.txt (код на ассемблере), out.txt (объектный код), list.txt (листинг).
6.7 Сообщения, выдаваемые программой
Программа может выдавать следуюшие ошибки:
- Неверное кол-во полей;
- Метка уже объявлена;
- Переменная уже объявлена;
- Неверная разрядность операндов;
- Неверный тип операнда;
- Неизвестная директива;
- Неверные данные;
- Неверная метка;
- Неверная структура.
7 Тестирование программы
Тест1:
A SEGMENT
ORG 100H
M: MOV AX, BX
A ENDS
END M
Результат:
H A 2
T 0100 02 8BC3
E 0100
Листинг:
3 8BC3 M: MOV AX, BX
Тест2:
A SEGMENT
ORG 100H
M: SUB AX, [BX+SI+B+12H]
B DW 1234H
A ENDS
END M
Результат:
HA6
T0100 04 2B801600
T0104 02 3412
E 0100
Листинг:
3 2B801600 M: SUB AX, [BX+SI+B+12H]
4 3412 B DW 1234H
Тест3:
A SEGMENT
M: JA M
A ENDS
END M
Результат:
HA2
T0000 02 7700
E0000
Листинг:
2 7700 M: JA M
Заключение
В ходе выполнения курсового проекта был разработан транслятор для подмножества команд языка Ассемблер IBM PC. Программа разработана в интегрированной среде программирования (IDE) eclipses на языке Java.
Сформулированы форматы команд ассемблер–программы, согласно правилам синтаксиса языка Ассемблер процессора INTEL 8086/88, а также формат представления результатов: файла листинга и объектного кода. Был изучен двухпросмотровый алгоритм трансляции. Определены основные подзадачи и методы их решения, выбраны структуры данных и описаны основные блоки структурной схемы.
Программа протестирована на тестовых примерах, результаты тестов верные, из чего можно сделать вывод о правильности работы программы.
Литература
1. Нортон П. Язык ассемблера для IBM PC. - M.:Мир, 1993;
2. Абель П. Язык ассемблера для IBM PC и программирования.-М.:Высш.шк., 1992;
3. Методические указания к выполнению курсовой работы по дисциплине "Системное программирование " для студентов специальности 7.091501
Приложение A
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class ASM {
public static void main( String[] args ) {
SourceLine SL = new SourceLine();
BufferedReader input;
try {
input = new BufferedReader( new FileReader("input.txt") );
String line;
while( ( line = input.readLine()) != null ){
SL.split( line.toUpperCase() );
if( SL.hasError ) break;
SL.start();
if( SL.hasError ) break;
if( line.substring( 0, 4).equals( "END" ) ) break;
}
if ( !SL.hasError ) {
SL.createH();
SL.SC.startConvert();
SL.SC.createE();
}
SL.SC.close();
}
catch ( FileNotFoundException e ) {
e.printStackTrace();
}
catch ( IOException e ) {
e.printStackTrace();
}
}
}
import java.util.Arrays;
import java.util.StringTokenizer;
import java.util.regex.Pattern;
public class SourceLine {
String[] fields; // поля
private String label = ""; // метка
private String mnem = ""; // КОП
private String directive = ""; // директива
private String link = ""; // ссылка
private String var = ""; // переменная
private String[] data; // данные
private boolean isCommand;
private int address = 0; // СЧАК
private String opType = ""; // тип операндов
private int wBitR1 = 0;
private int wBitR2 = 0;
private int wBitN = 0;
boolean hasError = false;
SourceCode SC = new SourceCode( this );
private int codeLength = 0; // длина кодированной строки
private int memOff = 0; // смещение в адресе
private boolean hasSegment = false;
private int SCLength = 0; // длинна всего кода
private String segmentName = "";
private int offset = 0;
String line = "";
void split( String line ) { // разделения на поля
this.line = line;
line.substring( 0, line.indexOf( ";" ) < 0 ? line.length() : line.indexOf( ";" ) );
StringTokenizer tokens = new StringTokenizer( line, " \t\n\r,");
if ( tokens.countTokens() < 2 ) {
error( 0 );
return;
}
fields = new String[ tokens.countTokens() ];
int index = 0;
while ( tokens.hasMoreElements() ) fields[ index++ ] = tokens.nextToken();
}
void error( int i ) {
System.out.println( Tables.errors[ i ] );
SC.List( i, line );
hasError = true;
}
void reset() {
label = "";
var = "";
mnem = "";
directive = "";
link = "";
opType = "";
isCommand = false;
wBitR1 = wBitR2 = wBitN = codeLength = memOff = 0;
}
void start() {
reset();
int i = 0;
if( fields[ 0 ].equals( "END" ) ) {
if( !SC.hasInTSI( fields[ 1 ] ) ) error( 7 );
String ttemp = Integer.toHexString( SC.searchTSI( fields[ 1 ]) + offset );
while( ttemp.length() < 4 ) ttemp = "0" + ttemp;
SC.start = ttemp;
}
else if ( checkLabel( fields[ 0 ] ) ) { // первый токен - метка
label = fields[ 0 ].toUpperCase();
if( SC.hasInTSI( label ) ) error( 1 );
i = 1;
}
else if ( checkVar( fields[ 0 ] ) ) { // первый токен - переменная
var = fields[ 0 ].toUpperCase();
if( SC.hasInTSI( var ) && !fields[ 1 ].equals( "ENDS") ) error( 2 );
i = 1;
}
if( checkMnem( fields[ 0 + i ] ) ) { // мнемоника
isCommand = true;
mnem = fields[ 0 + i ].toUpperCase();
if( checkReg( fields[ 1 + i ] ) ) { // оп1 регистр
wBitR1 = getWBitR( fields[ 1 + i ] );
if( ( fields[ 2 + i ].equals( "OFFSET" ) ) && ( fields.length == 4 + i ) ) { // OFFSET
opType = wBitR1 == 0 ? "RN8" : "RN16";
}
else if( ( fields[ 2 + i ].equals( "1" ) ) && ( fields.length == 3 + i ) ) { // оп2 "1"
opType = wBitR1 == 0 ? "R8" : "R16";
}
else if( checkReg( fields[ 2 + i ] ) && fields.length == 3 + i ) { // оп2 регистр
wBitR2 = getWBitR( fields[ 2 + i ] );
if( wBitR1 >= wBitR2 ) {
opType = wBitR1 == 0 ? "RR8" : "RR16";
}
else error( 3 );
}
else if( checkMem( fields[ 2 + i ] ) ) {
if( fields.length == 3 + i ) { // оп2 адрес
opType = wBitR1 == 0 ? "RO8" : "RO16";
}
}
else if( checkData( fields[ 2 + i ] ) > 0 && fields.length == 3 + i ) { // оп2 НО
wBitN = getWBitN( fields[ 2 + i ] );
if( wBitR1 >= wBitN ) {
opType = wBitR1 == 0 ? "RN8" : "RN16";
}
else error( 3 );
}
else error( 4 );
}
else if( checkMem( fields[ 1 + i ] ) ) { // оп1 адрес
if( checkReg( fields[ 2 + i ] ) ) { // оп2 регистр
if( fields.length == 3 + i ) {
opType = wBitR2 == 0 ? "OR8" : "OR16";
}
else error( 0 );
}
else error( 4 );
}
else if( checkLink( fields[ 1 + i ] ) ) { // оп1 ссылка
if( fields.length == 2 + i ) {
link = fields[ 1 + i ].toUpperCase();
opType = "L";
}
else error( 0 );
}
else if( checkData( fields[ 1 + i ] ) > 0 ) { // оп1 НО
if ( fields.length == 2 + i ) opType = "N";
else error( 0 );
}
else error( 4 );
}
/////////////////
else if ( Tables.searchTD( fields[ 0 + i ] ) >= 0 ) { // директива
if ( fields[ 0 + i ].toUpperCase().equals( "DB" ) || fields[ 0 + i ].toUpperCase().equals( "DW" ) ) { // проверить размер
data = new String[ fields.length - i - 1 ];
int k = 0;
boolean hasError = false;
for ( int j = 1 + i; j < fields.length; j++ ) {
if( !( ( checkData( fields[ j ] ) == 2 && fields[ 0 + i ].toUpperCase().equals( "DW" ) ) || ( checkData( fields[ j ] ) == 1 && fields[ 0 + i ].toUpperCase().equals( "DB" ) ) ) ) {
hasError = true;
break;
}
data[ k++ ] = fields[ j ];
}
// if( hasError ) error();
directive = fields[ 0 + i ].toUpperCase();
}
else if( i > 0 ) {
if( fields[ 1 ].toUpperCase().equals( "SEGMENT" ) || fields[ 1 ].toUpperCase().equals( "ENDS" ) ) {
if( fields.length > 2 ) error( 0 );
else directive = fields[ 1 ].toUpperCase();
}
else error( 5 );
}
else if( fields[ 0 ].equals( "END" ) ) {
if( ( checkLink( fields[ 1 ] ) ) ) {
if( fields.length == 2 ) directive = "END";
else error( 0 );
}
else error( 7 );
}
else if( fields[ 0 ].equals( "ORG" ) ) {
if( ( checkData( fields[ 1 ] ) ) > 0 ) {
if( fields.length == 2 ) directive = "ORG";
else error( 0 );
}
else error( 6 );
}
}
else error( 5 );
if( hasError ) return;
if( !var.equals( "" ) || !label.equals( "" ) ) {
SC.addToTSI( var.equals( "" ) ? label.substring( 0 , label.length() - 1 ) : var, address );
}
if( !hasSegment ) {
if( directive.equals( "SEGMENT" ) ) {
hasSegment = true;
segmentName = var;
addToCode();
}
else error( 8 );
}
else {
calculateSize();
address += this.codeLength;
SCLength += this.codeLength;
addToCode();
}
}
private void calculateSize() {
if( isCommand ) codeLength = Integer.parseInt( Tables.TFK[ Tables.searchTFK( mnem, opType ) ][ 6 ] ) + memOff;
else if ( directive.equals( "DB" ) || directive.equals( "DW" )) {
codeLength = directive.equals( "DB" ) ? 1 : 2;
}
}
private void addToCode() {
if ( hasError ) return;
if ( isCommand ) {
String[] temp = new String[ fields.length + 1 ];
temp = Arrays.copyOf( fields, fields.length + 1 );
temp[ fields.length ] = opType;
SC.addCodeLine( temp, isCommand, !( label.equals( "" ) && var.equals( "" ) ), codeLength );
}
else {
if ( directive.equals( "DB" )||directive.equals( "DW" )) { // директива + 2 пропуска + данные
String[] temp;
int i = 0;
if( !var.equals( "" ) ){
i++;
temp = new String[ fields.length + 1 + i ];
temp[ 0 ] = fields[ 0 ];
}
else temp = new String[ fields.length + 2 ];
temp[ 0 + i ] = fields[ 0 + i ];
temp[ 1 + i ] = "";
temp[ 2 + i ] = "";
for( int j = 1 + i; j < fields.length; j++ ) {
temp[ 2 + j ] = fields[ j ];
}
SC.addCodeLine( temp, isCommand, !( label.equals( "" ) && var.equals( "" ) ), codeLength );
}
else if ( directive.equals( "SEGMENT" ) || directive.equals( "ENDS" ) ) {
if( var.equals( "" ) ) error( 0 );
else if( directive.equals( "ENDS" ) && !var.equals( this.segmentName ) ) error( 8 );
else SC.addCodeLine( fields, isCommand, !( label.equals( "" ) && var.equals( "" ) ), codeLength );
}
else if ( directive.equals( "END" ) ) {
if( !( label.equals( "" ) && var.equals( "" ) ) ) error( 0 );
}
else if ( directive.equals( "ORG" ) ) {
offset = Integer.parseInt( fields[ 1 ].substring(0, fields[ 1 ].length() - 1 ), 16 );
String[] temp = new String[ 3 ];
temp[ 0 ] = fields[ 0 ];
temp[ 1 ] = fields[ 1 ];
temp[ 2 ] = "N";
SC.addCodeLine( temp, false, false, codeLength );
}
}
}
private boolean checkReg( String temp ) {
return Tables.searchTR( temp ) >= 0;
}
private boolean checkMnem( String temp ) {
return Tables.searchTFK( temp ) >= 0;
}
private boolean checkLink( String temp ) { // ссылка
return Pattern.compile( "[A-Z0-9]" ).matcher( temp.toUpperCase() ).matches();
}
private boolean checkVar( String temp ) { // переменная, переделать
return Pattern.compile( "[A-Z0-9]{1,2}" ).matcher( temp.toUpperCase() ).matches();
}
private boolean checkLabel( String temp ) { // метку тоже
return Pattern.compile( "[A-Z0-9]{1,2}:" ).matcher( temp.toUpperCase() ).matches();
}
private boolean checkMem( String temp ) { // адрес
int i = 0;
String str1 = temp.replace( "", "" );
while ( str1.contains( "+" ) ) {
str1 = str1.substring( str1.indexOf( '+' ) + 1 ); // проверить
i++;
}
String str = temp.replace( " ", "" ).replace( "[", "" ).replace( "]", "" );
if( ( temp.equals( "1" ) ) || !temp.contains( "[" ) || ( Tables.searchTA( str.substring( 0, 5 ) ) < 0 ) ) return false;
if( str.length() > 5 ) {
StringTokenizer tokens = new StringTokenizer( str.substring( 5 ), "+" );
while ( tokens.hasMoreElements() ) {
String t = tokens.nextToken();
if( t.equals( "OFFSET" ) ) continue;
if( ( checkData( t ) < 0 ) && !checkVar( t ) ) return false; // проверить checkdata = 1
}
memOff = 2;
}
return true;
}
private int getWBitR( String temp ) {
int index = Tables.searchTR( temp.toUpperCase() );
return index < 0 ?-1:Integer.parseInt( Tables.TR[ index ][2] );
}
private int getWBitN( String temp ) {
if( temp.toUpperCase().charAt( temp.length() - 1 ) == 'H' ){
if( temp.length() <= 3 ) return 0;
else return 1;
}
else {
if( Integer.parseInt( temp ) < 256 ) return 0;
else return 1;
}
}
private int checkData( String temp ) { // данные, если 1 - DB
if( temp.length() == 0 ) return 0;
if( ( Pattern.compile( "[0-9A-F]{1,4}H" ).matcher( temp ).matches() && ( temp.length() <= 5 ) ) || ( Pattern.compile( "[0-9]{1,5}" ).matcher( temp ).matches() && ( Integer.parseInt( temp ) <= 65535 ) ) ) {
if( temp.charAt( temp.length() - 1 ) == 'H' ) return temp.length() > 3 ? 2 : 1;
else return Integer.parseInt( temp ) > 255 ? 2 : 1;
}
return -1;
}
void createH() {
SC.outFile.println("H " + this.segmentName+ " " +this.address );
}
}
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.regex.Pattern;
public class SourceCode {
private int address = 0; // СЧАК
private int newAddress = 0;
boolean hasError = false;
int lineNumber = 0;
String line = "";
String start = "";
String command = "";
SourceLine SL = null;
PrintWriter listFile;
PrintWriter outFile;
LinkedList< Map<String, String[] > > code = new LinkedList< Map<String, String[] > >();
// label, opcode, directive, OP1, OP2, data, optype, codeLength
LinkedList< Map< String, Integer> > TSI = new LinkedList< Map< String, Integer > >();
//label\var, value\adress,
SourceCode( SourceLine sourceLine ) {
SL = sourceLine;
try {
listFile = new PrintWriter( "list.txt" );
outFile = new PrintWriter( "command.txt" );
}
catch ( FileNotFoundException e ) {
e.printStackTrace();
}
}
boolean hasInTSI( String temp ) {
for ( Map<String, Integer> element : TSI ) if ( element.containsKey( temp ) ) return true;
return false;
}
void addToTSI( String temp, int value ) {
Map< String, Integer > temp1 = new HashMap< String, Integer >();
temp1.put( temp, Integer.valueOf( value ) );
TSI.add( temp1 );
}
Integer searchTSI( String temp ) {
for ( Map<String, Integer> element : TSI ) {
if ( element.containsKey( temp ) ) return element.get( temp );
}
return null;
}
void addCodeLine( String[] temp, boolean isCommand, boolean hasLabelOrLink, int codeLength ) { // добавляет текущую строку кода в список
Map<String, String[]> temp1 = new HashMap<String, String[] >();
if ( isCommand ) {
int i = 0;
if ( hasLabelOrLink ) {
temp1.put( "Label", new String[]{ temp[ 0 ] } );
i++;
}
temp1.put( "opCode", new String[]{ temp[ 0 + i ] } );
temp1.put( "OP1", new String[]{ temp[ 1 + i ] } );
// для INT
if( temp.length > 3 + i ) {
if( temp[ 2 + i ].equals( "OFFSET" ) ) {
temp1.put( "OFFSET", new String[]{ "" } );
temp1.put("OP2",new String[]{temp[3 + i] } );
temp1.put("opType", ew String[]{temp[4+i] } );
}
else{
temp1.put("OP2",new String[]{temp[2 + i]} );
temp1.put(“opType", new String[]{temp[3+i]} );
}
}
else temp1.put( "opType", new String[]{ temp[ 2 + i ] } );
temp1.put( "codeLength", new String[]{ Integer.valueOf( codeLength ).toString() } );
}
else {
int i = 0;
if ( hasLabelOrLink ) {
temp1.put( "Label", new String[]{ temp[ 0 ] } );
i++;
}
if ( temp[ 0 + i ].equals( "ORG") ) {
temp1.put( "directive", new String[]{ temp[ 0 + i ] } );
temp1.put( "OP1", new String[]{ temp[ 1 + i ] } );
}
else{
temp1.put( "directive", new String[]{ temp[ 0 + i ] } );
temp1.put( "codeLength", new String[]{ String.valueOf( codeLength ) } ); // проверить
if( temp.length > 2 ) {
temp1.put( "OP1", new String[]{ temp[ 1 + i ] } );
temp1.put( "OP2", new String[]{ temp[ 2 + i ] } );
String[] tempA = new String[ temp.length - 3 - i ];
int s = 0;
for ( int j = 3 + i; j < temp.length; j++ ) {
tempA[ s++ ] = temp[ j ];
}
temp1.put( "data", tempA ); //
}
}
}
temp1.put( "line", new String[]{ this.SL.line } );
code.addLast( temp1 );
}
void startConvert() {
for ( Map<String, String[] > line : code ) {
this.line = "";
this.line = line.get( "line" )[ 0 ];
lineNumber++;
String codeLine = "";
// команда
if ( line.containsKey( "opCode" ) ) {
String codeOpCode = ""; // код мнемоники
String Reg1 = "";
String Reg2 = "";
String Mod = "";
String AdrType = ""; // r/m
String Disp = "";
String Data = "";
String[] temp = Tables.TFK[ Tables.searchTFK( line.get( "opCode" )[ 0 ], line.get( "opType" )[ 0 ] ) ];
codeOpCode = temp[ 1 ] + temp[ 2 ];
if ( line.get( "opType" )[ 0 ].equals( "RR8" ) || line.get( "opType" )[ 0 ].equals( "RR16") ) {
Reg1 = Tables.TR[ Tables.searchTR( line.get( "OP1" )[ 0 ] ) ][ 1 ];
Reg2 = Tables.TR[ Tables.searchTR( line.get( "OP2" )[ 0 ] ) ][ 1 ];
}
else if ( line.get( "opType" )[ 0 ].equals( "RO8" ) || line.get( "opType" )[ 0 ].equals( "RO16") ) {
String[] tempOp = checkOp( line.get( "OP2" )[ 0 ] );
if( tempOp[ 0 ].equals( "-1" ) ) {
error( 6 );
return;
}
Reg1 = Tables.TR[ Tables.searchTR( line.get( "OP1" )[ 0 ] ) ][ 1 ];
Mod = tempOp.length > 1 ? "10" : "00";
AdrType = getAdrType( tempOp[ 0 ] );
Disp = tempOp[ 1 ] != null ? tempOp[ 1 ] : "";
}
else if ( line.get( "opType" )[ 0 ].equals( "OR8" ) || line.get( "opType" )[ 0 ].equals( "OR16") ) {
String[] tempOp = checkOp( line.get( "OP1" )[ 0 ] );
if( tempOp[ 0 ].equals( "-1" ) ) {
error( 6 );
return;
}
Reg1 = Tables.TR[ Tables.searchTR( line.get( "OP2" )[ 0 ] ) ][ 1 ];
Mod = tempOp.length > 1 ? "10" : "00";
AdrType = getAdrType( tempOp[ 0 ] );
Disp = tempOp[ 1 ] != null ? tempOp[ 1 ] : "";
}
else if ( line.get( "opType" )[ 0 ].equals( "RN8" ) || line.get( "opType" )[ 0 ].equals( "RN16" ) ) {// проверить размерность НО
Reg1 = Tables.TR[ Tables.searchTR( line.get( "OP1" )[ 0 ] ) ][ 1 ];
if( line.containsKey( "OFFSET" ) ) {
Data = getData( searchTSI( line.get( "OP2" )[ 0 ] ).toString(), false );
}
else{
Data = getData( line.get( "OP2" )[ 0 ], false );
}
}
else if ( line.get( "opType" )[ 0 ].equals( "R8" ) || line.get( "opType" )[ 0 ].equals( "R16") ) {
Reg1 = Tables.TR[ Tables.searchTR( line.get( "OP1" )[ 0 ] ) ][ 1 ];
}
else if ( line.get( "opType" )[ 0 ].equals( "N" ) ) {
String blabla = getData( line.get( "OP1" )[ 0 ], true );
blabla = blabla.substring( 0, blabla.length() - 1 );
blabla = Integer.toBinaryString( Integer.parseInt( blabla, 16 ) );
while( blabla.length() < 8 ) blabla = "0" + blabla;
Data = blabla;
}
else if ( line.get( "opType" )[ 0 ].equals( "L" ) ) {
String blabla = getData( searchTSI( line.get( "OP1" )[ 0 ] ).toString(), true );
blabla = blabla.substring( 0, blabla.length() - 1 );
blabla = Integer.toBinaryString( Integer.parseInt( blabla, 16 ) );
while( blabla.length() < 8 ) blabla = "0" + blabla;
Disp = blabla;
}
String pattern1 = Tables.TFK[ Tables.searchTFK( line.get( "opCode" )[ 0 ], line.get( "opType" )[ 0 ] )][ 3 ];
pattern1 = pattern1.replace( "Reg1", Reg1 );
pattern1 = pattern1.replace( "Reg2", Reg2 );
pattern1 = pattern1.replace( "Mod", Mod );
pattern1 = pattern1.replace( "AdrType", AdrType );
pattern1 = pattern1.replace( "Data", Data );
pattern1 = pattern1.replace( "Disp", Disp );
String pattern2 = Tables.TFK[ Tables.searchTFK( line.get( "opCode" )[ 0 ], line.get( "opType" )[ 0 ] )][ 4 ];
pattern2 = pattern2.replace( "Disp", Disp );
pattern2 = pattern2.replace( "Data", Data );
codeLine = Integer.toHexString( Integer.parseInt( codeOpCode + pattern1, 2 ) ) + pattern2.substring( 0, pattern2.length() );
newAddress = Integer.parseInt( line.get( "codeLength" )[ 0 ] );
this.createT( codeLine.toUpperCase() );
}
else if ( line.get( "directive" ) != null ) {
if ( line.get( "directive" )[ 0 ].equals( "DB" ) || line.get( "directive" )[ 0 ].equals( "DW" ) ) { // проверить длинну ""
String[] tempData = line.get( "data" );
for ( int in = 0; in < tempData.length; in++ ) {
String tC = getData( tempData[ in ], line.get( "directive" )[ 0 ].equals( "DB" ) );
codeLine = tC.substring( 0 , tC.indexOf( 'H' ) < 0 ? tC.length() : tC.length() - 1 );
newAddress = line.get( "directive" )[ 0 ].equals( "DB" ) ? 1 : 2;
createT( codeLine );
}
}
else if ( line.get( "directive" )[ 0 ].equals( "ORG" ) ) {
this.address = Integer.parseInt( line.get( "OP1" )[ 0 ].substring( 0, line.get( "OP1" )[ 0 ].length() - 1 ), 16 );
}
}
}
}
void error( int i ) {
System.out.println( Tables.errors[ i ] );
List( i, line );
hasError = true;
}
private String[] checkOp( String temp ) { // регистры, смешение( НО + var )
temp = temp.replace( " ", "" ).replace( "[", "" ).replace( "]", "" );
String adrType = temp.substring( 0, 5 );
if( temp.length() == 5 ) return new String[]{ adrType, null };
StringTokenizer tokens = new StringTokenizer( temp.substring( temp.indexOf( '+' ) + 1 ).substring( temp.indexOf( '+' ) + 1 ), "+" );
int summ = 0;
while ( tokens.hasMoreElements() ) {
String str = tokens.nextToken();
if( this.hasInTSI( str ) ) {
summ += Integer.parseInt(getData( searchTSI( str ).toString(), false ), 16 );
}
else if ( Pattern.compile( "[0-9A-F]{1,4}H" ).matcher( str ).matches() || Pattern.compile( "[0-9]{1,5}" ).matcher( str ).matches()) {
summ += Integer.parseInt(getData( str, false ), 16 );
}
else if( this.hasInTSI( str ) ) summ += searchTSI( str );
else return new String[]{ "-1", null };
}
String tempR = Integer.toHexString( summ );
while( tempR.length() < 4 ) tempR = "0" + tempR;
return new String[]{ adrType, tempR };
}
private String getData( String temp, boolean DB ) {
if( temp.contains("H") ){
if( DB ) {
if( temp.length() == 2 ) temp = "0" + temp;
}
else {
while( temp.length() < 5 ) temp = "0" + temp;
temp = temp.substring( 2, 4 ) + temp.substring( 0, 2 );
}
}
else temp = getData( Integer.toHexString( Integer.parseInt( temp ) ) + "H", DB );
return temp.toUpperCase();
}
private String getAdrType( String temp ) {
return Tables.TA[ Tables.searchTA( temp ) ][ 1 ];
}
private String correctAdr( String adr, boolean db ) {
while( adr.length() < ( db ? 2 : 4 ) ) adr = "0" + adr;
return adr;
}
private void createT( String codeLine ) {
outFile.println( "T " + correctAdr( Integer.toHexString( address ), false ) + " " + correctAdr( Integer.valueOf( newAddress ).toString(), !false ) + " " + codeLine );
address += newAddress;
List( -1, codeLine.toUpperCase() + " " + line );
}
void createE( ) {
outFile.println( "E " + this.start );
}
void List( int e, String code ) {
if( e == -1 ){
listFile.println( this.lineNumber + " " + code );
}
else{
listFile.println( this.lineNumber + " " + Tables.errors[ e ] + " " + code );
}
}
void close() {
listFile.close();
outFile.close();
}
}
public class Tables {
final static String[][] TFK = { // таблица форматов команд
// Мнемокод, код, байт W, дополнительные байты, тип операндов
{ "MOV", "1000101", "0", "11Reg1Reg2", "", "RR8", "2" },
{ "MOV", "1000101", "1", "11Reg1Reg2", "", "RR16", "2" },
{ "MOV", "1000101", "0", "ModAdrTypeReg1", "Disp", "RO8", "2" },
{ "MOV", "1000101", "1", "ModAdrTypeReg1", "Disp", "RO16", "2" },
{ "MOV", "1000100", "0", "ModReg1AdrType", "Disp", "OR8", "2" },
{ "MOV", "1000100", "1", "ModReg1AdrType", "Disp", "OR16", "2" },
{ "MOV", "1100011", "0", "11000Reg1", "Data", "RN8", "3" },
{ "MOV", "1100011", "1", "11000Reg1", "Data", "RN16", "4" },
//
{ "SUB", "0010101", "0", "11Reg1Reg2", "", "RR8", "2" },
{ "SUB", "0010101", "1", "11Reg1Reg2", "", "RR16", "2" },
{ "SUB", "0010101", "0", "ModAdrTypeReg1", "Disp", "RO8", "2" },
{ "SUB", "0010101", "1", "ModAdrTypeReg1", "Disp", "RO16", "2" },
{ "SUB", "0010100", "0", "ModReg1AdrType", "Disp", "OR8", "2" },
{ "SUB", "0010100", "1", "ModReg1AdrType", "Disp", "OR16", "2" },
{ "SUB", "1000001", "0", "11000Reg1", "Data", "RN8", "3" },
{ "SUB", "1000001", "1", "11000Reg1", "Data", "RN16", "4" },
//
{ "SHL", "1101000", "0", "11010Reg1", "", "R8", "2" },
{ "SHL", "1101000", "1", "11010Reg1", "", "R16", "2" },
//
{ "JA", "0111011", "1", "Disp", "", "L", "2" },
{ "INT", "1100110", "1", "Data", "", "N", "2" },
};
final static String[][] TR = { // таблица регистров
{ "AL", "000", "0" },
{ "AX", "000", "1" },
{ "CL", "001", "0" },
{ "CX", "001", "1" },
{ "DL", "010", "0" },
{ "DX", "010", "1" },
{ "BL", "011", "0" },
{ "BX", "011", "1" },
{ "AH", "100", "0" },
{ "SP", "100", "1" },
{ "CH", "101", "0" },
{ "BP", "101", "1" },
{ "DH", "110", "0" },
{ "SI", "110", "1" },
{ "BH", "100", "0" },
{ "DI", "100", "1" }
};
final static String[][] TA = { // таблица адресации
{ "BX+SI", "000" },
{ "BX+DI", "001" },
{ "BP+SI", "010" },
{ "BP+DI", "011" },
};
final static String[] TD = { // таблица директив
"SEGMENT",
"ENDS",
"ORG",
"END",
"DB",
"DW"
};
final static String[] errors = { // ошибки
"Неверное кол-во полей",
"Метка уже объявлена",
"Переменная уже объявлена",
"Неверная разрядность операндов",
"Неверный тип операнда",
"Неизвестная директива",
"Неверные данные",
"Неверная метка",
"Неверная структура",
};
static int searchTR( String temp ) { // поиск по таблице регистров
temp = temp.toUpperCase();
for ( int i = 0; i < TR.length; i++ ) {
if ( TR[ i ][ 0 ].equals( temp ) ) return i;
}
return -1;
}
static int searchTA( String temp ) { // поиск по таблице адресации
temp = temp.toUpperCase();
for ( int i = 0; i < TA.length; i++ ) {
if ( TA[ i ][ 0 ].equals( temp )) return i;
}
return -1;
}
static int searchTFK( String temp, String opType ) { // поиск по таблице форматов
temp = temp.toUpperCase();
for ( int i = 0; i < TFK.length; i++ ) {
if ( TFK[ i ][ 0 ].equals( temp ) && TFK[ i ][ 5 ].equals( opType ) ) return i;
}
return -1;
}
static int searchTFK( String temp ) { // поиск по таблице форматов
temp = temp.toUpperCase();
for ( int i = 0; i < TFK.length; i++ ) {
if ( TFK[ i ][ 0 ].equals( temp ) ) return i;
}
return -1;
}
static int searchTD( String temp ) { // поиск по таблице директив
for ( int i = 0; i < TD.length; i++ ) {
if ( TD[ i ].equals( temp )) return i;
}
return -1;
}
}