Skip to content

Commit

Permalink
Assignment 5 Linker Loader
Browse files Browse the repository at this point in the history
  • Loading branch information
quazi-irfan committed Dec 28, 2016
1 parent 986a621 commit f28a857
Show file tree
Hide file tree
Showing 3 changed files with 253 additions and 0 deletions.
14 changes: 14 additions & 0 deletions src/LinkerLoader/ExternalSymbolTable.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package LinkerLoader;

import java.util.HashMap;
import java.util.Map;

public class ExternalSymbolTable {
public Map<String, Integer[]> CSList = new HashMap<>();
public Map<String, Integer[]> SymbolList = new HashMap<>();

ExternalSymbolTable(){
CSList = new HashMap<>();
SymbolList = new HashMap<>();
}
}
150 changes: 150 additions & 0 deletions src/LinkerLoader/LinkerLoader.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
package LinkerLoader;

import java.util.ArrayList;

public class LinkerLoader {
public static Integer CSlength = null;

public static void Pass1(ExternalSymbolTable externalSymbolTable, String instruction){
if(instruction.charAt(0) == 'H'){
String CSlabel = instruction.substring(1, 5); // from 1 to 4
CSlabel = CSlabel.replaceAll(" ", "");
Integer CSstartAddress = Main.startingCSAddress;
CSlength = Integer.parseInt(instruction.substring(11, 17), 16); // from 11 to 16

externalSymbolTable.CSList.put(CSlabel, new Integer[]{CSstartAddress, CSlength});
}

else if(instruction.charAt(0) == 'D'){
int dRecCount = instruction.substring(1).length() / 10;
for(int i = 0; i<dRecCount; i++){
String SymbolLabel = instruction.substring(i*10 + 1, i*10 + 5);
SymbolLabel = SymbolLabel.replaceAll(" ", "");
Integer SymbolOffset = Integer.parseInt(instruction.substring(i*10 + 5, i*10 + 11), 16);
Integer SymbolAddress = Main.startingCSAddress +SymbolOffset;

externalSymbolTable.SymbolList.put(SymbolLabel, new Integer[]{SymbolAddress, SymbolOffset});
}
}

else if(instruction.charAt(0) == 'E'){
if(instruction.length() > 1) {
// Update the execution address
String executionAddress = instruction.substring(1, 7);
Main.executionAddres = Main.startMemory + Integer.parseInt(executionAddress, 16);
}
// Update the starting address of the next CS
Main.startingCSAddress += CSlength;

// Update the total length
Main.length += CSlength;
}
}

public static Integer CSStartAddress = null;

public static void Pass2(ExternalSymbolTable externalSymbolTable, ArrayList<String> memoryMap, String instruction){
if(instruction.charAt(0) == 'H'){
String CSlabel = instruction.substring(1, 5);
CSlabel = CSlabel.replaceAll(" ", "");
CSStartAddress = externalSymbolTable.CSList.get(CSlabel)[0] - Main.startMemory; // 3860(10) = 14432(16)
}
else if(instruction.charAt(0) == 'T'){
Integer Taddress = Integer.parseInt(instruction.substring(1, 7), 16);
Integer Tlength = Integer.parseInt(instruction.substring(7, 9), 16);
String Trecord = instruction.substring(9, instruction.length());

// memory address = CS start address + T record offset
Integer memoryAddress = CSStartAddress + Taddress;

for(int i = 0; i<Tlength; i++){
memoryMap.set(memoryAddress, Trecord.substring(i*2, i*2+2));
memoryAddress += 1;
}
}

else if(instruction.charAt(0) == 'M'){
// get the address specified in the M record
Integer Maddress = Integer.parseInt(instruction.substring(1, 7), 16);
Integer memoryAddress = CSStartAddress + Maddress;

// get the six nibbles as a string from the address
String nibbles = memoryMap.get(memoryAddress).concat(memoryMap.get(memoryAddress+1)).concat(memoryMap.get(memoryAddress+2));

// get the length of nibbles we need to modify, and resize it if necessary
Integer length = Integer.parseInt(instruction.substring(7, 9), 16);
if(length == 5){
nibbles = nibbles.substring(1);
}

// Get the value of the nibble
Integer value = Integer.parseInt(nibbles, 16);

// get symbol address
String SymbolLabel = instruction.substring(10, instruction.length());
SymbolLabel = SymbolLabel.replaceAll(" ", "");
Integer SymbolAddress;
if(externalSymbolTable.CSList.get(SymbolLabel) == null)
SymbolAddress = externalSymbolTable.SymbolList.get(SymbolLabel)[0];
else
SymbolAddress = externalSymbolTable.CSList.get(SymbolLabel)[0];

// get the sign, and calculate the final value
char sign = instruction.charAt(9);
if(sign == '+'){
value += SymbolAddress;
} else if(sign == '-'){
value -= SymbolAddress;
}

// Convert the result to hex string
nibbles = Integer.toHexString(value);

// resize the string, in case of format 4 instruction
if(length == 5){
// restore the first character
String temp = new String();
temp = temp.concat(String.valueOf(memoryMap.get(memoryAddress).charAt(0)));

// pad it to 5 character long
nibbles = padLeft(nibbles, 5);

// append the first character
nibbles = temp.concat(nibbles);
}

// append in case of WORD directive
else {
nibbles = padLeft(nibbles, 6);
}

// replace the 3 memory mapping
memoryMap.set(memoryAddress, nibbles.substring(0,2));
memoryMap.set(memoryAddress+1, nibbles.substring(2,4));
memoryMap.set(memoryAddress+2, nibbles.substring(4,6));

}

}

static String padLeft(String str, int i){
int padCount = i - str.length();

// no padding required
if(padCount <= 0){
return str;
}

// padding required
else {
StringBuilder sb = new StringBuilder();

for(int j = 0 ;j<padCount; j++){
sb.append('0');
}
sb.append(str);

return sb.toString();
}
}
}
89 changes: 89 additions & 0 deletions src/LinkerLoader/Main.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package LinkerLoader;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Map;

public class Main {
public static Integer startMemory = Integer.parseInt("03860", 16);
public static Integer startingCSAddress = startMemory;
public static Integer executionAddres = null;
public static Integer length = 0;

public static void main(String[] args) throws IOException{
ExternalSymbolTable externalSymbolTable = new ExternalSymbolTable();

// String[] objectPrograms = {"prog1.txt", "func1.txt"}; // Source : Loading and Linking Example 4 a5
// String[] objectPrograms = {"prog2.txt", "func2.txt"}; // Source : Loading and Linking Example 2 c

// String[] objectPrograms = args;

// Pass 1
for(String fileName : args){
try(BufferedReader reader = new BufferedReader(new FileReader(fileName))) {
String instruction = reader.readLine();
while(instruction != null){
LinkerLoader.Pass1(externalSymbolTable, instruction);
instruction = reader.readLine();
}
} catch (IOException e){
System.out.println("Problem opening file during Pass 1.");
}
}

// memory map; initializing it to ??
int rowCount = (int) Math.ceil((double)length/16);
ArrayList<String> memoryMap = new ArrayList<>();
for(int i = 0; i<rowCount * 16; i++){
memoryMap.add("??");
}

// Pass 2
for(String fileName : args){
try(BufferedReader reader = new BufferedReader(new FileReader(fileName))) {
String instruction = reader.readLine();
while(instruction != null){
LinkerLoader.Pass2(externalSymbolTable, memoryMap, instruction);
instruction = reader.readLine();
}
} catch (IOException e){
System.out.println("Problem opening file during Pass 2.");
}
}

// print the memory map
System.out.println("Memory Layout : ");
System.out.println(" 0 1 2 3 4 5 6 7 8 9 A B C D E F");
for(int i = 0; i<rowCount; i++){
System.out.print(Integer.toHexString(startMemory + (i*16)).substring(0, 3).concat("X "));
for(int j = 0; j< 16; j++) {
System.out.print(memoryMap.get(i*16 + j) + " ");
}
System.out.println();
}

// Print the Execution Address
System.out.println("\nExecution Address : " + Integer.toHexString(executionAddres));

// Print the External Symbol Table
System.out.println("\nExternal Symbol Table : ");
System.out.println("CSECT\tSYMBOL\tADDR\tCSADDR\tLDADDR\tLENGTH");
for(Map.Entry<String, Integer[]> m : externalSymbolTable.CSList.entrySet()){
String CSlabel = m.getKey();
String CSstartAddress = Integer.toHexString(m.getValue()[0]);
String CSlenth = Integer.toHexString(m.getValue()[1]);

System.out.printf("%-25s%-18s%s\n", CSlabel, CSstartAddress, CSlenth);
}

for(Map.Entry<String, Integer[]> m : externalSymbolTable.SymbolList.entrySet()){
String SymbolLabel = m.getKey();
String SymbolAddress = Integer.toHexString(m.getValue()[0]);
String SymbolOffset = Integer.toHexString(m.getValue()[1]);

System.out.printf("%12s%8s%18s\n", SymbolLabel, SymbolOffset, SymbolAddress);
}
}
}

0 comments on commit f28a857

Please sign in to comment.