Commit bf09b50d authored by sea19's avatar sea19
Browse files

ASSEMBLER IS WORKING FOR DATA PROCESSING AND MULTIPLICATION

parent 8e00a9e5
CC = gcc
CFLAGS = -Wall -g -std=c99 -Werror -pedantic
EMULATEFILES = emulate.c fetch.c decode.c execute.c instrType.c
ASSEMBLEFILES = assemble.c readFile.c
ASSEMBLEFILES = assemble.c assemble_utils.c
#.PHONY: all clean
all: emulate assemble
......@@ -9,7 +9,7 @@ all: emulate assemble
emulate: emulate.o fetch.o decode.o execute.o instrType.o
$(CC) $(CFLAGS) $(EMULATEFILES) -o emulate
assemble: assemble.o readFile.o
assemble: assemble.o assemble_utils.o
$(CC) $(CFLAGS) $(ASSEMBLEFILES) -o assemble
clean:
......
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include "readFile.h"
#include "assemble_utils.h"
#define MAX_SIZE_OF_STRING 50
int main(int argc, char **argv) {
assert(argc == 3);
int length = getLengthOfFile(argv[1]);
char **instruction = calloc(length, sizeof(char *));
if (!instruction) {
perror("Node allocation failed!");
if (argc != 3) {
perror("Must only provide two arguments!");
exit(EXIT_FAILURE);
}
for (int i = 0; i < length; i++) {
instruction[i] = calloc(MAX_SIZE_OF_STRING, sizeof(char));
if (!instruction[i]) {
perror("Node allocation failed!");
exit(EXIT_FAILURE);
}
}
readSourceFile(argv[1], instruction);
for (int i = 0; i < length; i++) {
printf("%s\n", instruction[i]);
}
free(instruction);
for (int i = 0; i < length; i++) {
free(instruction[i]);
}
FILE *fileSrc = fopen(argv[1], "r");
FILE *fileDest = fopen(argv[2], "w");
second_pass(fileSrc, fileDest);
fclose(fileSrc);
fclose(fileDest);
return EXIT_SUCCESS;
}
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include "assemble_utils.h"
//return statements not included yet..
//need way to calculate Operand2..
//need to make way to read registers..
//special instructions TODO..
static const char *mnemonicsList[] = {
"add", "sub", "rsb", "and", "eor", "orr", "mov", "tst", "teq", "cmp", "mul",
"mla", "ldr", "str", "beq", "bne", "bge", "blt", "bgt", "ble", "b", "lsl", "andeq"
};
int checkBit(int pos, int number) {
return (number >> pos) % pos != 0;
}
void second_pass(FILE *srcFile, FILE *dstFile) {
int currentAddress = 0;
char *buffer = calloc(50, sizeof(char));
memset(buffer, 0, sizeof(char) * sizeof(buffer));
while (fgets(buffer, 50, srcFile)) {
int len = strlen(buffer);
if (buffer[len - 1] == ':') {
continue;
}
int instruction = 0;
instruction = generateBinary(buffer);
fwrite(&instruction, sizeof(int), 1, dstFile);
currentAddress += 4;
memset(buffer, 0, sizeof(char) * sizeof(buffer));
}
free(buffer);
}
void setBitAtPos(int pos, int value, int *number) {
*number |= (value << pos);
}
int generateBinary(char *buffer) {
//int len = strlen(buffer);
char *sep = " ,", *token = strtok(buffer, sep), operands[6][20];
memset(operands, 0, sizeof(operands));
int mnemonic = findMnemonic(token), noOperands = 0;
while (token != NULL) {
token = strtok(NULL, sep);
if (token) {
strcpy(operands[noOperands], token);
noOperands++;
}
}
if (mnemonic < MUL) {
return assembleDataProcessing(mnemonic, operands);
}
if (mnemonic < LDR) {
return assembleMultiply(mnemonic, operands);
}
if (mnemonic < BEQ) {
return assembleSIngleDataTransfer(mnemonic, operands);
}
if (mnemonic < LSLOP) {
return assembleBranch(mnemonic, operands);
}
return assembleSpecial(mnemonic, operands);
}
int findMnemonic(char *p) {
int i;
for (i = 0; i <= 22; i++) {
if (!strcmp(p, mnemonicsList[i])) {
return i;
}
}
return -1; //instruction not found
}
int getOperand2(char operands[20]) {
int result = 0;
if (operands[2] == 'x') {
result = (int) strtol(operands + 1, NULL, 0); //Converts a hex string into an integer
} else {
result = atoi(operands + 1);
}
return result;
}
int isImmediate(char operands[20]) {
if (operands[0] == '#') {
return 1;
}
return 0;
}
int assembleDataProcessing(enum mnemonics mnemonic, char operands[6][20]) {
int result = 0, opCode, cond = 14; //14 = 1110
setBitAtPos(28, cond, &result);
if (mnemonic >= ADD && mnemonic <= ORR) {
switch (mnemonic) {
case ADD:
opCode = 4; //0100
break;
case SUB:
opCode = 2; //0010
break;
case RSB:
opCode = 3; //0011
break;
case AND:
opCode = 0; //0000
break;
case EOR:
opCode = 1; //0001
break;
case ORR:
opCode = 12; //1100
break;
default:
perror("Invalid mnemonic");
}
int rd = atoi(operands[0] + 1), rn = atoi(operands[1] + 1);
setBitAtPos(21, opCode, &result);
setBitAtPos(16, rn, &result);
setBitAtPos(12, rd, &result);
int operand2 = getOperand2(operands[2]);
int immediate = isImmediate(operands[2]);
setBitAtPos(25, immediate, &result);
setBitAtPos(0, operand2, &result);
return result;
}
if (mnemonic == MOV) {
int rd = atoi(operands[0] + 1);
opCode = 13; //1101
setBitAtPos(21, opCode, &result);
setBitAtPos(12, rd, &result);
int operand2 = getOperand2(operands[1]);
int immediate = isImmediate(operands[1]);
setBitAtPos(25, immediate, &result);
setBitAtPos(0, operand2, &result);
return result;
}
switch (mnemonic) {
case TST:
opCode = 8; //1000
break;
case TEQ:
opCode = 9; //1001
break;
case CMP:
opCode = 10; //1010
break;
default:
perror("Invalid mnemonic");
}
int rn = 0;
setBitAtPos(20, 1, &result);
setBitAtPos(21, opCode, &result);
setBitAtPos(16, rn, &result);
return result;
}
int assembleMultiply(enum mnemonics mnemonic, char operands[6][20]) {
int result = 0, cond = 14, mask = 9;
int rd = atoi(operands[0] + 1), rs = atoi(operands[2] + 1);
int rm = atoi(operands[1] + 1); //1110, 1001
setBitAtPos(28, cond, &result);
setBitAtPos(16, rd, &result);
setBitAtPos(8, rs, &result);
setBitAtPos(4, mask, &result);
setBitAtPos(0, rm, &result);
if (mnemonic == MLA) {
int rn = atoi(operands[3] + 1);
setBitAtPos(12, rn, &result);
setBitAtPos(21, 1, &result);
}
return result;
}
int assembleSIngleDataTransfer(enum mnemonics mnemonic, char operands[6][20]) {
int result = 0, cond = 14; //1110
int rd = atoi(operands[0] + 1);
setBitAtPos(28, cond, &result);
setBitAtPos(26, 1, &result);
if (mnemonic == LDR) {
setBitAtPos(20, 1, &result);
}
return result;
}
int assembleBranch(enum mnemonics mnemonic, char operands[6][20]) {
int result = 0, cond = 14, mask = 5; //1110, 101
if (mnemonic >= BEQ && mnemonic <= B) {
switch (mnemonic) {
case BEQ:
cond = 0; //0000
break;
case BNE:
cond = 1; //0001
break;
case BGE:
cond = 10; //1010
break;
case BLT:
cond = 11; //1011
break;
case BGT:
cond = 12; //1100
break;
case BLE:
cond = 13; //1101
break;
case B:
cond = 14; //1110
break;
default:
perror("Invalid mnemonic");
}
}
setBitAtPos(28, cond, &result);
setBitAtPos(25, mask, &result);
return result;
}
int assembleSpecial(enum mnemonics mnemonic, char operands[6][20]) {
if (mnemonic == ANDEQ) {
return 0;
}
strcpy(operands[3], operands[1]);
strcpy(operands[1], operands[0]);
strcpy(operands[2], "lsl");
return assembleDataProcessing(MOV, operands);
}
#ifndef ASSEMBLE_UTILS_H
#define ASSEMBLE_UTILS_H
#include <stdio.h>
enum mnemonics {
ADD, SUB, RSB, AND, EOR, ORR, MOV, TST, TEQ, CMP, MUL, MLA, LDR, STR, BEQ, BNE, BGE, BLT, BGT, BLE, B, LSLOP, ANDEQ
};
void second_pass(FILE *srcFile, FILE *dstFile);
int generateBinary(char *buffer);
int findMnemonic(char *p);
int assembleDataProcessing(enum mnemonics mnemonic, char operands[6][20]);
int assembleMultiply(enum mnemonics mnemonic, char operands[6][20]);
int assembleSIngleDataTransfer(enum mnemonics mnemonic, char operands[6][20]);
int assembleBranch(enum mnemonics mnemonic, char operands[6][20]);
int assembleSpecial(enum mnemonics mnemonic, char operands[6][20]);
int checkBit(int pos, int number);
void setBitAtPos(int pos, int value, int *number);
void setBitSequence(int pos1, int pos2, int value, int *number);
#endif
#ifndef EMULATE_H
#define EMULATE_H
#define NREGS 17
#define STACK_SIZE 16384 //Defined stack as ints which are 4 bytes so (64*1024)/4
#define PC 15
......@@ -9,3 +12,4 @@ void printResult(armstate *state, int numOfInstr);
void startCycle(armstate *state);
int main(int argc, char **argv);
#endif
#include <stdio.h>
int getLengthOfFile(char *fileName) {
FILE *ptr = fopen(fileName, "r");
int size = 0;
char c = getc(ptr);
while (c != EOF) {
if (c == '\n' || c == ' ') {
size++;
}
c = getc(ptr);
}
fclose(ptr);
return size;
}
void readSourceFile(char *fileName, char **instruction) {
int i = 0;
FILE *ptr = fopen(fileName, "r");
while (!feof(ptr)) {
fscanf(ptr, "%s", instruction[i]);
i++;
}
fclose(ptr); //Closes file "filename"
}
int getLengthOfFile(char *fileName);
void readSourceFile(char *fileName, char **instruction);
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment