Исправления в коде

This commit is contained in:
Victor 2014-03-22 18:45:13 +02:00
parent 36ab1b7c05
commit e240978379
7 changed files with 302 additions and 328 deletions

View File

@ -1,167 +1,167 @@
package com.annimon.asm.directives; package com.annimon.asm.directives;
import com.annimon.asm.ListingGenerateHelper; import com.annimon.asm.ListingGenerateHelper;
import com.annimon.asm.VarTable; import com.annimon.asm.VarTable;
import com.annimon.asm.exceptions.CommaExpectedException; import com.annimon.asm.exceptions.CommaExpectedException;
import com.annimon.asm.exceptions.ExceptionWithLineNumber; import com.annimon.asm.exceptions.ExceptionWithLineNumber;
import com.annimon.asm.exceptions.FewArgumentsException; import com.annimon.asm.exceptions.FewArgumentsException;
import com.annimon.asm.exceptions.TooManyArgumentsException; import com.annimon.asm.exceptions.TooManyArgumentsException;
import com.annimon.asm.exceptions.WrongArgumentException; import com.annimon.asm.exceptions.WrongArgumentException;
/** /**
* *
* @author aNNiMON * @author aNNiMON
*/ */
public class Add extends Directive implements ISyntaxChecker, IListingGenerator { public class Add extends Directive implements ISyntaxChecker, IListingGenerator {
public Add() { public Add() {
super("add", ID.ADD); super("add", ID.ADD);
} }
@Override @Override
public boolean check(int lineNumber, int[] ids) throws ExceptionWithLineNumber { public boolean check(int lineNumber, int[] ids) throws ExceptionWithLineNumber {
if (ids[0] != getId()) return false; if (ids[0] != getId()) return false;
if (ids.length < 4) throw new FewArgumentsException(lineNumber); if (ids.length < 4) throw new FewArgumentsException(lineNumber);
else if (ids.length > 4) throw new TooManyArgumentsException(lineNumber); else if (ids.length > 4) throw new TooManyArgumentsException(lineNumber);
if (ids[2] != ID.COMMA) throw new CommaExpectedException(lineNumber); if (ids[2] != ID.COMMA) throw new CommaExpectedException(lineNumber);
int[] pairs = new int[] { int[] pairs = new int[] {
// Ðåãèñòð - Ðåãèñòð // Ðåãèñòð - Ðåãèñòð
ID.REGISTER_BYTE, ID.REGISTER_BYTE, ID.REGISTER_BYTE, ID.REGISTER_BYTE,
ID.REGISTER_WORD, ID.REGISTER_WORD, ID.REGISTER_WORD, ID.REGISTER_WORD,
ID.REGISTER_WORD, ID.REGISTER_BYTE, ID.REGISTER_WORD, ID.REGISTER_BYTE,
// Ðåãèñòð - Ïàìÿòü // Ðåãèñòð - Ïàìÿòü
ID.REGISTER_BYTE, ID.VAR_BYTE, ID.REGISTER_BYTE, ID.VAR_BYTE,
ID.REGISTER_WORD, ID.VAR_WORD, ID.REGISTER_WORD, ID.VAR_WORD,
ID.REGISTER_WORD, ID.VAR_BYTE, ID.REGISTER_WORD, ID.VAR_BYTE,
// Ïàìÿòü - Ðåãèñòð // Ïàìÿòü - Ðåãèñòð
ID.VAR_BYTE, ID.REGISTER_BYTE, ID.VAR_BYTE, ID.REGISTER_BYTE,
ID.VAR_WORD, ID.REGISTER_WORD, ID.VAR_WORD, ID.REGISTER_WORD,
ID.VAR_WORD, ID.REGISTER_BYTE, ID.VAR_WORD, ID.REGISTER_BYTE,
// Ðåãèñòð - Çíà÷åíèå // Ðåãèñòð - Çíà÷åíèå
ID.REGISTER_BYTE, ID.NUMBER_BYTE, ID.REGISTER_BYTE, ID.NUMBER_BYTE,
ID.REGISTER_WORD, ID.NUMBER_WORD, ID.REGISTER_WORD, ID.NUMBER_WORD,
ID.REGISTER_WORD, ID.NUMBER_BYTE, ID.REGISTER_WORD, ID.NUMBER_BYTE,
// Ïàìÿòü - Çíà÷åíèå // Ïàìÿòü - Çíà÷åíèå
ID.VAR_BYTE, ID.NUMBER_BYTE, ID.VAR_BYTE, ID.NUMBER_BYTE,
ID.VAR_WORD, ID.NUMBER_WORD, ID.VAR_WORD, ID.NUMBER_WORD,
ID.VAR_WORD, ID.NUMBER_BYTE, ID.VAR_WORD, ID.NUMBER_BYTE,
}; };
boolean correct = false; boolean correct = false;
for(int i = 0; i < pairs.length; i += 2) { for(int i = 0; i < pairs.length; i += 2) {
if ( (ids[1] == pairs[i]) && (ids[3] == pairs[i+1]) ) { if ( (ids[1] == pairs[i]) && (ids[3] == pairs[i+1]) ) {
correct = true; correct = true;
break; break;
} }
} }
if (!correct) throw new WrongArgumentException(lineNumber); if (!correct) throw new WrongArgumentException(lineNumber);
return true; return true;
} }
@Override @Override
public String generate(int lineNumber, int[] ids, String[] strs, VarTable vars) { public String generate(int lineNumber, int[] ids, String[] strs, VarTable vars) {
if (ids[0] != getId()) return ""; if (ids[0] != getId()) return "";
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
if ( (ids[3] == ID.NUMBER_BYTE) || (ids[3] == ID.NUMBER_WORD) ) { if ( (ids[3] == ID.NUMBER_BYTE) || (ids[3] == ID.NUMBER_WORD) ) {
// ADD acc, imm 0000010w | data // ADD acc, imm 0000010w | data
if ( (strs[1].equalsIgnoreCase("ax")) || (strs[1].equalsIgnoreCase("al")) ) { if ( (strs[1].equalsIgnoreCase("ax")) || (strs[1].equalsIgnoreCase("al")) ) {
byte val = 0b00000100; byte val = 0b00000100;
if (strs[1].equalsIgnoreCase("ax")) val |= 1; if (strs[1].equalsIgnoreCase("ax")) val |= 1;
sb.append(ListingGenerateHelper.toHexString(val)) sb.append(ListingGenerateHelper.toHexString(val))
.append(' ') .append(' ')
.append(ListingGenerateHelper.toLittleEndianString(strs[3])); .append(ListingGenerateHelper.toLittleEndianString(strs[3]));
return sb.toString(); return sb.toString();
} }
// ADD r/m, imm 100000sw | mod000r/m | data // ADD r/m, imm 100000sw | mod000r/m | data
if (ListingGenerateHelper.isRegisterOrMemory(ids[1])) { if (ListingGenerateHelper.isRegisterOrMemory(ids[1])) {
int val = 0b100000_00; int val = 0b100000_00;
if ( (ids[1] == ID.REGISTER_WORD) || (ids[1] == ID.VAR_WORD) ) { if ( (ids[1] == ID.REGISTER_WORD) || (ids[1] == ID.VAR_WORD) ) {
val |= 1; val |= 1;
} }
String varaddr = " "; String varaddr = " ";
if ( (ids[1] == ID.VAR_BYTE) || (ids[1] == ID.VAR_WORD)) { if ( (ids[1] == ID.VAR_BYTE) || (ids[1] == ID.VAR_WORD)) {
short offset = vars.getAddressOfVariable(strs[1]); short offset = vars.getAddressOfVariable(strs[1]);
varaddr += ListingGenerateHelper.toLittleEndianString(offset) + " "; varaddr += ListingGenerateHelper.toLittleEndianString(offset) + " ";
} }
// mod // mod
int modreg = 0b00; int modreg = 0b00;
if (ids[1] == ID.REGISTER_WORD) modreg = 0b11; if (ids[1] == ID.REGISTER_WORD) modreg = 0b11;
modreg <<= 6; modreg <<= 6;
// r/m // r/m
if (strs[1].toLowerCase().indexOf("si") != -1) modreg |= 0b100; if (strs[1].toLowerCase().contains("si")) modreg |= 0b100;
else if (strs[1].toLowerCase().indexOf("di") != -1) modreg |= 0b101; else if (strs[1].toLowerCase().contains("di")) modreg |= 0b101;
else modreg |= 0b110; else modreg |= 0b110;
sb.append(ListingGenerateHelper.toHexString(val)) sb.append(ListingGenerateHelper.toHexString(val))
.append(' ') .append(' ')
.append(ListingGenerateHelper.toHexString(modreg)) .append(ListingGenerateHelper.toHexString(modreg))
.append(varaddr) .append(varaddr)
.append(ListingGenerateHelper.toLittleEndianString(strs[3])); .append(ListingGenerateHelper.toLittleEndianString(strs[3]));
return sb.toString(); return sb.toString();
} }
} }
// ADD r/m, reg 000000dw | modregr/m // ADD r/m, reg 000000dw | modregr/m
if (ListingGenerateHelper.isRegisterOrMemory(ids[1])) { if (ListingGenerateHelper.isRegisterOrMemory(ids[1])) {
int val = 0b000000_00; int val = 0b000000_00;
if ( (ids[1] == ID.REGISTER_WORD) || (ids[1] == ID.VAR_WORD) ) { if ( (ids[1] == ID.REGISTER_WORD) || (ids[1] == ID.VAR_WORD) ) {
val |= 1; val |= 1;
} }
if ( (ids[1] == ID.REGISTER_BYTE) || (ids[1] == ID.REGISTER_WORD) ) { if ( (ids[1] == ID.REGISTER_BYTE) || (ids[1] == ID.REGISTER_WORD) ) {
val |= 0b10; val |= 0b10;
} }
String varaddr = " "; String varaddr = " ";
if ( (ids[1] == ID.VAR_BYTE) || (ids[1] == ID.VAR_WORD)) { if ( (ids[1] == ID.VAR_BYTE) || (ids[1] == ID.VAR_WORD)) {
short offset = vars.getAddressOfVariable(strs[1]); short offset = vars.getAddressOfVariable(strs[1]);
varaddr += ListingGenerateHelper.toLittleEndianString(offset) + " "; varaddr += ListingGenerateHelper.toLittleEndianString(offset) + " ";
} }
// mod // mod
int modreg = 0b00; int modreg = 0b00;
if ( (ListingGenerateHelper.isRegister(ids[1])) && if ( (ListingGenerateHelper.isRegister(ids[1])) &&
(ListingGenerateHelper.isRegister(ids[3])) ) { (ListingGenerateHelper.isRegister(ids[3])) ) {
// Åñëè îáà îïåðàíäà - ðåãèñòðû, òî mod = 11 // Åñëè îáà îïåðàíäà - ðåãèñòðû, òî mod = 11
modreg |= 0b11; modreg |= 0b11;
} }
modreg <<= 6; modreg <<= 6;
// r/m // r/m
if (modreg == 0) modreg = 0b110; if (modreg == 0) modreg = 0b110;
else { else {
// Åñëè mod != 11, òî r/m - id ðåãèñòðà. // Åñëè mod != 11, òî r/m - id ðåãèñòðà.
modreg |= ListingGenerateHelper.getRegisterCode(strs[3]); modreg |= ListingGenerateHelper.getRegisterCode(strs[3]);
} }
// reg - id ðåãèñòðà ïåðâîãî îïåðàíäà, ëèáî 0. // reg - id ðåãèñòðà ïåðâîãî îïåðàíäà, ëèáî 0.
byte regID = ListingGenerateHelper.getRegisterCode(strs[1]); byte regID = ListingGenerateHelper.getRegisterCode(strs[1]);
if (modreg == 0b110) { if (modreg == 0b110) {
regID = ListingGenerateHelper.getRegisterCode(strs[3]); regID = ListingGenerateHelper.getRegisterCode(strs[3]);
} }
regID <<= 3; regID <<= 3;
modreg |= regID; modreg |= regID;
sb.append(ListingGenerateHelper.toHexString(val)) sb.append(ListingGenerateHelper.toHexString(val))
.append(' ') .append(' ')
.append(ListingGenerateHelper.toHexString(modreg)) .append(ListingGenerateHelper.toHexString(modreg))
.append(varaddr); .append(varaddr);
} }
return sb.toString(); return sb.toString();
} }
} }

View File

@ -1,28 +1,24 @@
package com.annimon.asm.directives; package com.annimon.asm.directives;
/** /**
* *
* @author aNNiMON * @author aNNiMON
*/ */
public class ByteRegister extends Register { public class ByteRegister extends Register {
public ByteRegister() { @Override
super(); public int getId() {
} return ID.REGISTER_BYTE;
}
@Override
public int getId() { @Override
return ID.REGISTER_BYTE; protected String[] getRegisterNames() {
} return new String[] {
"ah", "al",
@Override "bh", "bl",
protected String[] getRegisterNames() { "ch", "cl",
return new String[] { "dh", "dl",
"ah", "al", };
"bh", "bl", }
"ch", "cl",
"dh", "dl", }
};
}
}

View File

@ -1,27 +1,20 @@
package com.annimon.asm.directives; package com.annimon.asm.directives;
/** /**
* *
* @author aNNiMON * @author aNNiMON
*/ */
public class ByteValue extends NumericValue { public class ByteValue extends NumericValue {
public ByteValue() { @Override
super(); public int getId() {
} return ID.NUMBER_BYTE;
}
@Override
public int getId() { @Override
return ID.NUMBER_BYTE; protected boolean checkRange(Integer value) {
} if (value == null) return false;
return (-128 <= value) && (value <= 255);
@Override }
protected boolean checkRange(Integer value) {
if (value == null) return false; }
if ( (-128 <= value.intValue()) && (value.intValue() <= 255) ) {
return true;
}
return false;
}
}

View File

@ -1,27 +1,23 @@
package com.annimon.asm.directives; package com.annimon.asm.directives;
/** /**
* Íåîïðåäåë¸ííîå çíà÷åíèå (?) * Íåîïðåäåë¸ííîå çíà÷åíèå (?)
* @author aNNiMON * @author aNNiMON
*/ */
public class InfinityValue extends NumericValue { public class InfinityValue extends NumericValue {
public InfinityValue() { @Override
super(); public int getId() {
} return ID.NUMBER_INFINITY;
}
@Override
public int getId() { @Override
return ID.NUMBER_INFINITY; public boolean isDirective(String text) {
} return text.equals("?");
}
@Override
public boolean isDirective(String text) { @Override
return text.equals("?"); protected boolean checkRange(Integer value) {
} return true;
}
@Override }
protected boolean checkRange(Integer value) {
return true;
}
}

View File

@ -1,25 +1,25 @@
package com.annimon.asm.directives; package com.annimon.asm.directives;
/** /**
* *
* @author aNNiMON * @author aNNiMON
*/ */
public abstract class Register extends Directive { public abstract class Register extends Directive {
public Register() { public Register() {
super("", ID.NULL); super("", ID.NULL);
} }
@Override @Override
public boolean isDirective(String text) { public boolean isDirective(String text) {
String[] names = getRegisterNames(); String[] names = getRegisterNames();
for (int i = 0; i < names.length; i++) { for (String register : names) {
if (text.equalsIgnoreCase(names[i])) { if (text.equalsIgnoreCase(register)) {
return true; return true;
} }
} }
return false; return false;
} }
protected abstract String[] getRegisterNames(); protected abstract String[] getRegisterNames();
} }

View File

@ -1,27 +1,23 @@
package com.annimon.asm.directives; package com.annimon.asm.directives;
/** /**
* *
* @author aNNiMON * @author aNNiMON
*/ */
public class WordRegister extends Register { public class WordRegister extends Register {
public WordRegister() { @Override
super(); public int getId() {
} return ID.REGISTER_WORD;
}
@Override
public int getId() { @Override
return ID.REGISTER_WORD; protected String[] getRegisterNames() {
} return new String[] {
"ax", "bx", "cx", "dx",
@Override "cs", "ds", "ss", "es",
protected String[] getRegisterNames() { "sp", "bp", "si", "di"
return new String[] { };
"ax", "bx", "cx", "dx", }
"cs", "ds", "ss", "es",
"sp", "bp", "si", "di" }
};
}
}

View File

@ -1,27 +1,20 @@
package com.annimon.asm.directives; package com.annimon.asm.directives;
/** /**
* *
* @author aNNiMON * @author aNNiMON
*/ */
public class WordValue extends NumericValue { public class WordValue extends NumericValue {
public WordValue() { @Override
super(); public int getId() {
} return ID.NUMBER_WORD;
}
@Override
public int getId() { @Override
return ID.NUMBER_WORD; protected boolean checkRange(Integer value) {
} if (value == null) return false;
return (-32768 <= value) && (value <= 65535);
@Override }
protected boolean checkRange(Integer value) {
if (value == null) return false; }
if ( (-32768 <= value.intValue()) && (value.intValue() <= 65535) ) {
return true;
}
return false;
}
}