asm_parser/assembler.c

70 lines
2.4 KiB
C

/***************************************************************************
* file name : assembler.c *
* author : *
* description : This program will assemble a .ASM file into a .OBJ file *
* This program will use the "asm_parser" library to achieve *
* its functionality. *
* *
***************************************************************************
*
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "asm_parser.h"
int main(int argc, char **argv) {
if (argc < 2) {
printf("Usage: %s <assembly_file.asm>\n", argv[0]);
return 1;
}
char *filename = argv[1]; // name of ASM file
char program[ROWS][COLS]; // ASM file line-by-line
char program_bin_str[ROWS][17]; // instructions converted to a binary string
unsigned short int program_bin[ROWS]; // instructions in binary (HEX)
int num_lines = read_asm_file(filename, program);
if (num_lines != 0) {
return num_lines; // Return error code from read_asm_file
}
int instr_count = 0;
for (int i = 0; i < ROWS && program[i][0] != '\0'; i++) {
char *line = program[i];
char instr_bin_str[17] = {0};
int ret = parse_instruction(line, instr_bin_str);
if (ret == 0) {
strcpy(program_bin_str[instr_count], instr_bin_str);
unsigned short int bin = str_to_bin(instr_bin_str);
if (bin == 6) { // Error code from str_to_bin
printf("Error on line %d: %s\n", i + 1, line);
return 6;
}
// if program_bin is full, return error
if (instr_count >= ROWS) {
printf("Error: Program too large\n");
return 0;
}
program_bin[instr_count] = bin;
instr_count++;
} else {
printf("Error on line %d: %s\n", i + 1, line);
return ret;
}
// ret == 0 means successful parsing
}
// Write the object file
char obj_filename[256];
strcpy(obj_filename, filename);
char *dot = strrchr(obj_filename, '.');
if (dot != NULL) {
strcpy(dot, ".obj");
} else {
strcat(obj_filename, ".obj");
}
int ret = write_obj_file(obj_filename, program_bin, instr_count);
if (ret != 0) {
return ret; // Return error code from write_obj_file
}
printf("Successfully assembled %s to %s\n", filename, obj_filename);
return 0;
}