SPCC 7
SPCC 7
7
Roll no.:B-632
A two-pass assembler works by reading the assembly code twice to generate the correct machine code:
1. First Pass:
• The first pass goes through each line of the assembly code:
• If a label is found (e.g., START: MOV 5), the assembler records the label and its memory
address (or line number).
• If an instruction is found (e.g., MOV 5), the assembler processes it but does not generate
machine code yet. It simply moves to the next instruction.
The main objective of the first pass is to gather all the labels and store their corresponding addresses.
At the end of the first pass, the symbol table will contain all the labels and their addresses.
void chk_label();
void chk_opcode();
void READ_LINE();
void PASS1();
void PASS2();
struct optab {
char code[10], objcode[10];
} myoptab[3] = {
{"LDA", "00"},
{"JMP", "01"},
{"STA", "02"}
};
struct symtab {
char symbol[10];
int addr;
} mysymtab[10];
printf("LOCATION LABEL\tOPERAND\tOPCODE\n");
printf("____________________________________\n");
READ_LINE();
if (!strcmp(opcode, "START")) {
startaddr = atoi(operand);
locctr = startaddr;
strcpy(programname, label);
fclose(inter);
fclose(input);
}
PASS2: Second Pass of the Assembler
void PASS2() {
FILE *inter, *output;
char record[30], part[6], value[5];
int currtxtlen = 0, foundopcode, foundoperand, chk, operandaddr, recaddr = 0;
inter = fopen("inter.txt", "r");
if (inter == NULL) {
printf("Error: Cannot open inter.txt\n");
exit(1);
}
READ_LINE();
if (!strcmp(opcode, "START")) {
if (fgets(line, 20, inter) == NULL) {
strcpy(line, "END");
}
}
if (strlen(part) > 0) {
if ((currtxtlen + strlen(part)) <= 8) {
strcat(record, "^");
strcat(record, part);
currtxtlen += strlen(part);
} else {
printf("\nT^ %d ^%d %s", recaddr, currtxtlen, record);
fprintf(output, "\nT^ %d ^%d %s", recaddr, currtxtlen, record);
recaddr += currtxtlen;
currtxtlen = strlen(part);
strcpy(record, "^");
strcat(record, part);
}
}
}
return 0;
}
Output:
Conclusion:
The two-pass assembler is a common technique for translating assembly code into machine code. The
first pass builds a symbol table with labels and addresses, while the second pass resolves the labels to
their addresses and generates the final machine code.