Исправления в коде
This commit is contained in:
parent
36ab1b7c05
commit
e240978379
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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",
|
}
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
@ -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"
|
}
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user