partial success! testParse will parse a file, though not all the hex is correct. primarily this is the case for instructions not yet added however. running from main with cli arguments currently will always result in a seg fault.

This commit is contained in:
Josh Ashton
2023-10-17 13:08:31 -06:00
parent 160cf8d9a0
commit e0102289e4
15 changed files with 162 additions and 128 deletions
+40
View File
@@ -0,0 +1,40 @@
.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
Executable
BIN
View File
Binary file not shown.
+67 -4
View File
@@ -2,6 +2,8 @@
#include <stdlib.h>
#include <string.h>
#include "util/parse.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"
@@ -10,21 +12,82 @@ int help() {
" mipsToHex --help\n"
" mipsToHex [ file ]\n"
" mipsToHex --asm [ asmFile ]\n"
" mipsToHex -a [ asmFile ]\n"
" mipsToHex --asm [ asmFile ] --hex [ hexFile ]\n"
" mipsToHex -a [ asmFile ] -x [ hexFile ]\n"
);
return 0;
}
int error() {
printf("There must be at least one argument.");
int error(char * msg) {
printf("\n%s\n", msg);
help();
return 1;
}
int printHex(struct instruction* current) {
while(current->nextInstruction != NULL) {
printf("0x%s ", convert(current));
current = current->nextInstruction;
}
free(current);
return 1;
}
int writeHex(struct instruction * current) {
while(current->nextInstruction != NULL) {
printf("0x%s ", convert(current));
current = current->nextInstruction;
}
return 1; // TODO: Need to write the output to the file.
}
int main(int argc, char* args[]) {
if(argc < 2) return error();
if(argc < 2) return error("There must be at least one argument.");
if(strcmp(args[1], "-h") == 0 || strcmp(args[1], "--help") == 0) return help();
return 0;
char * file;
//FILE * outputFile;
// If the only argument is the input file, then set the FILE pointer.
if(argc == 2) {
printf("only 1 true arg, %s", args[1]);
file = args[1];
}
struct instruction * head = initParse(file);
return printHex(head);
//if(outputFile != NULL) return writeHex(head, outputFile);
//else return printHex(head);
}
/**
// If there are 5 arguments total, then we should have the flag for the hex output file in position 4.
} else if(argc == 5) {
printf("4 true args, %s, %s", args[3], args[4]);
if(strcmp(args[3], "-x") == 0 || strcmp(args[3], "--hex") == 0)
outputFile= fopen(args[4], "w");
else return error("invalid argument format.");
// Catch if the file does not exist/cannot be opened.
if(outputFile == NULL) return error("output file cannot be created or written. check permissions.");
}
// If there are at least 3 arguments, then we should have the flag for the assembly input file in position 1.
if(argc >= 3) {
printf("at least 2 true args, %s, %s", args[1], args[2]);
if(strcmp(args[1], "--asm") == 0 || strcmp(args[1], "-a") == 0) {
file = fopen(args[2], "r");
outputFile = NULL;
} else return error("invalid argument format.");
}
*/
// Catch if the file does not exist/cannot be opened.
View File
-2
View File
@@ -1,2 +0,0 @@
add $t3, $t1, $t2 # Sum the previous and current values and save in register t3
addi $t0, $t0, 1 # Increment counter
BIN
View File
Binary file not shown.
+1
View File
@@ -0,0 +1 @@
0x00000020 0x00000020 0x00000020 0x00000020 0x00000020 0x00000020 0x00400008 0x00801020 0x00000024 0x00000020 0x00000020 0x00000020 0x00400008 0x00000024 0x00000020 0x00000024 0x00000020 0x00400008 0x00801020 0x00000024 0x00400008 0x00000024 0x00000020 0x0000F821 0x0000F820 0x0000F820 0x01000008 0x01200008 0x01400008 0x01600008 0x00005820 0x00005820 0x012A5820 0x012A5820 0x012A5820 0x21080001 0x01014020 0x01014020 0x01014020 0x0000F821
-55
View File
@@ -1,55 +0,0 @@
Compiling...
Output...
.dataU
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: "u
f
.textT
.
main:T
li v0 4r
la a0 welcomeMessageT
syscalle
s
jal getInpute
j
jal fibonacciM
move a0 v0c
li v0 1
syscall
s
ori v0 0 10c
syscall0
s
getInput:1
li v0 4t
la a0 prompti
syscallr
s
li v0 5r
syscallr
move a0 v0p
m
jr raa
j
fibonacci:p
move s1 a0p
li t0 2
li t1 0
li t2 1
li t3 0
l
while:0
bge t0 s1 donee
add t3 t1 t2n
move t1 t2t
m
move t2 t3t
addi t0 t0 1n
a
b while
b
done:l
move v0 t2
jr rav
-9
View File
@@ -22,7 +22,6 @@ int test_toBinary_0_size5() {
int expectedOutput[] = { 0, 0, 0, 0, 0 };
int cmp = compareIntArray(binary, expectedOutput, size);
free(binary);
return cmp;
}
@@ -33,7 +32,6 @@ int test_toBinary_0_size6() {
int expectedOutput[] = { 0, 0, 0, 0, 0, 0 };
int cmp = compareIntArray(binary, expectedOutput, size);
free(binary);
return cmp;
}
@@ -44,7 +42,6 @@ int test_toBinary_10_size6() {
int expectedOutput[] = { 0, 0, 1, 0, 1, 0 };
int cmp = compareIntArray(binary, expectedOutput, size);
free(binary);
return cmp;
}
@@ -55,7 +52,6 @@ int test_toBinary_20_size6() {
int expectedOutput[] = { 0, 1, 0, 1, 0, 0 };
int cmp = compareIntArray(binary, expectedOutput, size);
free(binary);
return cmp;
}
@@ -66,7 +62,6 @@ int test_toBinary_17_size16() {
int expectedOutput[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1};
int cmp = compareIntArray(binary, expectedOutput, size);
free(binary);
return cmp;
}
@@ -83,7 +78,6 @@ int test_rToBinary_sll() {
int expectedOutput[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 };
int cmp = compareIntArray(binary, expectedOutput, 32);
free(binary);
return cmp;
}
@@ -101,7 +95,6 @@ int test_rToBinary_add() {
int expectedOutput[] = { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 };
int cmp = compareIntArray(binary, expectedOutput, 32);
free(binary);
return cmp;
}
@@ -118,7 +111,6 @@ int test_rToHex_add() {
char * hex = rToHex(rFormat);
char * expectedHex = "02326820";
int cmp = strcmp(hex, expectedHex);
free(hex);
if(cmp < 0 || cmp > 0) return 0;
else return 1;
@@ -136,7 +128,6 @@ int test_rToHex_sll() {
char * hex = rToHex(rFormat);
char * expectedHex = "00107080";
int cmp = strcmp(hex, expectedHex);
free(hex);
if(cmp < 0 || cmp > 0) return 0;
else return 1;
+3 -18
View File
@@ -4,18 +4,9 @@
#include "../util/parse.c"
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));
printf("0x%s ", convert(current));
current = current->nextInstruction;
}
@@ -23,16 +14,10 @@ int traverse(struct instruction* current) {
return 1; // TODO
}
int test_readFile() {
struct instruction * head = initParse(filepath);
traverse(head);
return 1;
}
int main() {
// filepath may be a relative or an absolute filepath
//filepath = "/home/jashton/dev/mipsToHex/src/test/Fibonacci.asm";
filepath = "Fibonacci.asm";
char * filepath = "Fibonacci.asm";
return test_readFile();
return traverse(initParse(filepath));
}
+21 -10
View File
@@ -109,27 +109,31 @@ int * rToBinary(r* format) {
int * opcode = toBinary(format->opcode, 6);
fillArray(bin, opcode, 0, size);
free(opcode);
int * rs = toBinary(format->rs, 5);
fillArray(bin, rs, 6, size);
free(rs);
int * rt = toBinary(format->rt, 5);
fillArray(bin, rt, 11, size);
free(rt);
int * rd = toBinary(format->rd, 5);
fillArray(bin, rd, 16, size);
free(rd);
int * shamt = toBinary(format->shamt, 5);
fillArray(bin, shamt, 21, size);
free(shamt);
int * funct = toBinary(format->funct, 6);
fillArray(bin, funct, 26, size);
free(funct);
// Print the binary representation.
/**
for(int i = 0; i < 32; i++) {
printf("%d", bin[i]);
if(i % 4 == 3) printf(" ");
}
printf("\n"); // Separate the bit string from the hex
*/
return bin;
}
@@ -148,19 +152,26 @@ int * iToBinary(i* format) {
int * opcode = toBinary(format->opcode, 6);
fillArray(bin, opcode, 0, size);
free(opcode);
int * rs = toBinary(format->rs, 5);
fillArray(bin, rs, 6, size);
free(rs);
int * rt = toBinary(format->rt, 5);
fillArray(bin, rt, 11, size);
free(rt);
int * immediate = toBinary(format->immediate, 16);
fillArray(bin, immediate, 16, size);
free(immediate);
// Print the binary representation
/**
printf("\n");
for(int i = 0; i < 32; i++) {
printf("%d", bin[i]);
if(i % 4 == 3) printf(" ");
}
printf("\n");
*/
return bin;
}
+1 -1
View File
@@ -1,5 +1,4 @@
#define FOREACH_FUNCTION(FUNCTION) \
FUNCTION(addi) \
FUNCTION(add) \
FUNCTION(jr) \
FUNCTION(syscall) \
@@ -12,6 +11,7 @@
FUNCTION(sltu) \
FUNCTION(sll) \
FUNCTION(srl) \
FUNCTION(addi) \
FUNCTION(sub) \
FUNCTION(subu) \
FUNCTION(jal) \
+18 -12
View File
@@ -19,7 +19,6 @@ void initFunctions() {
// -------------------------- R FORMAT INSTRUCTIONS -------------------------- //
char * addFunc(int * args) {
r* rFormat = (r*)malloc(sizeof(r));
rFormat->rd = args[0];
rFormat->rs = args[1];
rFormat->rt = args[2];
@@ -201,9 +200,19 @@ char * beqFunction(int * args) {
// -------------------------- J FORMAT INSTRUCTIONS -------------------------- //
int str2int(char * numStr) {
int intVal = 0;
while(* numStr != '\0') {
intVal *= 10;
intVal += * numStr - '0'; //0x30 ascii value of charater 0
numStr++;
}
return intVal;
}
// Helper function to get the number of arguments.
int getArgCount(struct args * a) {
printf("getArgCount ");
int count = 0;
while(a != NULL) {
@@ -216,8 +225,6 @@ int getArgCount(struct args * a) {
// 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;
@@ -237,21 +244,20 @@ int * getArgs(struct args * a) {
// otherwise, we have found a constant.
else {
array[index] = (int) a->arg[0];
printf("%d", array[index]);
// TODO: This is broken. Currently only gets the first digit.
array[index] = str2int(a->arg);
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) {
@@ -306,20 +312,20 @@ char * funcToCall(int i, struct args * remainingArgs) {
default:
hex = "";
}
free(rFormat);
free(iFormat);
return hex;
}
// Convert a linked list instruction into hexadecimal
char * convert(struct instruction * i) {
printf("convert ");
initFunctions();
struct args * remainingArgs;
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++) {
for(int i = 0; i < 13; i++) {
if(strcmp(a->arg, FUNCTION_STRING[i]) == 0) {
call = i;
remainingArgs = a->nextArg;
+2 -2
View File
@@ -1,11 +1,11 @@
typedef struct args {
char * arg;
struct args *nextArg; // Allows dynamically sized lists of arguments. For eg. syscall will just be 1 element, but add has 4 elements.
struct args * nextArg; // Allows dynamically sized lists of arguments. For eg. syscall will just be 1 element, but add has 4 elements.
} args;
typedef struct instruction {
int formatType; // 0 = R, 1 = I, 2 = J
struct instruction* nextInstruction;
struct args* a; // A linked list of each argument of the instruction.
struct args * a; // A linked list of each argument of the instruction.
} instruction;
+9 -15
View File
@@ -6,8 +6,6 @@
#include "functions.c"
FILE * file;
// Determines if the parser should keep a space, based upon if the space is surrounded by two non-space characters.
int determineKeepSpace(char prior, char after) {
if(&prior != (char *) NULL && !isspace(prior))
@@ -19,6 +17,8 @@ int determineKeepSpace(char prior, char after) {
// Cleans up the input string to prepare for parsing into command and arguments.
char * removeCommentsAndWhiteSpace(char * line) {
if(line[0] == 10) return "";
int len = strlen(line);
char tmpLine[256];
int parsedIndex = 0;
@@ -36,14 +36,13 @@ char * removeCommentsAndWhiteSpace(char * line) {
} else if(isspace(line[i])) {
// Check if we're within bounds of the array to check whitespace
if((i - 1 >= 0) && (i + 1 < len)) {
if((i - 1 >= 0) && (i + 1 < len))
if(determineKeepSpace(line[i - 1], line[i + 1]) == 1) {
tmpLine[parsedIndex] = line[i];
parsedIndex++;
}
}
}
}
// Create a dynamically sized array containing only the valid characters
char * parsed = (char *)calloc(parsedIndex, sizeof(char));
@@ -69,20 +68,16 @@ void parseIntoNotation(char * bareLine, args * a) {
}
}
// Accepts an already verified FILE pointer to parse. Creates a Linked List to contain each instruction, with a sub Linked List
// to contain each argument of each instruction. Formatted into a custom numeric notation.
instruction* initParse(char * filepath) {
// Open and read a file.
file = fopen(filepath, "r");
FILE * file = fopen(filepath, "r");
if(file == NULL) return NULL;
// Maximum number of characters in a line is 1024.
char lines[1024];
char lines[256];
// Catch if the file does not exist/cannot be opened.
if(file == NULL) {
printf("%s cannot be opened.\n", filepath);
return NULL;
}
int numFunctions = 4; // TODO: Need to obtain dynamically.
int numFunctions = 16; // TODO: Need to obtain dynamically.
struct instruction* head = (instruction*) malloc(sizeof(instruction));
struct instruction* current = head;
@@ -98,6 +93,5 @@ instruction* initParse(char * filepath) {
current = current->nextInstruction;
}
fclose(file);
return head;
}