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
This commit is contained in:
@@ -2,9 +2,6 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Executable
BIN
Binary file not shown.
+19
-1
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
+196
-62
@@ -2,6 +2,10 @@
|
||||
#include <stdlib.h>
|
||||
#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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
+24
-39
@@ -4,9 +4,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user