a. Introduction:
Purpose of the Program:
Implements the Pass 2 of a Direct Linking Loader, which takes object code from multiple object modules and produces a memory image for execution.
Function of Pass 2:
Uses the External Symbol Table (ESTAB) generated in Pass 1 to resolve external references.
Processes text records, modifies addresses based on relocation information, and outputs the final object program in a structured format.
Main Tasks Performed:
Reads and processes the ESTAB file to load external symbols and their addresses.
Reads the INPUT file containing object code records, resolves addresses, and applies modifications.
Generates the OUTPUT file with the final memory image in hexadecimal format.
Outcome:
Produces a fully linked memory image ready for execution.
b. Problem Description:
Reading and Storing External Symbols:
The program first opens the ESTAB file and loads all external symbols, their addresses, and lengths into a table.
The EXECADDR (execution address) is initialized to the starting address of the first control section.
Processing Object Code Records:
Reads the INPUT file line by line to process Header (H), Text (T), and Modification (M) records.
The Header Record (H) defines the control section name and its starting address.
The Text Record (T) contains the actual object code and its length.
The Modification Record (M) specifies addresses that require adjustments based on external symbol references.
Handling Address Relocation and Modifications:
The program adjusts the addresses in the Modification Records by either adding or subtracting the address of the referenced external symbol from ESTAB.
It supports both positive (+) and negative (-) modifications.
The modified addresses are converted back into hexadecimal format and updated in the object code array.
Generating Output:
The program formats the final output into a structured memory image file (OUTPUT.TXT).
The memory image contains memory addresses and corresponding object code, formatted with tabular spacing.
The output is printed to the console for verification.
Error Handling and Validation:
Ensures that all symbols referenced in modification records exist in the ESTAB.
Handles potential mismatches between symbol references and definitions.
Objective:
The program resolves all external references and generates a fully linked and ready-to-execute memory image in Pass 2.
Ensures that all text records are correctly relocated and all modification records are processed accurately.
Pass 2 of two pass linking loader:
Code :
Pass 2 of two pass linking loader:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
struct exttable
{
char cextsym[20], extsym[20];
int address, length;
} estab[20];
struct objectcode
{
unsigned char code[15];
int add;
} obcode[500];
void main()
{
char temp[10];
FILE *fp1, *fp2, *fp3;
int i, j, x, y, pstart, exeloc, start, textloc, loc, textlen, length, location, st, s;
int n = 0, num = 0, inc = 0, count = 0, record = 0, mloc[30], mlen[30];
signed long int newadd;
char operation, lbl[10], input[10], label[50][10], opr[30], ch, *add1, address[10];
fp1 = fopen("INPUT.TXT", "r");
fp2 = fopen("ESTAB.TXT", "r");
fp3 = fopen("OUTPUT.TXT", "w");
while (!feof(fp2))
{
fscanf(fp2, "%s %s %x %x", estab[num].cextsym, estab[num].extsym, &estab[num].address, &estab[num].length);
num++;
}
exeloc = estab[0].address;
loc = exeloc;
start = loc;
st = start;
while (!feof(fp1))
{
fscanf(fp1, "%s", input);
if (strcmp(input, "H") == 0)
{
fscanf(fp1, "%s", input);
for (i = 0; i < num; i++)
if (strcmp(input, estab[i].cextsym) == 0)
{
pstart = estab[i].address;
break;
}
while (strcmp(input, "T") != 0)
fscanf(fp1, "%s", input);
}
do
{
if (strcmp(input, "T") == 0)
{
fscanf(fp1, "%x", &textloc);
textloc = textloc + pstart;
for (i = 0; i < (textloc - loc); i++)
{
strcpy(obcode[inc].code, "..");
obcode[inc++].add = start++;
}
fscanf(fp1, "%x", &textlen);
loc = textloc + textlen;
}
else if (strcmp(input, "M") == 0)
{
fscanf(fp1, "%x", &mloc[record]);
mloc[record] = mloc[record] + pstart;
fscanf(fp1, "%x", &mlen[record]);
fscanf(fp1, "%s", label[record++]);
}
else
{
length = strlen(input);
x = 0;
for (i = 0; i < length; i++)
{
obcode[inc].code[x++] = input[i];
if (x > 1)
{
obcode[inc++].add = start++;
x = 0;
}
}
}
fscanf(fp1, "%s", input);
} while (strcmp(input, "E") != 0);
if (strcmp(input, "E") == 0)
fscanf(fp1, "%s", input);
}
for (n = 0; n < record; n++)
{
operation = label[n][0];
length = strlen(label[n]);
for (i = 1; i < length; i++)
{
lbl[i - 1] = label[n][i];
}
lbl[length - 1] = '\0';
length = 0;
strcpy(address, "\0");
location = mloc[n] - exeloc;
loc = location;
count = 0;
while (length < mlen[n])
{
strcat(address, obcode[location++].code);
count++;
length += 2;
}
for (i = 0; i < num; i++)
{
if (strcmp(lbl, estab[i].cextsym) == 0)
break;
if (strcmp(lbl, estab[i].extsym) == 0)
break;
}
switch (operation)
{
case '+':
newadd = strtol(address, &add1, 16) + (long int)estab[i].address;
break;
case '-':
newadd = strtol(address, &add1, 16) - (long int)estab[i].address;
break;
}
ltoa(newadd, address, 16);
x = 0;
y = 0;
while (count > 0)
{
obcode[loc].code[x++] = address[y++];
if (x > 1)
{
x = 0;
loc++;
count--;
}
}
}
count = 0;
n = 0;
s = st - 16;
fprintf(fp3, "%x\t", s);
for (i = 1; i <= 16; i++)
{
fprintf(fp3, "xx");
if (i == 4 || i == 8 || i == 12)
{
fprintf(fp3, "\t");
}
}
fprintf(fp3, "\n\n%x\t", obcode[0].add);
for (i = 0; i < inc; i++)
{
fprintf(fp3, "%s", obcode[i].code);
n++;
if (n > 3)
{
fprintf(fp3, "\t");
n = 0;
count++;
}
if (count > 3)
{
fprintf(fp3, "\n\n%x\t", obcode[i + 1].add);
count = 0;
}
}
fclose(fp1);
fclose(fp2);
fclose(fp3);
printf("\n\t***** PASS TWO OF A DIRECT-LINKING LOADER *****\n");
printf("\nThe contents of the output file:");
printf("\n---------------------------------------------------------------");
printf("\nAddress\t\t\t\tContents");
printf("\n---------------------------------------------------------------\n");
fp3 = fopen("OUTPUT.TXT", "r");
ch = fgetc(fp3);
while (ch != EOF)
{
printf("%c", ch);
ch = fgetc(fp3);
}
fclose(fp3);
}