Introduction and Problem Description:
a. Introduction:
Pass 1 is the initial stage of a two-pass assembler, converting assembly language into machine code.
Focuses on analyzing the source program to extract essential information for generating the final object code.
Builds a symbol table mapping symbolic labels to memory locations.
Calculates memory addresses for instructions and data using the Location Counter (LOCCTR).
Processes assembler directives like START, END, BYTE, WORD, RESW, and RESB to allocate memory and define program boundaries.
Detects errors, such as duplicate labels or invalid instructions, enabling corrections before Pass 2.
Produces an intermediate file containing calculated addresses and program details.
b. Problem Description:
Symbol Table Construction:
Identifies and maps all labels to their respective memory addresses.
Detects and reports duplicate or undefined labels.
Memory Address Calculation:
Manages the LOCCTR to assign sequential addresses.
Accounts for varying instruction sizes and memory allocation directives like RESW and RESB.
Intermediate File Generation:
Ensures the file is accurate and well-structured with line numbers, mnemonics, operands, and addresses.
Prevents propagation of errors to Pass 2.
Directive Handling:
Processes START and END to define program boundaries.
Handles BYTE, WORD, RESW, and RESB for memory allocation.
Error Detection and Reporting:
Identifies syntax errors, invalid instructions, and misplaced labels.
Provides clear error messages for effective debugging.
Pass 1 of two pass assembler algorithm:
Codes:
SIC Pass 1 of two pass assembler:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct INPUT
{
char label[20], opcode[20], operand[20];
} INSTR;
typedef struct OpTab
{
char opCode[10], value[3], format[2];
} OPTAB;
int main()
{
INSTR a[100];
OPTAB b[102];
char sd[100];
char pName[30];
FILE *fp = fopen("SICinput.txt", "r");
FILE *ip = fopen("SICINT.txt", "w");
FILE *kp = fopen("SICSymTab.txt", "w");
FILE *optab = fopen("OpTab.txt", "r");
if (fp == NULL || ip == NULL || kp == NULL || optab == NULL)
{
printf("Unable to open one or more files\n");
return 1;
}
int Size = 0;
while (fscanf(optab, "%s %s %s", b[Size].opCode, b[Size].value, b[Size].format) != EOF)
{
Size++;
}
fclose(optab);
int i = 0;
int startValue = 0, locctr = 0;
while (fgets(sd, sizeof(sd), fp) && i < 100)
{
char lab[20] = "", oper[20] = "", open[20] = "";
int tokens = sscanf(sd, "%s %s %s", lab, oper, open);
strcpy(a[i].label, "");
strcpy(a[i].opcode, "");
strcpy(a[i].operand, "");
if (tokens == 1)
strcpy(a[i].opcode, lab);
else if (tokens == 2)
{
strcpy(a[i].opcode, lab);
strcpy(a[i].operand, oper);
}
else if (tokens == 3)
{
strcpy(a[i].label, lab);
strcpy(a[i].opcode, oper);
strcpy(a[i].operand, open);
if (i == 1)
strcpy(pName, a[i].label);
}
if ((strcmp(a[i].opcode, "START") == 0) && (i == 0))
{
strcpy(pName, a[i].label);
locctr = startValue = strtoul(a[0].operand, NULL, 16);
fprintf(ip, "%04X\t%s", startValue, sd);
if (tokens == 3)
fprintf(kp, "%s\t%X\n", a[i].label, startValue);
}
else
{
if (tokens == 3)
{
for (int j = 0; j < i; j++)
{
if (strcmp(a[i].label, a[j].label) == 0 && i != j)
{
printf("Duplicate label found: %s\n", a[j].label);
return 1;
}
}
fprintf(kp, "%s\t%X\n", a[i].label, locctr);
}
if (strcmp(a[i].opcode, "END") == 0)
continue;
else
{
fprintf(ip, "%04X\t%s", locctr, sd);
printf("PC address is: %X\n", locctr);
}
int found = 0, k = 0;
while (k < Size || strcmp(a[k].opcode, "END") == 0)
{
if (strcmp(b[k].opCode, a[i].opcode) == 0)
{
locctr += 3;
found = 1;
break;
}
k++;
}
if (found == 0)
{
if (strcmp(a[i].opcode, "WORD") == 0)
{
locctr += 3;
}
else if (strcmp(a[i].opcode, "RESW") == 0)
{
locctr += 3 * atoi(a[i].operand);
}
else if (strcmp(a[i].opcode, "RESB") == 0)
{
locctr += atoi(a[i].operand);
}
else if (strcmp(a[i].opcode, "BYTE") == 0)
{
if (a[i].operand[0] == 'X')
{
locctr += (strlen(a[i].operand) - 3) / 2;
}
else if (a[i].operand[0] == 'C')
{
locctr += strlen(a[i].operand) - 3;
}
}
else if (strcmp(a[i].opcode, "END") == 0)
continue;
else
{
printf("Invalid opcode found: %s\n", a[i].opcode);
}
}
}
i++;
}
// printf("%s\n",pName);
fprintf(ip, "%04X\t\t\tEND\t%s", locctr, pName);
int prLength = locctr - startValue;
printf("The program length is: %X\n", prLength);
fclose(fp);
fclose(ip);
fclose(kp);
return 0;
}
Sample Inputs and Outputs of SIC Pass 1 of two pass assembler:
Sample Inputs and Outputs of SIC/XE Pass 1 of two pass assembler: