From 160cf8d9a03f85826716b62e49447cd497636c06 Mon Sep 17 00:00:00 2001 From: Josh Ashton Date: Fri, 13 Oct 2023 16:00:22 -0600 Subject: [PATCH] succesfully parsing and outputing into converter. two main bugs, the converter adds 1 to the end somehow, and for the addi instruction it's registering that there are multiple free() statements --- src/main.c | 7 - src/test/Fibonacci.asm | 51 ------- src/test/a.out | Bin 0 -> 22064 bytes src/test/testParse.c | 20 ++- src/util/functionAssigner.h | 2 +- src/util/functions.c | 258 +++++++++++++++++++++++++++--------- src/util/instruction.h | 2 +- src/util/parse.c | 63 ++++----- 8 files changed, 241 insertions(+), 162 deletions(-) create mode 100755 src/test/a.out diff --git a/src/main.c b/src/main.c index 99e6f5c..7b23b8f 100644 --- a/src/main.c +++ b/src/main.c @@ -2,9 +2,6 @@ #include #include -#include "util/registers.h" -#include "util/functions.c" - int help() { printf( "\nA CLI-based tool to convert MIPS assembly instructions in a .asm file into hexadecimal instructions in a .hex file.\n" @@ -29,9 +26,5 @@ int main(int argc, char* args[]) { if(argc < 2) return error(); if(strcmp(args[1], "-h") == 0 || strcmp(args[1], "--help") == 0) return help(); - initFunctions(); - - for(int i = 0; i < 32; i++) - printf("%d: %s\n", i, REGISTER_STRING[i]); return 0; } diff --git a/src/test/Fibonacci.asm b/src/test/Fibonacci.asm index 470e5ee..e1358cb 100644 --- a/src/test/Fibonacci.asm +++ b/src/test/Fibonacci.asm @@ -1,53 +1,2 @@ -.data - welcomeMessage: .asciiz "Welcome to a MIPS assembly Fibonacci Sequence calculator!\nThis will calculate the nth term of the Fibonacci Sequence.\n" - prompt: .asciiz "Enter a number (n, input n > 2) to find the nth term:" - foundTerm: .asciiz "The nth term is: " - -.text - -main: - li $v0, 4 # syscall 4 is to print a string - la $a0, welcomeMessage # store the ascii string in register a0 - syscall # print - - jal getInput # get the user input - - jal fibonacci # calculate the nth fibonacci term - move $a0, $v0 # move the returned term to register a0 - li $v0, 1 # syscall 1 is to print an int - syscall # print - - ori $v0, $0, 10 # system call code 10 for exit - syscall # exit the program - -getInput: - li $v0, 4 # syscall 4 is to print a string - la $a0, prompt # store the ascii string in register a0 - syscall # print - - li $v0, 5 # syscall 5 is for reading an int - syscall # read an int from the user - move $a0, $v0 # load input into register a0 - - jr $ra # return to caller - -fibonacci: - move $s1, $a0 # Copy the nth term - li $t0, 2 # Counter - li $t1, 0 # Prev value - li $t2, 1 # Current value - li $t3, 0 # Next value - - while: - bge $t0, $s1, done # While the counter is less than n add $t3, $t1, $t2 # Sum the previous and current values and save in register t3 - move $t1, $t2 # Shift current value to previous value - - move $t2, $t3 # Shift next value to current value addi $t0, $t0, 1 # Increment counter - - b while # Jump back to start of while loop - - done: - move $v0, $t2 # Move current value to register v0 - jr $ra # Return to caller diff --git a/src/test/a.out b/src/test/a.out new file mode 100755 index 0000000000000000000000000000000000000000..2d27402765332b2d55b2c13079ca3e3757a33339 GIT binary patch literal 22064 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 literal 0 HcmV?d00001 diff --git a/src/test/testParse.c b/src/test/testParse.c index 90054f8..b9d5036 100644 --- a/src/test/testParse.c +++ b/src/test/testParse.c @@ -6,8 +6,26 @@ char * filepath; +int traverse(struct instruction* current) { + while(current->nextInstruction != NULL) { + struct args* currentArgs = current->a; + while(currentArgs != NULL) { + printf("%s ", currentArgs->arg); + currentArgs = currentArgs->nextArg; + } + printf("\n"); + + printf("%s\n", convert(current)); + + current = current->nextInstruction; + } + + return 1; // TODO +} + int test_readFile() { - initParse(filepath); + struct instruction * head = initParse(filepath); + traverse(head); return 1; } diff --git a/src/util/functionAssigner.h b/src/util/functionAssigner.h index 4f6bcbf..ff2fcaf 100644 --- a/src/util/functionAssigner.h +++ b/src/util/functionAssigner.h @@ -1,4 +1,5 @@ #define FOREACH_FUNCTION(FUNCTION) \ + FUNCTION(addi) \ FUNCTION(add) \ FUNCTION(jr) \ FUNCTION(syscall) \ @@ -13,7 +14,6 @@ FUNCTION(srl) \ FUNCTION(sub) \ FUNCTION(subu) \ - FUNCTION(addi) \ FUNCTION(jal) \ #define GENERATE_ENUM(ENUM) ENUM, diff --git a/src/util/functions.c b/src/util/functions.c index 8e3a16c..37db0d8 100644 --- a/src/util/functions.c +++ b/src/util/functions.c @@ -2,6 +2,10 @@ #include #include "formats.c" +#include "registers.h" +#include "functionAssigner.h" +#include "instruction.h" + r* rFormat; i* iFormat; @@ -14,10 +18,11 @@ void initFunctions() { } // -------------------------- R FORMAT INSTRUCTIONS -------------------------- // -char * add(int * args[]) { - rFormat->rd = *args[0]; - rFormat->rs = *args[1]; - rFormat->rt = *args[2]; +char * addFunc(int * args) { + r* rFormat = (r*)malloc(sizeof(r)); + rFormat->rd = args[0]; + rFormat->rs = args[1]; + rFormat->rt = args[2]; rFormat->funct = 32; // Unused in add instruction. @@ -26,10 +31,10 @@ char * add(int * args[]) { return rToHex(rFormat); } -char * addu(int * args[]) { - rFormat->rd = *args[0]; - rFormat->rs = *args[1]; - rFormat->rt = *args[2]; +char * adduFunction(int * args) { + rFormat->rd = args[0]; + rFormat->rs = args[1]; + rFormat->rt = args[2]; rFormat->funct = 33; // Unused in addu instruction. @@ -38,10 +43,10 @@ char * addu(int * args[]) { return rToHex(rFormat); } -char * and(int * args[]) { - rFormat->rd = *args[0]; - rFormat->rs = *args[1]; - rFormat->rt = *args[2]; +char * andFunction(int * args) { + rFormat->rd = args[0]; + rFormat->rs = args[1]; + rFormat->rt = args[2]; rFormat->funct = 36; // Unused in and instruction. @@ -50,8 +55,8 @@ char * and(int * args[]) { return rToHex(rFormat); } -char * jr(int * args[]) { - rFormat->rs = *args[0]; +char * jrFunction(int * args) { + rFormat->rs = args[0]; rFormat->funct = 8; // Unused in jr instruction. @@ -62,10 +67,10 @@ char * jr(int * args[]) { return rToHex(rFormat); } -char * nor(int * args[]) { - rFormat->rd = *args[0]; - rFormat->rs = *args[1]; - rFormat->rt = *args[2]; +char * norFunction(int * args) { + rFormat->rd = args[0]; + rFormat->rs = args[1]; + rFormat->rt = args[2]; rFormat->funct = 39; // Unused in nor instruction. @@ -74,10 +79,10 @@ char * nor(int * args[]) { return rToHex(rFormat); } -char * or(int * args[]) { - rFormat->rd = *args[0]; - rFormat->rs = *args[1]; - rFormat->rt = *args[2]; +char * orFunction(int * args) { + rFormat->rd = args[0]; + rFormat->rs = args[1]; + rFormat->rt = args[2]; rFormat->funct = 37; // Unused in or instruction. @@ -85,10 +90,10 @@ char * or(int * args[]) { return rToHex(rFormat); } -char * slt(int * args[]) { - rFormat->rd = *args[0]; - rFormat->rs = *args[1]; - rFormat->rt = *args[2]; +char * sltFunction(int * args) { + rFormat->rd = args[0]; + rFormat->rs = args[1]; + rFormat->rt = args[2]; rFormat->funct = 42; // Unused in slt instruction. @@ -97,10 +102,10 @@ char * slt(int * args[]) { return rToHex(rFormat); } -char * sltu(int * args[]) { - rFormat->rd = *args[0]; - rFormat->rs = *args[1]; - rFormat->rt = *args[2]; +char * sltuFunction(int * args) { + rFormat->rd = args[0]; + rFormat->rs = args[1]; + rFormat->rt = args[2]; rFormat->funct = 43; // Unused in sltu instruction. @@ -109,10 +114,10 @@ char * sltu(int * args[]) { return rToHex(rFormat); } -char * sll(int * args[]) { - rFormat->rd = *args[0]; - rFormat->rt = *args[1]; - rFormat->shamt = *args[2]; +char * sllFunction(int * args) { + rFormat->rd = args[0]; + rFormat->rt = args[1]; + rFormat->shamt = args[2]; rFormat->funct = 0; // Unused in sll instruction. @@ -121,10 +126,10 @@ char * sll(int * args[]) { return rToHex(rFormat); } -char * srl(int * args[]) { - rFormat->rd = *args[0]; - rFormat->rt = *args[1]; - rFormat->shamt = *args[2]; +char * srlFunction(int * args) { + rFormat->rd = args[0]; + rFormat->rt = args[1]; + rFormat->shamt = args[2]; rFormat->funct = 2; // Unused in sll instruction. @@ -133,10 +138,10 @@ char * srl(int * args[]) { return rToHex(rFormat); } -char * sub(int * args[]) { - rFormat->rd = *args[0]; - rFormat->rs = *args[1]; - rFormat->rt = *args[2]; +char * subFunction(int * args) { + rFormat->rd = args[0]; + rFormat->rs = args[1]; + rFormat->rt = args[2]; rFormat->funct = 34; // Unused in sll instruction. @@ -145,10 +150,10 @@ char * sub(int * args[]) { return rToHex(rFormat); } -char * subu(int * args[]) { - rFormat->rd = *args[0]; - rFormat->rs = *args[1]; - rFormat->rt = *args[2]; +char * subuFunction(int * args) { + rFormat->rd = args[0]; + rFormat->rs = args[1]; + rFormat->rt = args[2]; rFormat->funct = 35; // Unused in sll instruction. @@ -158,40 +163,169 @@ char * subu(int * args[]) { } // -------------------------- I FORMAT INSTRUCTIONS -------------------------- // -char * addi(int * args[]) { +char * addiFunction(int * args) { iFormat->opcode = 8; - iFormat->rt = *args[0]; - iFormat->rs = *args[1]; - iFormat->immediate = *args[2]; + iFormat->rt = args[0]; + iFormat->rs = args[1]; + iFormat->immediate = args[2]; return iToHex(iFormat); } -char * addiu(int * args[]) { +char * addiuFunction(int * args) { iFormat->opcode = 9; - iFormat->rt = *args[0]; - iFormat->rs = *args[1]; - iFormat->immediate = *args[2]; + iFormat->rt = args[0]; + iFormat->rs = args[1]; + iFormat->immediate = args[2]; return iToHex(iFormat); } -char * andi(int * args[]) { +char * andiFunction(int * args) { iFormat->opcode = 12; - iFormat->rt = *args[0]; - iFormat->rs = *args[1]; - iFormat->immediate = *args[2]; + iFormat->rt = args[0]; + iFormat->rs = args[1]; + iFormat->immediate = args[2]; return iToHex(iFormat); } -char * beq(int * args[]) { +char * beqFunction(int * args) { iFormat->opcode = 4; - iFormat->rt = *args[0]; - iFormat->rs = *args[1]; - iFormat->immediate = *args[2]; + iFormat->rt = args[0]; + iFormat->rs = args[1]; + iFormat->immediate = args[2]; return iToHex(iFormat); } // -------------------------- J FORMAT INSTRUCTIONS -------------------------- // + +// Helper function to get the number of arguments. +int getArgCount(struct args * a) { + printf("getArgCount "); + int count = 0; + + while(a != NULL) { + count++; + a = a->nextArg; + } + + return count; +} + +// Converts a linked list of arguments into an int array of arguments. +int * getArgs(struct args * a) { + printf("getArgs "); + + int * array = (int *) calloc(getArgCount(a), sizeof(int)); + int index = 0; + int update = 0; + while(a != NULL) { + + // check for valid register + for(int i = 0; i < 32; i++) { + if(strcmp(a->arg, REGISTER_STRING[i]) == 0) { + array[index] = i; + index++; + update = 1; + } + } + + // if we found a register, reset the update value to detect a register in the next argument. + if(update == 1) update = 0; + + // otherwise, we have found a constant. + else { + array[index] = (int) a->arg[0]; + printf("%d", array[index]); + index++; + } + + + // move to the next argument. + a = a->nextArg; + } + return array; +} + +// Helper function to determine what function to call given an input int +char * funcToCall(int i, struct args * remainingArgs) { + printf("funcToCall "); + int * args = getArgs(remainingArgs); + char * hex; + switch (i) { + case 0: + hex = addFunc(args); + break; + case 1: + hex = adduFunction(args); + break; + case 2: + hex = andFunction(args); + break; + case 3: + hex = jrFunction(args); + break; + case 4: + hex = norFunction(args); + break; + case 5: + hex = orFunction(args); + break; + case 6: + hex = sltFunction(args); + break; + case 7: + hex = sltuFunction(args); + break; + case 8: + hex = sllFunction(args); + break; + case 9: + hex = srlFunction(args); + break; + case 10: + hex = subFunction(args); + break; + case 11: + hex = subuFunction(args); + break; + case 12: + hex = addiFunction(args); + break; + case 13: + hex = addiuFunction(args); + break; + case 14: + hex = andiFunction(args); + break; + case 15: + hex = beqFunction(args); + break; + default: + hex = ""; + } + + return hex; +} + +// Convert a linked list instruction into hexadecimal +char * convert(struct instruction * i) { + printf("convert "); + initFunctions(); + struct args * a = i->a; + int call = 0; + struct args * remainingArgs; + + // Go through each of the available functions and find a match for the first argument, and get the remaining args + for(int i = 0; i < 4; i++) { + if(strcmp(a->arg, FUNCTION_STRING[i]) == 0) { + call = i; + remainingArgs = a->nextArg; + break; + } + } + + return funcToCall(call, remainingArgs); +} diff --git a/src/util/instruction.h b/src/util/instruction.h index fd9b650..23840ac 100644 --- a/src/util/instruction.h +++ b/src/util/instruction.h @@ -1,5 +1,5 @@ typedef struct args { - int arg; + char * arg; struct args *nextArg; // Allows dynamically sized lists of arguments. For eg. syscall will just be 1 element, but add has 4 elements. } args; diff --git a/src/util/parse.c b/src/util/parse.c index eac0a58..155704c 100644 --- a/src/util/parse.c +++ b/src/util/parse.c @@ -4,9 +4,7 @@ #include #include -#include "formats.c" -#include "registers.h" -#include "functionAssigner.h" +#include "functions.c" FILE * file; @@ -56,63 +54,50 @@ char * removeCommentsAndWhiteSpace(char * line) { } // Parse a line of assembly into numerical representations for the function (eg. add = 0), registers, offset, etc. -int * parseIntoNotation(char * bareLine) { - int numFunctions = 20; // TODO: Need to obtain dynamically. - //char * tokens = strtok(bareLine, " "); - +void parseIntoNotation(char * bareLine, args * a) { char * token = strtok(bareLine, " "); + args * current = a; + + while (token != NULL) { + current->arg = token; + token = strtok(NULL, " "); - int cmd; - for(int i = 0; i < numFunctions; i++) - if(strcmp(token, FUNCTION_STRING[i]) == 0) cmd = i; - - int * notation = (int *)calloc(4, sizeof(int)); - int counter = 1; - while (token != NULL) - { - // Compare only the first token to all available functions. - if(counter == 0) { + if(token != NULL) { + current->nextArg = (args*) malloc(sizeof(args)); + current = current->nextArg; } - - if(counter == 0) break; - - // Compare subsequent tokens to available registers. - for(int i = 0; i < 32; i++) { - if(strcmp(token, REGISTER_STRING[i]) == 0) { - notation[counter] = i; - counter++; - continue; - } - } - - printf("%s ", token); - token = strtok(NULL, " "); } - - return notation; } -int initParse(char * filepath) { +instruction* initParse(char * filepath) { // Open and read a file. file = fopen(filepath, "r"); // Maximum number of characters in a line is 1024. - char lines[256]; + char lines[1024]; // Catch if the file does not exist/cannot be opened. if(file == NULL) { printf("%s cannot be opened.\n", filepath); - return 0; + return NULL; } + int numFunctions = 4; // TODO: Need to obtain dynamically. + struct instruction* head = (instruction*) malloc(sizeof(instruction)); + struct instruction* current = head; // Get each line of the file, remove comments and whitespace, and attempt to parse while(fgets(lines, sizeof(lines), file)) { + struct args* argsHead = (args*) malloc(sizeof(args)); + current->a = argsHead; + char * line = removeCommentsAndWhiteSpace(lines); - int * notation = parseIntoNotation(line); + parseIntoNotation(line, argsHead); + + current->nextInstruction = (instruction*) malloc(sizeof(instruction)); + current = current->nextInstruction; } fclose(file); - - return 1; + return head; }