The SIC (Simplified Instructional Computer) and its extended version SIC/XE are educational computer architectures used to teach assembly language programming. SIC/XE adds complexity with more advanced instructions and flexible memory addressing. It uses a two-pass assembler process to translate assembly code into machine code.
Pass 2:
Use the Symbol Table to resolve addresses.
Translate instructions into Object Code.
Handle literals and external references.
Generate the Object Program with Header, Text, Modification, and End records.
Begin
read 1st input line
if OPCODE = ‘START’ then
begin
write listing line
read next input line
end
write Header record to object program
initialize 1st Text record
while OPCODE != ‘END’ do
begin
if this is not comment line then
begin
search OPTAB for OPCODE
if found then
Begin
if there is a symbol in OPERAND field then
Begin
search SYMTAB for OPERAND field then
if found then
Begin
store symbol value as operand address
Else
Begin
store 0 as operand address
set error flag (undefined symbol)
End
end (if symbol)
else store 0 as operand address
assemble the object code instruction
else if OPCODE = ‘BYTE’ or ‘WORD” then
convert constant to object code
if object code doesn’t fit into current Text record then
Begin
Write text record to object code
initialize new Text record
end
add object code to Text record
end {if not comment}
write listing line
read next input line
end
write listing line
read next input line
write last listing line
End {Pass 2}
Program:-
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
// Function prototypes
void passOne(char label[10], char opcode[10], char operand[10], char code[10], char mnemonic[3]);
void display();
int main() {
// for reading from input
char label[10], opcode[10], operand[10];
// for reading from optab
char code[10], mnemonic[3];
// Call pass1 function
passOne(label, opcode, operand, code, mnemonic);
return 0;
}
void passOne(char label[10], char opcode[10], char operand[10], char code[10], char mnemonic[3]) {
int locctr = 0, start = 0, length = 0;
char controlSection[10];
FILE *fp1, *fp2, *fp3, *fp4, *fp5; // File pointers for input, optab, symtab, intermediate file, and csect table
// Open files
fp1 = fopen("input.txt", "r"); // Input file
fp2 = fopen("optab.txt", "r"); // Optab file
fp3 = fopen("symtab.txt", "w"); // Symbol table
fp4 = fopen("intermediate.txt", "w");// Intermediate file
fp5 = fopen("csect_table.txt", "w"); // Control section table
if (!fp1 || !fp2 || !fp3 || !fp4 || !fp5) {
printf("Error opening files.\n");
exit(1);
}
// Read the first line of the input file
fscanf(fp1, "%s\t%s\t%s", label, opcode, operand);
strcpy(controlSection, label);
if (strcmp(opcode, "START") == 0) {
start = atoi(operand);
locctr = start;
fprintf(fp4, "%s\t%s\t%s\t%s\n", controlSection, label, opcode, operand);
fprintf(fp5, "%s\t%04X\t", controlSection, locctr); // Add control section name and start address
fscanf(fp1, "%s\t%s\t%s", label, opcode, operand);
}
int sectionLength = 0;
// Process the input file until END is encountered
while (1) {
// If the opcode is CSECT, update control section
if (strcmp(opcode, "CSECT") == 0) {
fprintf(fp5, "%04X\n", sectionLength); // Update previous control section length
fprintf(fp4, "%04X\t%s\t%s\t%s\n", locctr, label, opcode, operand);
locctr = 0;
sectionLength = 0;
strcpy(controlSection, label);
fprintf(fp5, "%s\t%04X\t", controlSection, locctr); // Add new control section
fscanf(fp1, "%s\t%s\t%s", label, opcode, operand);
continue;
}
// Write the intermediate file
fprintf(fp4, "%04X\t%s\t%s\t%s\n", locctr, label, opcode, operand);
// Write to symbol table if there is a label
if (strcmp(label, "**") != 0) {
fprintf(fp3, "%s\t%04X\n", label, locctr);
}
// Search for the opcode in the optab
rewind(fp2); // Reset the optab file pointer
int found = 0;
fscanf(fp2, "%s\t%s", code, mnemonic);
while (!feof(fp2)) {
if (strcmp(opcode, code) == 0) {
locctr += 3; // Increment location counter for valid opcodes
found = 1;
break;
}
fscanf(fp2, "%s\t%s", code, mnemonic);
}
// Handle pseudo-operations
if (!found) {
if (strcmp(opcode, "WORD") == 0) {
locctr += 3;
} else if (strcmp(opcode, "RESW") == 0) {
locctr += 3 * atoi(operand);
} else if (strcmp(opcode, "BYTE") == 0) {
if (operand[0] == 'C') {
locctr += strlen(operand) - 3; // Count characters in the constant
} else if (operand[0] == 'X') {
locctr += (strlen(operand) - 3) / 2; // Count bytes in the hexadecimal constant
}
} else if (strcmp(opcode, "RESB") == 0) {
locctr += atoi(operand);
}
}
// Break the loop when END is encountered
if (strcmp(opcode, "END") == 0) {
fprintf(fp4, "%04X\t%s\t%s\t%s\n", locctr, label, opcode, operand);
sectionLength = locctr;
fprintf(fp5, "%04X\n", sectionLength); // Finalize the current control section
break;
}
// Read the next line from the input file
fscanf(fp1, "%s\t%s\t%s", label, opcode, operand);
}
// Close all files
fclose(fp1);
fclose(fp2);
fclose(fp3);
fclose(fp4);
fclose(fp5);
// Display results
display();
// Calculate total length of the program
length = locctr - start;
printf("\nThe total length of the program is: %d\n", length);
}
void display() {
char str;
FILE *fp1, *fp2, *fp3, *fp4;
// Display Input File
printf("\nThe contents of the Input File:\n");
fp1 = fopen("input.txt", "r");
str = fgetc(fp1);
while (str != EOF) {
putchar(str);
str = fgetc(fp1);
}
fclose(fp1);
// Display Intermediate File
printf("\n\nThe contents of the Intermediate File:\n");
fp2 = fopen("intermediate.txt", "r");
str = fgetc(fp2);
while (str != EOF) {
putchar(str);
str = fgetc(fp2);
}
fclose(fp2);
// Display Symbol Table
printf("\n\nThe contents of the Symbol Table:\n");
fp3 = fopen("symtab.txt", "r");
str = fgetc(fp3);
while (str != EOF) {
putchar(str);
str = fgetc(fp3);
}
fclose(fp3);
// Display Control Section Table
printf("\n\nThe contents of the Control Section Table:\n");
fp4 = fopen("csect_table.txt", "r");
str = fgetc(fp4);
while (str != EOF) {
putchar(str);
str = fgetc(fp4);
}
fclose(fp4);
}
Output:-