diff --git a/src/assembler/assemble.c b/src/assembler/assemble.c index c4615bf..4774d15 100644 --- a/src/assembler/assemble.c +++ b/src/assembler/assemble.c @@ -5,6 +5,8 @@ #include #include #include +#include +#include #include "../instruction.h" @@ -201,6 +203,56 @@ Program createProgramFromText(const char* input) { return program; } -void assemble(const char* input, const char* outputFileName) { - Program program = createProgramFromText(input); +void serializeProgramToFile(Program* program, const char* outputFileName) { + + FILE* fp = fopen(outputFileName, "wb"); + if (fp == NULL) { + fprintf(stderr, "Couldn't open file %s for writing\n", outputFileName); + exit(1); + } + + for (size_t i = 0; i < program->len; i++) { + Instruction* inst = &program->at[i]; + + uint16_t packed = 0; + + packed |= (SerializedInst)(inst->opcode & 0b0000000000001111) ; + packed |= (SerializedInst)(inst->operands[0] & 0b0000000000001111) << 4; + packed |= (SerializedInst)(inst->operands[1] & 0b0000000000001111) << 8; + packed |= (SerializedInst)(inst->operands[2] & 0b0000000000001111) << 12; + + size_t written = fwrite(&packed, sizeof(uint16_t), 1, fp); + if (written != 1) { + fprintf(stderr, "failed to write %" PRIx16 " into file %s\n", packed, outputFileName); + fclose(fp); + exit(1); + } + + if (inst->hasImm16) { + size_t written = fwrite(&inst->immediate, sizeof(uint16_t), 1, fp); + if (written != 1) { + fprintf(stderr, "failed to write %" PRIx16 " into file %s\n", packed, outputFileName); + fclose(fp); + exit(1); + } + } + } + + fclose(fp); + +} + +void assemble(const char* input, const char* outputFileName) { + clock_t start = clock(); + Program program = createProgramFromText(input); + clock_t parsed = clock(); + serializeProgramToFile(&program, outputFileName); + clock_t serialized = clock(); + + printf("Finished assembling %s, took %lg seconds (%lg secs parsing, %lg secs serializing)\n", + outputFileName, + (serialized - start) / (long double) CLOCKS_PER_SEC, + (parsed - start) / (long double) CLOCKS_PER_SEC, + (serialized - parsed) / (long double) CLOCKS_PER_SEC + ); }