Advertisement
Bewin

passTwo

Sep 29th, 2024 (edited)
151
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.40 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4.  
  5. // Function to perform the Pass Two of the assembler process
  6. void passTwo(char label[10], char opcode[10], char operand[10], char code[10], char mnemonic[3])
  7. {
  8.     FILE *f1, *f2, *f3, *f4, *f5;
  9.     int locctr, start, length, recordLength = 0;
  10.     char textRecord[70] = "";  // Holds the contents of the current text record
  11.     int textStartAddr;  // Tracks the starting address of the current text record
  12.  
  13.     // Open all necessary files for reading and writing
  14.     if ((f1 = fopen("intermediate.txt", "r")) == NULL ||
  15.         (f2 = fopen("optab.txt", "r")) == NULL ||
  16.         (f3 = fopen("symtab.txt", "r")) == NULL ||
  17.         (f4 = fopen("output.txt", "w")) == NULL ||
  18.         (f5 = fopen("length.txt", "r")) == NULL)
  19.     {
  20.         printf("Error opening one of the files.\n");
  21.         exit(1);
  22.     }
  23.  
  24.     // Read the program's starting label, opcode, and operand, then the program length
  25.     fscanf(f1, "%s\t%s\t%s", label, opcode, operand);
  26.     fscanf(f5, "%d", &length);
  27.  
  28.     // If the first opcode is "START", initialize the program's starting address
  29.     if (strcmp(opcode, "START") == 0) {
  30.         start = atoi(operand);  // Convert starting address to an integer
  31.         fprintf(f4, "H^%s^%06d^%02d\n", label, start, length);  // Write header record
  32.         fscanf(f1, "%X\t%s\t%s\t%s", &locctr, label, opcode, operand);  // Read next line
  33.     } else {
  34.         locctr = 0;  // If no START directive, start at address 0
  35.     }
  36.  
  37.     textStartAddr = locctr;  // Initialize text record start address
  38.  
  39.     // Main loop to process each line until encountering the "END" opcode
  40.     while (strcmp(opcode, "END") != 0) {
  41.         rewind(f2);  // Reset optab file pointer to the beginning
  42.         int found = 0;
  43.         char objectCode[10] = "";  // String to hold generated object code
  44.  
  45.         // Search for the opcode in the optab to get its machine code
  46.         while (fscanf(f2, "%s\t%s", code, mnemonic) != EOF) {
  47.             if (strcmp(opcode, code) == 0) {  // Match found in optab
  48.                 if (strcmp(operand, "-") != 0) {  // If operand exists
  49.                     rewind(f3);  // Reset symtab file pointer to search for operand
  50.                     char symbol[10];
  51.                     int address;
  52.  
  53.                     // Search for the operand's address in the symtab
  54.                     while (fscanf(f3, "%s\t%X", symbol, &address) != EOF) {
  55.                         if (strcmp(operand, symbol) == 0) {  // Match found in symtab
  56.                             sprintf(objectCode, "%s%04X^", mnemonic, address);  // Format object code
  57.                             recordLength += 3;
  58.                             found = 1;
  59.                             break;
  60.                         }
  61.                     }
  62.                 } else {  // If no operand, use 0000 as the address
  63.                     sprintf(objectCode, "%s0000^", mnemonic);
  64.                     recordLength += 3;
  65.                     found = 1;
  66.                 }
  67.                 break;
  68.             }
  69.         }
  70.  
  71.         // Handle cases where the opcode is "WORD" or "BYTE"
  72.         if (!found) {
  73.             if (strcmp(opcode, "WORD") == 0) {  // For WORD, convert operand to object code
  74.                 sprintf(objectCode, "%06d^", atoi(operand));
  75.                 recordLength += 3;
  76.             } else if (strcmp(opcode, "BYTE") == 0) {  // For BYTE, process character or hex constants
  77.                 if (operand[0] == 'C') {  // If BYTE operand is a character
  78.                     for (int i = 2; i < strlen(operand) - 1; i++) {
  79.                         sprintf(objectCode + strlen(objectCode), "%02X", operand[i]);  // Convert to ASCII hex
  80.                         recordLength++;
  81.                     }
  82.                     strcat(objectCode, "^");
  83.                 } else if (operand[0] == 'X') {  // If BYTE operand is a hex constant
  84.                     strcat(objectCode, operand + 2);  // Append hex digits to object code
  85.                     strcat(objectCode, "^");
  86.                     recordLength += (strlen(operand) - 3) / 2;
  87.                 }
  88.             }
  89.         }
  90.  
  91.         // Check if the current object code will exceed max record length (1E in hex, or 30 in decimal)
  92.         if (recordLength > 30) {
  93.             // Write the current text record to output and start a new record
  94.             fprintf(f4, "T^%06X^%02llX^%s\n", textStartAddr, recordLength - strlen(objectCode) / 2, textRecord);
  95.             textStartAddr = locctr;  // Reset text start address for new record
  96.             strcpy(textRecord, "");  // Clear text record
  97.             recordLength = strlen(objectCode) / 2;  // Reset record length
  98.         }
  99.  
  100.         strcat(textRecord, objectCode);  // Add the generated object code to the text record
  101.  
  102.         // Read the next line in the intermediate file
  103.         fscanf(f1, "%X\t%s\t%s\t%s", &locctr, label, opcode, operand);
  104.     }
  105.  
  106.     // Write the final text record to the output file
  107.     fprintf(f4, "T^%06X^%02X^%s\n", textStartAddr, recordLength, textRecord);
  108.  
  109.     // Write the end record, specifying the program start address
  110.     fprintf(f4, "E^%06d\n", start);
  111.  
  112.     // Close all opened files
  113.     fclose(f1); fclose(f2); fclose(f3); fclose(f4); fclose(f5);
  114.  
  115.     printf("Pass 2 completed. Object code generated in output.txt\n");  // Confirmation message
  116. }
  117.  
  118. int main()
  119. {
  120.     char label[10], opcode[10], operand[10];
  121.     char code[10], mnemonic[3];
  122.  
  123.     // Call the Pass Two function to generate object code
  124.     passTwo(label, opcode, operand, code, mnemonic);
  125.     return 0;
  126. }
  127.  
  128.  
  129.  
  130. /*
  131. ---------------------------
  132.     intermediate.txt
  133. ---------------------------
  134.     SORT    START   1000
  135. 1000    -   LDA NUM1
  136. 1003    -   COMP    NUM2
  137. 1006    -   JLT SKIP
  138. 1009    -   LDA NUM1
  139. 100C    -   STA TEMP
  140. 100F    -   LDA NUM2
  141. 1012    -   STA NUM1
  142. 1015    -   LDA TEMP
  143. 1018    -   STA NUM2
  144. 101B    SKIP    J   SKIP
  145. 101E    NUM1    WORD    5
  146. 1021    NUM2    WORD    3
  147. 1024    TEMP    WORD    0
  148. 1027    -   END SORT
  149.  
  150.  
  151. ---------------------------
  152.         optab.txt
  153. ---------------------------
  154. LDA 00
  155. STA 0C
  156. COMP    28
  157. JLT 38
  158. J   3C
  159.  
  160.  
  161. ---------------------------
  162.         symtab.txt
  163. ---------------------------
  164. SKIP    101B
  165. NUM1    101E
  166. NUM2    1021
  167. TEMP    1024
  168.  
  169.  
  170.  
  171. ---------------------------
  172.         length.txt
  173. ---------------------------
  174. 27
  175.  
  176.  
  177. ---------------------------
  178.         output.txt
  179. ---------------------------
  180. H^SORT^001000^27
  181. T^001000^1E^00101E^281021^38101B^00101E^0C1024^001021^0C101E^001024^0C1021^3C101B^
  182. T^00101E^09^000005^000003^000000^
  183. E^001000
  184. */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement