ASMParser.c 0000600 0061730 0023423 00000040754 14237033174 013013 0 ustar jordanha23 Others #include "ASMParser.h" #include "SymbolTable.h" // On my honor: // // - I have not discussed the C language code in my program with // anyone other than my instructor or the teaching assistants // assigned to this course. // // - I have not used C language code obtained from another student, // the Internet, or any other unauthorized source, either modified // or unmodified. // // - If any C language code or documentation used in my program // was obtained from an authorized source, such as a text book or // course notes, that has been clearly noted with a proper citation // in the comments of my program. // // - I have not designed this program in such a way as to defeat or // interfere with the normal operation of the grading code. // // <Jordan Harrington> // <jordanha23> /*** Add include directives for here as needed. ***/ #include <inttypes.h> #include <stdbool.h> #include <string.h> #include <stdlib.h> #include <stdio.h> #include <assert.h> static struct { char *mnem; char *address; } registers[] = { {"$at", "00001"}, {"$a0", "00100"}, {"$a1", "00101"}, {"$a2", "00110"}, {"$a3", "00111"}, {"$t0", "01000"}, {"$t1", "01001"}, {"$t2", "01010"}, {"$t3", "01011"}, {"$t4", "01100"}, {"$t5", "01101"}, {"$t6", "01110"}, {"$t7", "01111"}, {"$t8", "11000"}, {"$t9", "11001"}, {"$s0", "10000"}, {"$s1", "10001"}, {"$s2", "10010"}, {"$s3", "10011"}, {"$s4", "10100"}, {"$s5", "10101"}, {"$s6", "10110"}, {"$s7", "10111"}, {"$v0", "00010"}, {"$v1", "00011"}, {"$zero", "00000"}, {"$k0", "11010"}, {"$k1", "11011"}, {NULL, 0}}; static struct { char *mnem; char *opCode; } op[] = { {"lw", "100011"}, {"sub", "000000"}, {"add", "000000"}, {"nor", "000000"}, {"mult", "000000"}, {"syscall", "000000"}, {"mul", "011100"}, {"slti", "001010"}, {"lui", "001111"}, {"addi", "001000"}, {"la", "001000"}, {"beq", "000100"}, {"bne", "000101"}, {"sw", "101011"}, {"nop", "000000"}, {"sll", "000000"}, {"sra", "000000"}, {"srav", "000000"}, {"slt", "000000"}, {"blt", "101010"}, {"j", "000010"}, {"addu", "000000"}, {"move", "000000"}, {"addiu", "001001"}, {"li", "001001"}, {"blez", "000110"}, {"bgtz", "000111"}, {NULL, 0}}; static struct { char *mnem; char *funcCode; } func[] = { {"sub", "100010"}, {"slt", "101010"}, {"addu", "100001"}, {"move", "100001"}, {"sra", "000011"}, {"srav", "000111"}, {"add", "100000"}, {"mult", "011000"}, {"nor", "100111"}, {"mul", "000010"}, {"syscall", "001100"}, {"sll", "000000"}, {"nop", "000000"}, {NULL, 0}}; static struct { char *mnem; char *mType; } type[] = { {"sub", "r"}, {"nor", "r"}, {"add", "r"}, {"syscall", "r"}, {"mul", "r"}, {"mult", "s"}, {"lw", "i"}, {"lui", "i"}, {"addi", "i"}, {"slti", "i"}, {"la", "i"}, {"beq", "i"}, {"bne", "i"}, {"sw", "i"}, {"nop", "r"}, {"sll", "r"}, {"sra", "r"}, {"srav", "r"}, {"slt", "r"}, {"blt", "r"}, {"j", "ju"}, {"addu", "r"}, {"move", "r"}, {"addiu", "i"}, {"li", "i"}, {"blez", "i"}, {"bgtz", "i"}, {NULL, 0}}; #define REG_LENGTH 4 #define OP_FUNC_CODE_LENGTH 7 #define REG_ADD_LENGTH 6 #define TARGET_LENGTH 27 static bool blt = false; char *findReg(char *inp); char *findFunc(char *inp); char *findOp(char *inp); char *findType(char *inp); uint8_t binaryToDec(char *addy); uint16_t findInstructionNum(char *word); uint16_t findImm(char *word); char *unDecToBinary(char *word); ParseResult *parseASM(const char *const pASM, uint16_t instructionNumber) { // Create ParseResult ParseResult *res = calloc(1, sizeof(ParseResult)); res->ASMInstruction = calloc(strlen(pASM) + 1, sizeof(char)); strcpy(res->ASMInstruction, pASM); res->rd = 0; res->rs = 0; res->rt = 0; char *line = calloc(strlen(pASM) + 1, sizeof(char)), *str[4]; strcpy(line, pASM); // Grabs arguments int i = 0; str[i] = strtok(line, " ,\t"); while (str[i++]) str[i] = strtok(NULL, " ,\t"); // Sets mnemonic for type checking res->Mnemonic = calloc(strlen(str[0]) + 1, sizeof(char)); strcpy(res->Mnemonic, (blt) ? "bne" : str[0]); // Allocates fields of ParseResult based on instruction type if (!strcmp(findType(res->Mnemonic), "ju")) res->Opcode = calloc(OP_FUNC_CODE_LENGTH, sizeof(char)); else if (!strcmp(findType(res->Mnemonic), "i")) { res->RT = calloc(REG_ADD_LENGTH, sizeof(char)); res->RS = calloc(REG_ADD_LENGTH, sizeof(char)); res->Opcode = calloc(OP_FUNC_CODE_LENGTH, sizeof(char)); res->rtName = calloc(REG_LENGTH, sizeof(char)); res->rsName = calloc(REG_LENGTH, sizeof(char)); res->IMM = calloc(IMM_LENGTH, sizeof(char)); } else if (!strcmp(findType(res->Mnemonic), "r")) { res->rtName = calloc(REG_LENGTH, sizeof(char)); res->rsName = calloc(REG_LENGTH, sizeof(char)); res->rdName = calloc(REG_LENGTH, sizeof(char)); res->Funct = calloc(OP_FUNC_CODE_LENGTH, sizeof(char)); res->Opcode = calloc(OP_FUNC_CODE_LENGTH, sizeof(char)); res->RT = calloc(REG_ADD_LENGTH, sizeof(char)); res->RS = calloc(REG_ADD_LENGTH, sizeof(char)); res->RD = calloc(REG_ADD_LENGTH, sizeof(char)); res->shamt = calloc(REG_ADD_LENGTH, sizeof(char)); } else if (!strcmp(findType(res->Mnemonic), "s")) { res->rtName = calloc(REG_LENGTH, sizeof(char)); res->rsName = calloc(REG_LENGTH, sizeof(char)); res->RT = calloc(REG_ADD_LENGTH, sizeof(char)); res->RS = calloc(REG_ADD_LENGTH, sizeof(char)); res->RD = calloc(REG_ADD_LENGTH, sizeof(char)); res->Funct = calloc(OP_FUNC_CODE_LENGTH, sizeof(char)); res->Opcode = calloc(OP_FUNC_CODE_LENGTH, sizeof(char)); } // R-type if (!strcmp(res->Mnemonic, "mul") || !strcmp(str[0], "sub") || !strcmp(str[0], "add") || !strcmp(str[0], "nor") || !strcmp(str[0], "slt") || !strcmp(str[0], "addu")) { strcpy(res->rdName, str[1]); strcpy(res->rsName, str[2]); strcpy(res->rtName, str[3]); strcpy(res->shamt, "00000"); strcpy(res->RD, findReg(str[1])); strcpy(res->RS, findReg(str[2])); strcpy(res->RT, findReg(str[3])); strcpy(res->Funct, findFunc(str[0])); strcpy(res->Opcode, findOp(str[0])); res->rd = binaryToDec(res->RD); res->rs = binaryToDec(res->RS); res->rt = binaryToDec(res->RT); } else if (!strcmp(res->Mnemonic, "sll") || !strcmp(res->Mnemonic, "sra")) { strcpy(res->rdName, str[1]); strcpy(res->rtName, str[2]); strncpy(res->shamt, &decToBinary(str[3])[11], 6); strcpy(res->RD, findReg(str[1])); strcpy(res->RT, findReg(str[2])); strcpy(res->RS, "00000"); strcpy(res->Funct, findFunc(str[0])); strcpy(res->Opcode, findOp(str[0])); res->rd = binaryToDec(res->RD); res->rt = binaryToDec(res->RT); } else if (!strcmp(res->Mnemonic, "move")) { strcpy(res->rdName, str[1]); strcpy(res->rtName, str[2]); strcpy(res->shamt, "00000"); strcpy(res->RD, findReg(str[1])); strcpy(res->RT, findReg(str[2])); strcpy(res->RS, findReg("$zero")); strcpy(res->Funct, findFunc(str[0])); strcpy(res->Opcode, findOp(str[0])); res->rd = binaryToDec(res->RD); res->rs = binaryToDec(res->RS); res->rt = binaryToDec(res->RT); } else if (!strcmp(res->Mnemonic, "srav")) { strcpy(res->rdName, str[1]); strcpy(res->rsName, str[3]); strcpy(res->rtName, str[2]); strcpy(res->shamt, "00000"); strcpy(res->RD, findReg(str[1])); strcpy(res->RS, findReg(str[3])); strcpy(res->RT, findReg(str[2])); strcpy(res->Funct, findFunc(str[0])); strcpy(res->Opcode, findOp(str[0])); res->rd = binaryToDec(res->RD); res->rs = binaryToDec(res->RS); res->rt = binaryToDec(res->RT); } else if (!strcmp(res->Mnemonic, "syscall")) { strcpy(res->RD, "00000"); strcpy(res->RS, "00000"); strcpy(res->RT, "00000"); strcpy(res->shamt, "00000"); strcpy(res->Funct, findFunc(str[0])); strcpy(res->Opcode, findOp(str[0])); } else if (!strcmp(res->Mnemonic, "nop")) { strcpy(res->shamt, "00000"); strcpy(res->RD, findReg("$zero")); strcpy(res->RT, findReg("$zero")); strcpy(res->RS, "00000"); strcpy(res->Funct, findFunc(str[0])); strcpy(res->Opcode, findOp(str[0])); res->rd = binaryToDec(res->RD); res->rt = binaryToDec(res->RT); } else if (!strcmp(res->Mnemonic, "blt")) { strcpy(res->rdName, "$at"); strcpy(res->rsName, str[1]); strcpy(res->rtName, str[2]); strcpy(res->shamt, "00000"); strcpy(res->RD, findReg("$at")); strcpy(res->RS, findReg(str[1])); strcpy(res->RT, findReg(str[2])); strcpy(res->Funct, findFunc("slt")); strcpy(res->Opcode, findOp("slt")); res->rd = binaryToDec(res->RD); res->rs = binaryToDec(res->RS); res->rt = binaryToDec(res->RT); blt = true; } // I-type else if (!strcmp(res->Mnemonic, "blez") || !strcmp(res->Mnemonic, "bgtz")) { strcpy(res->rsName, str[1]); strcpy(res->RS, findReg(str[1])); strcpy(res->RT, findReg("$zero")); strcpy(res->Opcode, findOp(str[0])); res->rs = binaryToDec(res->RS); res->rt = binaryToDec(res->RT); int16_t symbolInstructNum = findInstructionNum(str[2]); int16_t i = (symbolInstructNum - instructionNumber) - 1; char *imm = calloc(TARGET_LENGTH, sizeof(char)); snprintf(imm, sizeof(char *), "%d", i); char *bin = decToBinary(imm); strcpy(res->IMM, bin); free(bin); free(imm); res->Imm = i; } else if (!strcmp(res->Mnemonic, "bne") || !strcmp(res->Mnemonic, "beq")) { if (blt) { strcpy(res->rsName, "$at"); strcpy(res->RS, findReg("$at")); strcpy(res->RT, findReg("$zero")); strcpy(res->Opcode, findOp("bne")); res->rs = binaryToDec(res->RS); res->rt = binaryToDec(res->RT); int16_t symbolInstructNum = findInstructionNum(str[3]); int16_t i = (symbolInstructNum - instructionNumber); if (i < 0) i--; char *imm = calloc(TARGET_LENGTH, sizeof(char)); snprintf(imm, sizeof(char *), "%d", i); char *bin = decToBinary(imm); strcpy(res->IMM, bin); free(bin); free(imm); res->Imm = i; blt = false; } else { strcpy(res->rsName, str[1]); strcpy(res->rtName, str[2]); strcpy(res->RS, findReg(str[1])); strcpy(res->RT, findReg(str[2])); strcpy(res->Opcode, findOp(str[0])); res->rs = binaryToDec(res->RS); res->rt = binaryToDec(res->RT); int16_t symbolInstructNum = findInstructionNum(str[3]); int16_t i = (symbolInstructNum - instructionNumber) - 1; char *imm = calloc(TARGET_LENGTH, sizeof(char)); snprintf(imm, sizeof(char *), "%d", i); char *bin = decToBinary(imm); strcpy(res->IMM, bin); free(bin); free(imm); res->Imm = i; } } else if (!strcmp(res->Mnemonic, "li")) { strcpy(res->rtName, str[1]); strcpy(res->RT, findReg(str[1])); strcpy(res->RS, findReg("$zero")); strcpy(res->Opcode, findOp(str[0])); res->rs = binaryToDec(res->RS); res->rt = binaryToDec(res->RT); char *bin = unDecToBinary(str[2]); strcpy(res->IMM, bin); free(bin); res->Imm = strtoul(str[2], NULL, 10); res->rs = binaryToDec(res->RS); res->rt = binaryToDec(res->RT); } else if (!strcmp(res->Mnemonic, "la")) { strcpy(res->rtName, str[1]); strcpy(res->RT, findReg(str[1])); strcpy(res->RS, findReg("$zero")); strcpy(res->Opcode, findOp(str[0])); res->rs = binaryToDec(res->RS); res->rt = binaryToDec(res->RT); uint16_t i = findImm(str[2]); char *imm = calloc(TARGET_LENGTH, sizeof(char)); snprintf(imm, sizeof(char *), "%d", i); char *bin = decToBinary(imm); strcpy(res->IMM, bin); free(bin); free(imm); res->Imm = i; } else if (!strcmp(res->Mnemonic, "addi") || !strcmp(res->Mnemonic, "slti") || !strcmp(res->Mnemonic, "addiu")) { strcpy(res->rtName, str[1]); strcpy(res->rsName, str[2]); strcpy(res->RT, findReg(str[1])); strcpy(res->RS, findReg(str[2])); strcpy(res->Opcode, findOp(str[0])); char *bin; if (!strcmp(res->Mnemonic, "addiu")) bin = unDecToBinary(str[3]); else bin = decToBinary(str[3]); strcpy(res->IMM, bin); free(bin); if (!strcmp(res->Mnemonic, "addiu")) res->Imm = strtoul(str[3], NULL, 10); else res->Imm = atol(str[3]); res->rs = binaryToDec(res->RS); res->rt = binaryToDec(res->RT); } else if (!strcmp(res->Mnemonic, "lw") || !strcmp(res->Mnemonic, "sw")) { uint16_t x = 0; bool lwLabel = false; char *trash = calloc(1, sizeof(char)), offset[50], regi[4]; if (!strcmp(res->Mnemonic, "lw")) if ((x = findImm(str[2])) != 0) lwLabel = true; if (!lwLabel) { sscanf(str[2], " %[^(]%c %[^)]", offset, trash, regi); strcpy(res->rtName, str[1]); strcpy(res->rsName, regi); strcpy(res->RT, findReg(str[1])); strcpy(res->RS, findReg(regi)); strcpy(res->Opcode, findOp(str[0])); char *bin = decToBinary(offset); strcpy(res->IMM, bin); free(bin); res->Imm = atol(offset); res->rs = binaryToDec(res->RS); res->rt = binaryToDec(res->RT); free(trash); } else { strcpy(res->rtName, str[1]); strcpy(res->RT, findReg(str[1])); strcpy(res->Opcode, findOp(str[0])); strcpy(res->RS, findReg("$zero")); char *imm = calloc(TARGET_LENGTH, sizeof(char)); snprintf(imm, sizeof(char *), "%d", x); char *bin = decToBinary(imm); strcpy(res->IMM, bin); free(bin); free(imm); res->Imm = x; } } else if (!strcmp(res->Mnemonic, "lui")) { strcpy(res->rtName, str[1]); strcpy(res->RT, findReg(str[1])); strcpy(res->Opcode, findOp(str[0])); strcpy(res->RS, "00000"); free(res->rsName); res->rsName = NULL; char *bin = decToBinary(str[2]); strcpy(res->IMM, bin); free(bin); res->Imm = atol(str[2]); res->rt = binaryToDec(res->RT); } // S-type else if (!strcmp(res->Mnemonic, "mult")) { strcpy(res->rsName, str[1]); strcpy(res->rtName, str[2]); strcpy(res->RS, findReg(str[1])); strcpy(res->RT, findReg(str[2])); strcpy(res->Funct, findFunc(str[0])); strcpy(res->Opcode, findOp(str[0])); strcpy(res->RD, "00000"); res->rs = binaryToDec(res->RS); res->rt = binaryToDec(res->RT); } // J-type else if (!strcmp(res->Mnemonic, "j")) { strcpy(res->Opcode, findOp(str[0])); int16_t symbolInstructNum = findInstructionNum(str[1]); if (symbolInstructNum) symbolInstructNum--; char *imm = calloc(1, sizeof(char)); snprintf(imm, sizeof(char *), "%d", symbolInstructNum); char *bin = decToBinary26(imm); res->Target = bin; free(imm); } free(line); return res; } uint8_t binaryToDec(char *addy) { int dec = 0; while (*addy) { dec *= 2; if (*addy == '1') dec++; addy++; } return dec; } char *findReg(char *inp) { int i = -1; while (registers[++i].mnem) if (!strcmp(inp, registers[i].mnem)) return registers[i].address; return NULL; } char *findFunc(char *inp) { int i = -1; while (func[++i].mnem) if (!strcmp(inp, func[i].mnem)) return func[i].funcCode; return NULL; } char *findType(char *inp) { int i = -1; while (type[++i].mnem) if (!strcmp(inp, type[i].mnem)) return type[i].mType; return NULL; } char *findOp(char *inp) { int i = -1; while (op[++i].mnem) if (!strcmp(inp, op[i].mnem)) return op[i].opCode; return NULL; } uint16_t findInstructionNum(char *word) { int i = -1; while (textSymbols[++i].key) if (!strcmp(word, textSymbols[i].key)) return textSymbols[i].instructionNum; return 0; } DATAParser.c 0000600 0061730 0023423 00000005772 14237031432 013100 0 ustar jordanha23 Others #include "DATAParser.h" #include "SymbolTable.h" #include <inttypes.h> #include <stdbool.h> #include <string.h> #include <stdint.h> #include <stdlib.h> #include <stdio.h> #include <assert.h> #define MAX_LINE_LENGTH 257 #define LINE_LENGTH 34 #define IMM_LENGTH 17 char *stringToBinary(char *text); char *decToBinary32(char *dec); /** Breaks up given MIPS32 assembly instruction and creates a proper * char* storing the machine code for data output. * * Pre: pASM points to an array holding the bits (as chars) of variables * defined within the program * * Returns: * A pointer to a proper char* representation of binary machine code */ void parseDATA(char pDATA[], int count) { char *binary = calloc((MAX_LINE_LENGTH * 2), sizeof(char)), *name = calloc(MAX_LINE_LENGTH, sizeof(char)), value[MAX_LINE_LENGTH], type[8]; sscanf(pDATA, "%s %s %s", name, type, value); free(name); dataSymbols[count].type = calloc(MAX_LINE_LENGTH, sizeof(char)); strcpy(dataSymbols[count].type, type); if (!strcmp(type, ".asciiz")) { char *text = strchr(pDATA, '"'), *bin = stringToBinary(text); strcpy(binary, bin); free(bin); } if (!strcmp(type, ".word")) { char *colon = strstr(value, ":"), *comma = strstr(value, ","); if (colon) { char *v = strtok(value, ":"), *s = strtok(NULL, ":"), *bin = decToBinary32(v); v[strcspn(v, "\n")] = 0; int size = atoi(s) - 1, i = 0; strcpy(binary, decToBinary32(value)); strcat(binary, "\n"); while (i++ < size) strcat(binary, bin), strcat(binary, "\n"); free(bin); } else if (comma) { char *tok = strtok(pDATA, " ,\t"); int ignore = 0; while (tok != NULL) { if (ignore++ < 2) tok = strtok(NULL, " ,\t"); else { tok[strcspn(tok, ",")] = 0; tok[strcspn(tok, "\n")] = 0; char *bin = decToBinary32(tok); strcat(binary, bin); strcat(binary, "\n"); free(bin); tok = strtok(NULL, " ,\t"); } } free(tok); } else { char *bin = decToBinary32(value); strcpy(binary, bin); strcat(binary, "\n"); free(bin); } } dataSymbols[count].binary = binary; } char *stringToBinary(char *text) { if (!text) return NULL; char *binary = calloc(MAX_LINE_LENGTH * 8, sizeof(char)); binary[0] = '\0'; int count = 0; for (size_t i = 0; i < strlen(text) + 1; i++) { if (text[i] == '"' || text[i] == '\n') continue; for (int j = 7; j >= 0; --j) strcat(binary, (text[i] & (1 << j)) ? "1" : "0"); if (!(count = !((count + 1) % 4) ? 0 : count + 1)) strcat(binary, "\n"); } return binary; } char *decToBinary32(char *dec) { int32_t n = atoi(dec), i = 0, s = 31; char *binaryNum = calloc(33, sizeof(char)); while (s >= 0) binaryNum[i++] = ((n >> s--) & 1) ? '1' : '0'; return binaryNum; } Parser.c 0000600 0061730 0023423 00000020730 14237034155 012442 0 ustar jordanha23 Others #include "ASMParser.h" #include "ParseResult.h" #include "DATAParser.h" #include "SymbolTable.h" #include <inttypes.h> #include <stdbool.h> #include <string.h> #include <stdlib.h> #include <stdio.h> #include <assert.h> #define MAX_LINE_LENGTH 257 void getTextSymbols(FILE *readF, uint16_t currOffset); void getDataSymbols(FILE *readF, uint16_t currOffset); int main(int args, char *files[]) { if (args > 2) { // Reads in input file and create output file FILE *readF = fopen(files[1], "r"); FILE *outF = fopen(files[2], "w"); // Checks for input file if (!readF) printf("Error: unable to create %s\n", files[1]); else { char *line = calloc(MAX_LINE_LENGTH, sizeof(char)), *dataSection = NULL; bool data = false, text = false, table = false; int instructionNum = 0; while (fgets(line, MAX_LINE_LENGTH - 1, readF)) { char lineCopy[MAX_LINE_LENGTH + 1]; strcpy(lineCopy, line); char instruction[MAX_LINE_LENGTH + 1]; strcpy(instruction, strtok(lineCopy, " ,\t")); instruction[strcspn(instruction, "\n")] = 0; char *type = findType(instruction); if (strcmp(instruction, "#") != 0 && strcmp(instruction, " ") != 0) { if (table) { free(type); free(line); fclose(outF); fclose(readF); return 0; } if (!strcmp(instruction, ".data")) { data = true; getDataSymbols(readF, ftell(readF)); continue; } if (!strcmp(instruction, ".text")) { text = true; getTextSymbols(readF, ftell(readF)); if ((table = (args == 4))) makeTable(outF); continue; } if (data) { int i = 0, x = 0, length = 0; while (dataSymbols[x].binary) length += strlen(dataSymbols[x++].binary) + 1; dataSection = calloc(length * 2, sizeof(char)); strcpy(dataSection, dataSymbols[0].binary); while (dataSymbols[++i].binary) { int prevLength = strlen(dataSymbols[i - 1].binary); char *prevType = dataSymbols[i - 1].type, *currType = dataSymbols[i].type; if (!strcmp(prevType, ".asciiz") && !strcmp(currType, ".word")) { int length = (prevLength < 33) ? prevLength : prevLength % 33, num_zero = 32 - length, x = 0; if (prevLength != 33) { while (x++ < num_zero) strcat(dataSection, "0"); strcat(dataSection, "\n"); } } strcat(dataSection, dataSymbols[i].binary); if ((prevLength + strlen(dataSymbols[i].binary)) % 33 == 32) strcat(dataSection, "\n"); } int dataLen = strlen(dataSection), remainder, j = 0; if ((remainder = (dataLen % 33)) != 0) { while (j++ < (32 - (dataLen % 33))) strcat(dataSection, "0"); strcat(dataSection, "\n"); } data = false; continue; } if (text) { if (type) { line[strcspn(line, "\n")] = 0; char *bltCopy; if (!strcmp(instruction, "blt")) { bltCopy = calloc(MAX_LINE_LENGTH + 1, sizeof(char)); strcpy(bltCopy, line); } ParseResult *asmI = parseASM(line, ++instructionNum); if (!strcmp(type, "r")) fprintf(outF, "%s%s%s%s%s%s\n", asmI->Opcode, asmI->RS, asmI->RT, asmI->RD, asmI->shamt, asmI->Funct); if (!strcmp(type, "i")) fprintf(outF, "%s%s%s%s\n", asmI->Opcode, asmI->RS, asmI->RT, asmI->IMM); if (!strcmp(type, "s")) fprintf(outF, "%s%s%s%s%s%s\n", asmI->Opcode, asmI->RS, asmI->RT, asmI->RD, asmI->RD, asmI->Funct); if (!strcmp(type, "ju")) fprintf(outF, "%s%s\n", asmI->Opcode, asmI->Target); if (!strcmp(asmI->Mnemonic, "blt")) { ParseResult *bltAsmi = parseASM(bltCopy, ++instructionNum); fprintf(outF, "%s%s%s%s\n", bltAsmi->Opcode, bltAsmi->RS, bltAsmi->RT, bltAsmi->IMM); free(bltAsmi); free(bltCopy); } clearResult(asmI); free(asmI); } continue; } } } fprintf(outF, "\n%s", dataSection); free(line); free(dataSection); fclose(outF); fclose(readF); } cleanTable(); } return 0; } void getDataSymbols(FILE *readF, uint16_t currOffset) { fseek(readF, currOffset, SEEK_SET); char *line = calloc(MAX_LINE_LENGTH, sizeof(char)); int count = 0, address = 8192; while (fgets(line, MAX_LINE_LENGTH - 1, readF)) { char lineCopyData[MAX_LINE_LENGTH + 1]; strcpy(lineCopyData, line); strcpy(dataSymbols[count].key, strtok(line, " ,\t")); dataSymbols[count].key[strcspn(dataSymbols[count].key, "\n")] = 0; if (!strcmp(dataSymbols[count].key, ".text")) break; if (!findType(dataSymbols[count].key) && strlen(dataSymbols[count].key) > 0) { dataSymbols[count].key[strcspn(dataSymbols[count].key, ":")] = 0; parseDATA(lineCopyData, count); dataSymbols[count].address = address; int binLength = strlen(dataSymbols[count++].binary); address += (binLength % 33 == 0) ? (4 * (binLength / 33)) : (4 * ((binLength / 33) + 1)); } } dataSymbols[count].binary = NULL; fseek(readF, currOffset, SEEK_SET); free(line); } void getTextSymbols(FILE *readF, uint16_t currOffset) { fseek(readF, currOffset, SEEK_SET); char *line = calloc(MAX_LINE_LENGTH, sizeof(char)); int count = 0, address = 0, instructionCount = 0; while (fgets(line, MAX_LINE_LENGTH, readF)) { char tSymbol[MAX_LINE_LENGTH + 1]; strcpy(tSymbol, strtok(line, " ,\t")); tSymbol[strcspn(tSymbol, "\n")] = 0; if (!findType(tSymbol) && strcmp(tSymbol, "") != 0 && strcmp(tSymbol, "#") != 0) { tSymbol[strcspn(tSymbol, ":")] = 0; textSymbols[count].key = calloc(MAX_LINE_LENGTH, sizeof(char)); strcpy(textSymbols[count].key, tSymbol); textSymbols[count].instructionNum = (strcmp(tSymbol, "main") == 0) ? instructionCount : (instructionCount + 1); address = (4 * instructionCount); textSymbols[count++].address = address; } if (findType(tSymbol)) instructionCount++; } textSymbols[count].key = NULL; textSymbols[count].instructionNum = 0; fseek(readF, currOffset, SEEK_SET); free(line); } ParseResult.c 0000600 0061730 0023423 00000006551 14236772524 013474 0 ustar jordanha23 Others #include "ParseResult.h" #include <stdlib.h> #include <string.h> static struct { char* mnem; char* mType; } type[] = { { "sub", "r" }, { "nor", "r" }, { "add", "r" }, { "syscall", "r" }, { "mul", "r" }, { "mult", "s" }, { "lw", "i" }, { "lui", "i" }, { "addi", "i" }, { "slti", "i" }, { "la", "i" }, { "beq", "i" }, { "bne", "i" }, { "sw", "i" }, { "nop", "r" }, { "sll", "r" }, { "sra", "r" }, { "srav", "r" }, { "slt", "r" }, { "blt", "r" }, { "j", "ju" }, { "addu", "r" }, { "move", "r" }, { "addiu", "i" }, { "li", "i" }, { "blez", "i" }, { "bgtz", "i" }, { NULL, 0 } }; /*** Add include directives for here as needed. ***/ char* clearType(char* inp); /** Frees the dynamic content of a ParseResult object. * * Pre: pPR points to a proper ParseResult object. * Post: All of the dynamically-allocated arrays in *pPR have been * deallocated; pointers are NULL, static fields are reset to * default values. * * Comments: * - The function has no information about whether *pPR has been * allocated dynamically, so it cannot risk attempting to * deallocate *pPR. * - The function is intended to provide the user with a simple * way to free memory; the user may or may not reuse *pPR. So, * the function does set the pointers in *pPR to NULL. */ void clearResult(ParseResult* const pPR) { if(pPR){ pPR->Imm = 0; pPR->rd = 0; pPR->rs = 0; pPR->rt = 0; if(!strcmp(clearType(pPR->Mnemonic), "ju")){ free(pPR->Opcode); free(pPR->Target); } if(!strcmp(clearType(pPR->Mnemonic), "i")){ free(pPR->RS); free(pPR->RT); free(pPR->rsName); free(pPR->rtName); free(pPR->Opcode); free(pPR->IMM); } if(!strcmp(clearType(pPR->Mnemonic), "r")){ free(pPR->rdName); free(pPR->rsName); free(pPR->rtName); free(pPR->Opcode); free(pPR->Funct); free(pPR->RD); free(pPR->RS); free(pPR->RT); free(pPR->shamt); } if(!strcmp(clearType(pPR->Mnemonic), "s")){ free(pPR->RS); free(pPR->RT); free(pPR->RD); free(pPR->rsName); free(pPR->rtName); free(pPR->Opcode); free(pPR->Funct); } } free(pPR->Mnemonic); free(pPR->ASMInstruction); } /** Prints the contents of a ParseResult object. * * Pre: Log is open on an output file. * pPR points to a proper ParseResult object. */ void printResult(FILE* Log, const ParseResult* const pPR) { fprintf(Log, "%s\n", pPR->ASMInstruction); fprintf(Log, " %s %s\n", pPR->Opcode, pPR->Mnemonic); fprintf(Log, " %2"PRIu8" %s", pPR->rd, pPR->rdName); if ( pPR->RD != NULL ) { fprintf(Log, " %s", pPR->RD); } fprintf(Log, "\n"); fprintf(Log, " %2"PRIu8" %s", pPR->rs, pPR->rsName); if ( pPR->RS != NULL ) { fprintf(Log, " %s", pPR->RS); } fprintf(Log, "\n"); fprintf(Log, " %2"PRIu8" %s", pPR->rt, pPR->rtName); if ( pPR->RT != NULL ) { fprintf(Log, " %s", pPR->RT); } fprintf(Log, "\n"); fprintf(Log, " %s\n", pPR->Funct); fprintf(Log, " %"PRId16"\n", pPR->Imm); if ( pPR->IMM != NULL ) { fprintf(Log, " %s", pPR->IMM); } fprintf(Log, "\n"); fprintf(Log, "\n"); } char* clearType(char* inp){ int i = -1; while(type[++i].mnem) if(!strcmp(inp, type[i].mnem)) return type[i].mType; return NULL; } SymbolTable.c 0000600 0061730 0023423 00000003323 14237027136 013423 0 ustar jordanha23 Others #include "SymbolTable.h" #include <inttypes.h> #include <stdbool.h> #include <string.h> #include <stdlib.h> #include <assert.h> DataSymbol dataSymbols[NUM_SYMBOLS] = {0}; TextSymbol textSymbols[NUM_SYMBOLS] = {0}; void makeTable(FILE *outF) { int x = -1, j = -1, i = 0; while (dataSymbols[i].binary) { char key[sizeof(dataSymbols[i].key) + 1]; j = -1; while (dataSymbols[i].key[++j] != 0) key[j] = dataSymbols[i].key[j]; fprintf(outF, "0x%08X\t%s\n", dataSymbols[i++].address, key); } while (textSymbols[++x].key != NULL) fprintf(outF, "0x%08X\t%s\n", textSymbols[x].address, textSymbols[x].key); } void cleanTable() { int i = -1, x = -1; while (dataSymbols[++i].binary) free(dataSymbols[i].binary), free(dataSymbols[i].type); while (textSymbols[++x].key) free(textSymbols[x].key); } char *decToBinary(char *dec) { int16_t n = atol(dec); int i = 0, s = 15; char *binaryNum = calloc(IMM_LENGTH, sizeof(char)); while (s >= 0) binaryNum[i++] = ((n >> s--) & 1) ? '1' : '0'; return binaryNum; } char *decToBinary26(char *dec) { int n = atoi(dec), i = 0, s = 25; char *binaryNum = calloc(27, sizeof(char)); while (s >= 0) binaryNum[i++] = ((n >> s--) & 1) ? '1' : '0'; return binaryNum; } char *unDecToBinary(char *dec) { uint16_t n; sscanf(dec, "%hd", &n); int i = 0, s = 15; char *binaryNum = calloc(IMM_LENGTH, sizeof(char)); while (s >= 0) binaryNum[i++] = ((n >> s--) & 1) ? '1' : '0'; return binaryNum; } uint16_t findImm(char *word) { int i = -1; while (dataSymbols[++i].binary) if (!strcmp(word, dataSymbols[i].key)) return dataSymbols[i].address; return 0; } ASMParser.h 0000600 0061730 0023423 00000001507 14236755613 013021 0 ustar jordanha23 Others #ifndef ASMPARSER_H #define ASMPARSER_H #include "ParseResult.h" char* findReg(char* inp); char* findFunc(char* inp); char* findOp(char* inp); char* findType(char* inp); uint8_t binaryToDec(char* addy); char* decToBinary(char* dec); /** Breaks up given MIPS32 assembly instruction and creates a proper * ParseResult object storing information about that instruction. * * Pre: pASM points to an array holding the bits (as chars) of a * syntactically valid assembly instruction, whose mnemonic is * one of the following: * * addi mul mult lui lw sub * * Returns: * A pointer to a proper ParseResult object whose fields have been * correctly initialized to correspond to the target of pASM. */ ParseResult* parseASM(const char* const pASM, uint16_t offset); #endif DATAParser.h 0000600 0061730 0023423 00000000660 14236755613 013111 0 ustar jordanha23 Others #ifndef DATAPARSER_H #define DATAPARSER_H /** Breaks up given MIPS32 assembly instruction and creates a proper * char* storing the machine code for data output. * * Pre: pASM points to an array holding the bits (as chars) of variables * defined within the program * * Returns: * A pointer to a proper char* representation of binary machine code */ void parseDATA(char pDATA[], int count); #endif ParseResult.h 0000600 0061730 0023423 00000006460 14236755613 013500 0 ustar jordanha23 Others #ifndef PARSERESULT_H #define PARSERESULT_H #include <inttypes.h> #include <stdio.h> char* clearType(char* inp); /** Represents the possible field values for a MIPS32 machine instruction. * * A ParseResult object is said to be proper iff: * * - Each of the char* members is either NULL or points to a zero- * terminated C-string. * - If ASMInstruction is not NULL, the contents of the array represent * a MIPS32 assembly instruction. * - If ASMInstruction is not NULL, the other fields are set to properly * represent the corresponding fields of the MIPS32 assembly instruction * stored in ASMInstruction. * - Each field that is not relevant to the MIPS32 assembly instruction * is set as described in the comments below. */ struct _ParseResult { // Each char* member will be NULL or point to dynamically-allocated char array // holding a zero-terminated C string. // The assembly code portion char* ASMInstruction; // the assembly instruction, as a C-string char* Mnemonic; // the symbolic name of the instruction char* rdName; // the symbolic names of the registers, as C-strings; char* rsName; // NULL if the register field is not specified char* rtName; // in the assembly instruction // The following are integer values int16_t Imm; // the immediate field, as a signed integer; // 0 if not relevant for the assembly instruction uint8_t rd; // the three register fields, as small unsigned integers; uint8_t rs; // 255 if not relevant for the assembly instruction uint8_t rt; char* shamt; // shift amount char* Target; // target for jump instructions // The computed machine code portion // These are malloc'd zero-terminated C-strings char* Opcode; // the opcode field bits char* Funct; // the funct field bits // NULL if not relevant for the assembly instruction char* RD; // the bit representations of the register numbers; char* RS; // NULL if not relevant for the assembly instruction char* RT; char* IMM; // 2's complement bit representation of the immediate; // NULL if not relevant for the assembly instruction }; typedef struct _ParseResult ParseResult; /** Frees the dynamic content of a ParseResult object. * * Pre: pPR points to a proper ParseResult object. * Post: All of the dynamically-allocated arrays in *pPR have been * deallocated. * *pPR is proper. * * Comments: * - The function has no information about whether *pPR has been * allocated dynamically, so it cannot risk attempting to * deallocate *pPR. * - The function is intended to provide the user with a simple * way to free memory; the user may or may not reuse *pPR. So, * the function does set the pointers in *pPR to NULL. */ void clearResult(ParseResult* const pPR); /** Prints the contents of a ParseResult object. * * Pre: Log is open on an output file. * pPR points to a proper ParseResult object. */ void printResult(FILE* Log, const ParseResult* const pPR); #endif SymbolTable.h 0000600 0061730 0023423 00000001235 14236755613 013437 0 ustar jordanha23 Others #ifndef SYMBOLTABLE_H #define SYMBOLTABLE_H #include <stdio.h> #define NUM_SYMBOLS 1000 #define IMM_LENGTH 17 struct _DataSymbol { char key[100]; char* binary; int address; char* type; }; typedef struct _DataSymbol DataSymbol; extern DataSymbol dataSymbols[NUM_SYMBOLS]; struct _TextSymbol { char* key; int instructionNum; int address; }; typedef struct _TextSymbol TextSymbol; extern TextSymbol textSymbols[NUM_SYMBOLS]; /** Writes the symbol table out o the given file * * Pre: outF is a valid output file * */ void makeTable(FILE* outF); void cleanTable(); char* decToBinary(char* dec); char* decToBinary26(char* dec); #endif pledge.txt 0000600 0061730 0023423 00000001264 14236755613 013054 0 ustar jordanha23 Others On my honor: - I have not discussed the C language code in my program with anyone other than my instructor or the teaching assistants assigned to this course. - I have not used C language code obtained from another student, the Internet, or any other unauthorized source, either modified or unmodified. - If any C language code or documentation used in my program was obtained from an authorized source, such as a text book or course notes, that has been clearly noted with a proper citation in the comments of my program. - I have not designed this program in such a way as to defeat or interfere with the normal operation of the grading code. <Jordan Harrington> <jordanha23>