/*
* Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this
license
* Click nbfs://nbhost/SystemFileSystem/Templates/cFiles/main.c to edit this template
*/
/*
* File: main.c
* Author: Andrew Schelb
*
* Created on March 7, 2023, 2:51 PM
*/
#include
#include
#define TEXT_SEGMENT 0x0200
#define DATA_SEGMENT 0x0000
#define MAX_SIZE 1024
typedef struct {
char* name;
int opcode;
int funct;
int rs;
int rt;
int rd;
int imm;
int add;
} Instruction;
typedef struct {
int n;
int size;
char* name;
} Directive;
// MIPS Instructions
Instruction instructions[] = {
{"add", 0, 32, 0, 0, 0, 0, 0},
{"addu", 0, 33, 0, 0, 0, 0, 0},
{"sub", 0, 34, 0, 0, 0, 0, 0},
{"sll", 0, 0, 0, 0, 0, 0, 0},
{"slt", 0, 42, 0, 0, 0, 0, 0},
{"addi", 8, 0, 0, 0, 0, 0, 0},
{"lui", 15, 0, 0, 0, 0, 0, 0},
{"ori", 13, 0, 0, 0, 0, 0, 0},
{"lw", 35, 0, 0, 0, 0, 0, 0},
{"sw", 43, 0, 0, 0, 0, 0, 0},
{NULL, 0, 0, 0, 0, 0, 0, 0}
};
// MIPS Directives
Directive directives[] = {
{0, 0, ".text"},
{1, 0, ".data"},
{2, 1, ".dbyte"},
{3, 4, ".integer"},
{-1, 0, NULL}
};
// Function Prototypes
Instruction* getInstruction(char*);
Directive* getDirective(char*);
int getRegisterNumber(char*);
int parseInstruction(char*, int*, int*);
int parseDirective(char*, int*, int*);
void assemble(char*, int*);
int main(int argc, char** argv) {
// Checking command line arguments
if (argc < 2) {
printf("Usage: %s \n", argv[0]);
return -1;
}
// Initializing memory
int text_segment[MAX_SIZE];
int data_segment[MAX_SIZE];
memset(text_segment, 0, MAX_SIZE);
memset(data_segment, 0, MAX_SIZE);
// Assembling
assemble(argv[1], text_segment);
// Writing to output file
FILE* fp = fopen(argv[2], "wb");
fwrite(data_segment, 1, MAX_SIZE, fp);
fwrite(text_segment, 1, MAX_SIZE, fp);
fclose(fp);
return 0;
}
// Assembling the input file
void assemble(char* filename, int* text_segment) {
int line_number = 0;
int text_offset = 0;
int data_offset = 0;
char line[256];
FILE* fp = fopen(filename, "r");
while (fgets(line, 256, fp)) {
// Handling blank lines
if (strcmp(line, "\n") == 0) {
continue;
}
// Parsing line
char. Continue
char* label = NULL;
char* instruction = NULL;
char* directive = NULL;
char* operands = NULL;
label = strtok(line, ":");
instruction = strtok(NULL, " \n\t");
directive = strtok(NULL, " \n\t");
operands = strtok(NULL, "\n\t");
// Handling instructions
if (instruction) {
// Parsing instruction
int opcode = 0;
int funct = 0;
int rs = 0;
int rt = 0;
int rd = 0;
int imm = 0;
int add = 0;
if (parseInstruction(instruction, &opcode, &funct)) {
rs = getRegisterNumber(strtok(operands, ","));
rt = getRegisterNumber(strtok(NULL, ","));
if (opcode == 0) {
rd = getRegisterNumber(strtok(NULL, ","));
} else {.
// Generating machine code
int machine_code = 0;
machine_code |= (opcode << 26);
machine_code |= (rs << 21);
machine_code |= (rt << 16);
machine_code |= (rd << 11);
machine_code |= (imm << 0);
machine_code |= (add << 0);
machine_code |= (funct << 0);
// Writing machine code to text segment
t.