2024-10-30 11:29:20 +08:00
|
|
|
/***************************************************************************
|
|
|
|
|
* 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"
|
|
|
|
|
|
2024-10-30 16:31:10 +08:00
|
|
|
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);
|
2024-10-30 17:34:54 +08:00
|
|
|
if (num_lines != 0) {
|
|
|
|
|
return num_lines; // Return error code from read_asm_file
|
2024-10-30 16:31:10 +08:00
|
|
|
}
|
|
|
|
|
int instr_count = 0;
|
2024-10-30 17:34:54 +08:00
|
|
|
for (int i = 0; i < ROWS && program[i][0] != '\0'; i++) {
|
2024-10-30 16:31:10 +08:00
|
|
|
char *line = program[i];
|
2024-10-30 17:34:54 +08:00
|
|
|
char instr_bin_str[17] = {0};
|
2024-10-30 16:31:10 +08:00
|
|
|
int ret = parse_instruction(line, instr_bin_str);
|
2024-10-30 17:34:54 +08:00
|
|
|
if (ret == 0) {
|
2024-10-30 16:31:10 +08:00
|
|
|
strcpy(program_bin_str[instr_count], instr_bin_str);
|
2024-10-30 17:34:54 +08:00
|
|
|
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 i + 1;
|
|
|
|
|
}
|
|
|
|
|
program_bin[instr_count] = bin;
|
2024-10-30 16:31:10 +08:00
|
|
|
instr_count++;
|
2024-10-30 17:44:50 +08:00
|
|
|
} else {
|
2024-10-30 17:34:54 +08:00
|
|
|
printf("Error on line %d: %s\n", i + 1, line);
|
|
|
|
|
return i + 1;
|
2024-10-30 16:31:10 +08:00
|
|
|
}
|
2024-10-30 17:34:54 +08:00
|
|
|
// ret == 0 means successful parsing
|
2024-10-30 16:31:10 +08:00
|
|
|
}
|
|
|
|
|
// 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);
|
2024-10-30 17:34:54 +08:00
|
|
|
if (ret != 0) {
|
|
|
|
|
return ret; // Return error code from write_obj_file
|
2024-10-30 16:31:10 +08:00
|
|
|
}
|
|
|
|
|
printf("Successfully assembled %s to %s\n", filename, obj_filename);
|
|
|
|
|
return 0;
|
2024-10-30 17:34:54 +08:00
|
|
|
}
|