diff --git a/Server/src/main/java/net/simon987/server/assembly/Assembler.java b/Server/src/main/java/net/simon987/server/assembly/Assembler.java index 151f952..89c8782 100755 --- a/Server/src/main/java/net/simon987/server/assembly/Assembler.java +++ b/Server/src/main/java/net/simon987/server/assembly/Assembler.java @@ -23,6 +23,8 @@ public class Assembler { private InstructionSet instructionSet; private RegisterSet registerSet; + + private static final int MEM_SIZE = 0x10000; // Size in words public Assembler(InstructionSet instructionSet, RegisterSet registerSet, ServerConfiguration config) { this.instructionSet = instructionSet; @@ -206,6 +208,11 @@ public class Assembler { try { int factor = Integer.decode(valueTokens[0]); + + if (factor > MEM_SIZE) { + throw new InvalidOperandException("Factor '"+factor+"' exceeds total memory size", currentLine); + } + String value = valueTokens[1].substring(4, valueTokens[1].lastIndexOf(')')); //Handle label @@ -341,14 +348,17 @@ public class Assembler { } //Pass 2: Save label names and location - char currentOffset = 0; + int currentOffset = 0; for (currentLine = 0; currentLine < lines.length; currentLine++) { try { - checkForLabel(lines[currentLine], result, currentOffset); + checkForLabel(lines[currentLine], result, (char)currentOffset); //Increment offset currentOffset += parseInstruction(lines[currentLine], currentLine, instructionSet).length / 2; + if (currentOffset >= MEM_SIZE) { + throw new OffsetOverflowException(currentOffset, MEM_SIZE, currentLine); + } } catch (AssemblyException e) { //Ignore error on pass 2 //System.out.println(e); @@ -379,10 +389,19 @@ public class Assembler { //Encode instruction byte[] bytes = parseInstruction(line, currentLine, result.labels, instructionSet); currentOffset += bytes.length / 2; + + if (currentOffset >= MEM_SIZE) { + throw new OffsetOverflowException(currentOffset, MEM_SIZE, currentLine); + } + out.write(bytes); } catch (EmptyLineException | PseudoInstructionException e) { //Ignore empty lines and pseudo-instructions + } catch (FatalAssemblyException asmE) { + // Save error, but abort assembly at this line + result.exceptions.add(asmE); + break; } catch (AssemblyException asmE) { //Save errors on pass3 result.exceptions.add(asmE); diff --git a/Server/src/main/java/net/simon987/server/assembly/exception/FatalAssemblyException.java b/Server/src/main/java/net/simon987/server/assembly/exception/FatalAssemblyException.java new file mode 100644 index 0000000..37ec681 --- /dev/null +++ b/Server/src/main/java/net/simon987/server/assembly/exception/FatalAssemblyException.java @@ -0,0 +1,20 @@ +package net.simon987.server.assembly.exception; + +/** + * Class of exceptions that should stop assembly immediatly + */ +public class FatalAssemblyException extends AssemblyException { + + /** + * Message of the exception + */ + private static final String message = "A fatal assembly error has occurred"; + + /** + * Create a new Duplicate Segment Exception + */ + public FatalAssemblyException(String msg, int line) { + super(msg, line); + } +} + diff --git a/Server/src/main/java/net/simon987/server/assembly/exception/OffsetOverflowException.java b/Server/src/main/java/net/simon987/server/assembly/exception/OffsetOverflowException.java new file mode 100644 index 0000000..2641a15 --- /dev/null +++ b/Server/src/main/java/net/simon987/server/assembly/exception/OffsetOverflowException.java @@ -0,0 +1,19 @@ +package net.simon987.server.assembly.exception; + +/** + * Threw when offset for stored instruction/data overflows the size of memory + */ +public class OffsetOverflowException extends FatalAssemblyException { + + /** + * Message of the exception + */ + private static final String message = "Program data exceeds memory size "; + + /** + * Create a new Offset Overflow Exception + */ + public OffsetOverflowException(int offset, int memsiz, int line) { + super(message + offset + " > " + memsiz, line); + } +}