Generate machine code and produce the final object program.
Convert symbolic machine op-codes to their corresponding bit patterns.
Store machine op-codes in the MOT (Machine Opcode Table), which includes the symbolic code, length, and bit configuration.
Process pseudo-operations and store them in the POT (Pseudo-Operation Table).
Generate object code: Replace labels with their corresponding addresses and translate instructions into their binary formats.
Write the final object program and generate a listing of the source code.
During the first pass, the assembler scans the assembly code, checks for errors, assigns memory locations to instructions and symbols, and creates an intermediate file for use in Pass 2.
Symbol Table: A key data structure that holds symbols (labels) and their corresponding memory addresses. In Pass 2, the assembler uses this table to resolve symbolic addresses, replacing references to labels with actual memory addresses, which is essential for generating correct object code.
Literal Table: This table stores literals defined in the source program along with their assigned memory addresses and values. During Pass 2, the assembler uses this table to map literals to their memory locations, ensuring that literal values are accurately included in the object code.
Location Counter (LC): A dynamic structure that tracks the memory address of each instruction and data item. In Pass 2, the Location Counter assigns memory addresses to each program component, ensuring proper placement and alignment of the object code segments.
Opcode Table (OPTAB): Contains machine opcodes and instruction formats for all mnemonics in the assembly language. The assembler uses this table in Pass 2 to retrieve the correct opcode and instruction format, which are necessary for converting mnemonics into executable machine code.
begin
read first input line (from intermediate file)
if OPCODE ='START' then
begin
write listing line
read next input line
end {if START}
write Header record to object program
initialize first Text record
while OPCODE != 'END' do
begin
if this is not a 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
if found then
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
end {if opcode found}
else if OPCODE ='BYTE' or 'WORD' then
convert constant to object code
if object code will not fit into the current Text record then
begin
write Text record to object program
initialize new Text record
end
add object code to Text record
end {if not comment}
write listing line
read next input line
end(while not END)
write last Text record to object program
write End record to object program
write last listing line
end{Pass 2}
Intermediate:
- COPY START 1000
1000 - +LDA ALPHA
1004 - ADD #1
1007 - DIV #2
100A - STA BETA
100D - SUB #4
1010 - STA GAMMA
1013 - +LDA GAMMA
1017 - ADD #2
101A - +LDA BETA
101E ALPHA BYTE C'COF'
1021 BETA RESW 2
1027 GAMMA RESW 2
102D - END 1000
Optab:
DIV 06
SUB 05
CMP 03
LDA 00
STA 23
ADD 01
JNC 08
Symbol Tab:
ALPHA 101E
BETA 1021
GAMMA 1027
#iinclude<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<stdbool.h>
char *decimalToHex(int decimal) {
static char hex_string[20];
sprintf(hex_string, "%X", decimal);
return hex_string;
}
void main() {
printf("\nPASS 2.\n");
char loc[20], label[20], opcode[20], operand[20];
char optab_opcode[10], optab_machine_code[10];
char symtab_label[10], symtab_address[10];
int count = 0, start, end, length = 0;
bool opcode_found = false;
bool label_found = false;
FILE *input, *output, *symtab, *optab;
input = fopen("intermediate.txt", "r");
output = fopen("object.txt", "w");
symtab = fopen("symtab.txt", "r");
optab = fopen("optab.txt", "r");
if (input == NULL || output == NULL || symtab == NULL || optab == NULL){
printf("Error! File not found!");
exit(0);
} else {
printf("All files opened successfully!\n");
}
fscanf(input, "%s %s %s %s", loc, label, opcode, operand);
start = strtol(operand, NULL, 16);
while (!feof(input)) {
if(strcmp(opcode,"BYTE")==0){
count+=strlen(operand)-3;
}
if (!(strcmp(opcode, "START") == 0 || strcmp(opcode, "END") == 0 || strcmp(opcode, "RESW") == 0 || strcmp(opcode, "RESB") == 0 || strcmp(opcode,"BYTE")==0)) {
count+=3;
}
fscanf(input, "%s %s %s %s", loc, label, opcode, operand);
}
end = strtol(loc, NULL, 16);
printf("END: %d/ START: %d", end, start);
length = end - start;
rewind(input);
fscanf(input, "%s %s %s %s", loc, label, opcode, operand);
fprintf(output, "H^%s^00%s^0000%d\n", label, operand, length);
fprintf(output, "T^00%s^%d^", operand,count);
while (!feof(input)) {
if (strcmp(opcode, "START") == 0 || strcmp(opcode, "END") == 0 || strcmp(opcode, "RESW") == 0 || strcmp(opcode, "RESB") == 0) {
fscanf(input, "%s %s %s %s", loc, label, opcode, operand);
continue;
} else {
rewind(optab);
opcode_found = false;
fscanf(optab, "%s %s", optab_opcode, optab_machine_code);
while (!feof(optab)) {
if (strcmp(opcode, optab_opcode) == 0) {
opcode_found = true;
break;
}
fscanf(optab, "%s %s", optab_opcode, optab_machine_code);
}
if (opcode_found) {
rewind(symtab);
label_found = false;
fscanf(symtab, "%s %s", symtab_label, symtab_address);
while (!feof(symtab)) {
if (strcmp(symtab_label, operand) == 0) {
label_found = true;
break;
}
fscanf(symtab, "%s %s", symtab_label, symtab_address);
}
if (label_found) {
fprintf(output, "%s%s^", optab_machine_code, symtab_address);
} else {
printf("Error! Label not found in symtab!\n");
exit(0);
}
} else if (strcmp(opcode, "WORD") == 0) {
fprintf(output, "00000%s ", operand);
}
else if (strcmp(opcode, "BYTE") == 0) {
for (int i = 2; i < strlen(operand) - 1; i++) {
fprintf(output, "%s", decimalToHex(operand[i]));
}
fprintf(output, "^");
} else {
printf("Error!\n %s", opcode);
exit(0);
}
}
fscanf(input, "%s %s %s %s", loc, label, opcode, operand);
}
fprintf(output, "\nE^00%s\n", decimalToHex(start));
fclose(input);
fclose(output);
fclose(symtab);
fclose(optab);
output = fopen("object.txt", "r");
char str = fgetc(output);
printf("\n\nObject program file/ Output file : \n\n");
while (str != EOF) {
printf("%c", str);
str = fgetc(output);
}
fclose(output);
}