Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- // Function to perform the Pass Two of the assembler process
- void passTwo(char label[10], char opcode[10], char operand[10], char code[10], char mnemonic[3])
- {
- FILE *f1, *f2, *f3, *f4, *f5;
- int locctr, start, length, recordLength = 0;
- char textRecord[70] = ""; // Holds the contents of the current text record
- int textStartAddr; // Tracks the starting address of the current text record
- // Open all necessary files for reading and writing
- if ((f1 = fopen("intermediate.txt", "r")) == NULL ||
- (f2 = fopen("optab.txt", "r")) == NULL ||
- (f3 = fopen("symtab.txt", "r")) == NULL ||
- (f4 = fopen("output.txt", "w")) == NULL ||
- (f5 = fopen("length.txt", "r")) == NULL)
- {
- printf("Error opening one of the files.\n");
- exit(1);
- }
- // Read the program's starting label, opcode, and operand, then the program length
- fscanf(f1, "%s\t%s\t%s", label, opcode, operand);
- fscanf(f5, "%d", &length);
- // If the first opcode is "START", initialize the program's starting address
- if (strcmp(opcode, "START") == 0) {
- start = atoi(operand); // Convert starting address to an integer
- fprintf(f4, "H^%s^%06d^%02d\n", label, start, length); // Write header record
- fscanf(f1, "%X\t%s\t%s\t%s", &locctr, label, opcode, operand); // Read next line
- } else {
- locctr = 0; // If no START directive, start at address 0
- }
- textStartAddr = locctr; // Initialize text record start address
- // Main loop to process each line until encountering the "END" opcode
- while (strcmp(opcode, "END") != 0) {
- rewind(f2); // Reset optab file pointer to the beginning
- int found = 0;
- char objectCode[10] = ""; // String to hold generated object code
- // Search for the opcode in the optab to get its machine code
- while (fscanf(f2, "%s\t%s", code, mnemonic) != EOF) {
- if (strcmp(opcode, code) == 0) { // Match found in optab
- if (strcmp(operand, "-") != 0) { // If operand exists
- rewind(f3); // Reset symtab file pointer to search for operand
- char symbol[10];
- int address;
- // Search for the operand's address in the symtab
- while (fscanf(f3, "%s\t%X", symbol, &address) != EOF) {
- if (strcmp(operand, symbol) == 0) { // Match found in symtab
- sprintf(objectCode, "%s%04X^", mnemonic, address); // Format object code
- recordLength += 3;
- found = 1;
- break;
- }
- }
- } else { // If no operand, use 0000 as the address
- sprintf(objectCode, "%s0000^", mnemonic);
- recordLength += 3;
- found = 1;
- }
- break;
- }
- }
- // Handle cases where the opcode is "WORD" or "BYTE"
- if (!found) {
- if (strcmp(opcode, "WORD") == 0) { // For WORD, convert operand to object code
- sprintf(objectCode, "%06d^", atoi(operand));
- recordLength += 3;
- } else if (strcmp(opcode, "BYTE") == 0) { // For BYTE, process character or hex constants
- if (operand[0] == 'C') { // If BYTE operand is a character
- for (int i = 2; i < strlen(operand) - 1; i++) {
- sprintf(objectCode + strlen(objectCode), "%02X", operand[i]); // Convert to ASCII hex
- recordLength++;
- }
- strcat(objectCode, "^");
- } else if (operand[0] == 'X') { // If BYTE operand is a hex constant
- strcat(objectCode, operand + 2); // Append hex digits to object code
- strcat(objectCode, "^");
- recordLength += (strlen(operand) - 3) / 2;
- }
- }
- }
- // Check if the current object code will exceed max record length (1E in hex, or 30 in decimal)
- if (recordLength > 30) {
- // Write the current text record to output and start a new record
- fprintf(f4, "T^%06X^%02llX^%s\n", textStartAddr, recordLength - strlen(objectCode) / 2, textRecord);
- textStartAddr = locctr; // Reset text start address for new record
- strcpy(textRecord, ""); // Clear text record
- recordLength = strlen(objectCode) / 2; // Reset record length
- }
- strcat(textRecord, objectCode); // Add the generated object code to the text record
- // Read the next line in the intermediate file
- fscanf(f1, "%X\t%s\t%s\t%s", &locctr, label, opcode, operand);
- }
- // Write the final text record to the output file
- fprintf(f4, "T^%06X^%02X^%s\n", textStartAddr, recordLength, textRecord);
- // Write the end record, specifying the program start address
- fprintf(f4, "E^%06d\n", start);
- // Close all opened files
- fclose(f1); fclose(f2); fclose(f3); fclose(f4); fclose(f5);
- printf("Pass 2 completed. Object code generated in output.txt\n"); // Confirmation message
- }
- int main()
- {
- char label[10], opcode[10], operand[10];
- char code[10], mnemonic[3];
- // Call the Pass Two function to generate object code
- passTwo(label, opcode, operand, code, mnemonic);
- return 0;
- }
- /*
- ---------------------------
- intermediate.txt
- ---------------------------
- SORT START 1000
- 1000 - LDA NUM1
- 1003 - COMP NUM2
- 1006 - JLT SKIP
- 1009 - LDA NUM1
- 100C - STA TEMP
- 100F - LDA NUM2
- 1012 - STA NUM1
- 1015 - LDA TEMP
- 1018 - STA NUM2
- 101B SKIP J SKIP
- 101E NUM1 WORD 5
- 1021 NUM2 WORD 3
- 1024 TEMP WORD 0
- 1027 - END SORT
- ---------------------------
- optab.txt
- ---------------------------
- LDA 00
- STA 0C
- COMP 28
- JLT 38
- J 3C
- ---------------------------
- symtab.txt
- ---------------------------
- SKIP 101B
- NUM1 101E
- NUM2 1021
- TEMP 1024
- ---------------------------
- length.txt
- ---------------------------
- 27
- ---------------------------
- output.txt
- ---------------------------
- H^SORT^001000^27
- T^001000^1E^00101E^281021^38101B^00101E^0C1024^001021^0C101E^001024^0C1021^3C101B^
- T^00101E^09^000005^000003^000000^
- E^001000
- */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement