diff --git a/.vscode/launch.json b/.vscode/launch.json index a8d54f5..946ca46 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -4,6 +4,7 @@ // Для получения дополнительной информации посетите: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ + { "name": "Запустить", "type": "cppdbg", diff --git a/asm-savers.h b/asm-savers.h index 901cc1b..d7a71bf 100644 --- a/asm-savers.h +++ b/asm-savers.h @@ -3,7 +3,7 @@ #define ntsys_exit_if_error(parser) if (!ntsys_asm_arg_new((parser)->string, (parser)->cache)) #define ntsys_run_asm_parser(ss) __ntsys_arg_function_loader(&(ss)) -#define create_ntsys_asm_parser(cache, fp, str, table, table_size, labels) ((ntsys_argument_parser_t){(cache), (fp), (str), (table), (table_size), (labels), NULL, 0, 0}) +#define create_ntsys_asm_parser(cache, fp, str, table, table_size, labels, labels_pos, labels_count, cyc) ((ntsys_argument_parser_t){(cache), (fp), (str), (table), (table_size), (labels), (labels_pos), (labels_count), (cyc)}) #define create_ntsys_asm_save(ss) ((ntsys_asm_save_t){(ss), (ss)}) #define create_ntsys_asm_cache(ss) ((ntsys_asm_cache_t)&(ss)) #define ntsys_asm_arg_new(str, __cache) ((ntsys_get_arg((__cache))) && ((str) = __cache->string)) @@ -32,7 +32,7 @@ char* ntsys_get_str(char* ptr, FILE* fp) { fseek(fp, save_ptr, SEEK_SET); } if (len == 0) return NULL; - ptr = malloc(len); + ptr = malloc(len + 1); if (ptr == NULL) { ntsys_error("Out of memory!"); return NULL; @@ -43,6 +43,13 @@ char* ntsys_get_str(char* ptr, FILE* fp) { len ++; } ptr[len] = '\0'; + size_t i = 0; + __e_byte_t isStr = 0; + while (i < strlen(ptr)) { + if (ptr[i] == '"' && ptr[((i == 0) ? 1 : i) - 1] != '\\') {isStr = !isStr;} + if ((ptr[i] == ';' || ptr[i] == '#') && isStr == 0) ptr[i] = '\0'; + i ++; + } return ptr; } @@ -76,7 +83,7 @@ char* ntsys_get_arg(ntsys_asm_cache_t save) { size_t n_p = 0; __e_byte_t isStr = 0; while (1) { - if (str[n_p] == '"' && str[((n_p == 0) ? 1 : 0) - 1] != '\\') {isStr = !isStr;} + if (str[n_p] == '"' && str[((n_p == 0) ? 1 : n_p) - 1] != '\\') {isStr = !isStr;} if ((is_space(str[n_p]) && isStr == 0) || str[n_p] == '\0') { break; } @@ -85,6 +92,7 @@ char* ntsys_get_arg(ntsys_asm_cache_t save) { save->cache = &str[n_p + 1]; str[n_p] = '\0'; } + if (str[strlen(str) - 1] == '\n' || str[strlen(str) - 1] == '\r') str[strlen(str) - 1] = '\0'; if (strlen(str) == 0) { str = NULL; save->string = NULL; @@ -137,7 +145,7 @@ typedef struct { size_t table_length; char** labels; word_t* labels_positions; - size_t labels_count; + size_t* labels_count; byte_t is_rewrite; } ntsys_argument_parser_t; @@ -165,12 +173,12 @@ static void __input_datatype(ntsys_argument_parser_t* parser, byte_t* mode) { } else if (strcmp(str, "sqword") == 0) { data_type = 0xF8; } else if (strcmp(str, "db") == 0) { - data_type = 0xBC; + data_type = 0xB2; } else { ntsys_error("Incorrect datatype!"); return; } - if (data_type == 0xBC) fputc((__e_byte_t)0x02, parser->fp); + if (data_type == 0xB2) fputc((__e_byte_t)0x02, parser->fp); else fputc((__e_byte_t)data_type, parser->fp); *mode = data_type; } @@ -182,13 +190,25 @@ static void __write_label(ntsys_argument_parser_t* parser) { return; } size_t i = 0; - while (i < parser->labels_count) { + /* printf("Count: 0x%04lX\n", *(parser->labels_count)); */ + while (i < *(parser->labels_count)) { + /* printf("Label: \"%s\" to \"%s\"\n", parser->string, parser->labels[i]); */ if (strcmp(parser->string, parser->labels[i]) == 0) { - fwrite(&(parser->labels_positions[i]), 1, sizeof(word_t), parser->fp); + word_t cnt = parser->labels_positions[i]; + int __i = 1; + if (!(*((char *)&__i) == 1)) { + /* BIG ENDIAN */ + byte_t* ar = (byte_t*)&cnt; + byte_t s = ar[0]; + ar[0] = ar[1]; + ar[1] = s; + } + fwrite(&cnt, 1, sizeof(word_t), parser->fp); return; } i ++; } + } static void __input_data(ntsys_argument_parser_t* parser, byte_t* mode) { @@ -213,6 +233,20 @@ static void __input_data(ntsys_argument_parser_t* parser, byte_t* mode) { } long cnt = strtol(str, NULL, count_system); FILE* fp = parser->fp; + int __i = 1; + if (!(*((char *)&__i) == 1)) { + /* BIG ENDIAN */ + if ((data_type & 0x0F) != 0x01) { + size_t i = 0; + byte_t* ar = (byte_t*)&cnt; + while (i < (data_type & 0x0F)) { + byte_t s = ar[i]; + ar[i] = ar[(data_type & 0x0F) - i - 1]; + ar[(data_type & 0x0F) - i - 1] = s; + i ++; + } + } + } switch (data_type) { case 0x01: fwrite((__e_byte_t*)((byte_t*)&cnt), 1, sizeof(byte_t), fp); break; @@ -232,7 +266,7 @@ static void __input_data(ntsys_argument_parser_t* parser, byte_t* mode) { break; } } else { - if (data_type != 0xBC) { + if (data_type != 0xB2) { ntsys_error("Incorrect datatype! For jump to label please use db type!"); return; } @@ -251,17 +285,32 @@ static int __arg_writer(char* str, ntsys_argument_parser_t* parser, byte_t* mode } else { byte_t x = strtol(str, NULL, 16); fputc((char)x, parser->fp); + /* printf("Input: 0x%04X\n", x); */ } return EXIT_SUCCESS; } +int __load_label(ntsys_argument_parser_t* parser) { + char* str = parser->string; + str[strlen(str) - 1] = '\0'; + parser->labels[*(parser->labels_count)] = malloc(strlen(str) + 1); + if (parser->labels[*(parser->labels_count)] == NULL) { + ntsys_error("Out of memory!"); + return EXIT_FAILURE; + } + strcpy(parser->labels[*(parser->labels_count)], str); + parser->labels_positions[*(parser->labels_count)] = (word_t)(ftell(parser->fp)); + /* printf("Label: \"%s\" on 0x%08X\n", str, parser->labels_positions[*(parser->labels_count)]); */ + *parser->labels_count += 1; + return EXIT_SUCCESS; +} + static int select_argument(ntsys_argument_parser_t* parser) { size_t i = 0; byte_t internal = 0x00; char* str = parser->string; - if (str[strlen(str) - 1] == ':' && !parser->is_rewrite) { - /* TODO: Добавить метки */ - return EXIT_SUCCESS; + if (str[strlen(str) - 1] == ':' && parser->is_rewrite == 0) { + return __load_label(parser); } char buf[64]; char** table = parser->table; diff --git a/example.asm b/example.asm index c80d446..654a0c5 100644 --- a/example.asm +++ b/example.asm @@ -1,6 +1,7 @@ -main: +main: ; Метка main push.string "Hello, world!\n" ; Записываем строку - push byte 0x00 - syscall - push db main - jmp \ No newline at end of file + push byte 0x00 ; Запись номера SYSCALL + syscall ; Системный вызов +load: ; Цикл, здесь программа "зависнет" + push db load ; Адрес как db + jmp ; Выполняем \ No newline at end of file diff --git a/ntsys b/ntsys index 40fcbbf..69edfff 100755 Binary files a/ntsys and b/ntsys differ diff --git a/ntsys-assembler.h b/ntsys-assembler.h index e7ea542..e464661 100644 --- a/ntsys-assembler.h +++ b/ntsys-assembler.h @@ -17,11 +17,10 @@ char* ntsys_asm_table[] = { "push=00:T:D" }; -int ntsys_asm_from_string(size_t* mempos, char* str, FILE* fp) { - ntsys_labels_array_t labels = NULL; +int ntsys_asm_from_string(size_t* mempos, char* str, FILE* fp, byte_t cycle, ntsys_labels_array_t labels, word_t* labels_pos, size_t* labels_count) { ntsys_asm_save_t __save = create_ntsys_asm_save(str); ntsys_asm_cache_t __cache = create_ntsys_asm_cache(__save); - ntsys_argument_parser_t parser = create_ntsys_asm_parser(__cache, fp, str, ntsys_asm_table, ntsys_command_count, labels); + ntsys_argument_parser_t parser = create_ntsys_asm_parser(__cache, fp, str, ntsys_asm_table, ntsys_command_count, labels, labels_pos, labels_count, cycle); return ntsys_run_asm_parser(parser); } @@ -32,32 +31,81 @@ int ntsys_compile_asm(char* filename, char* asm_out) { return EXIT_FAILURE; } FILE* fw = fopen(asm_out, "wb"); - if (fw == NULL) { + FILE* tmp = tmpfile(); + if (fw == NULL || tmp == NULL) { ntsys_error("Cannot create or rewrite output file!"); fclose(fp); return EXIT_FAILURE; } char* st = NULL; size_t mem_pos = 0; - size_t lb_size = 1; - int c; - while ((c = getc(fp)) != EOF) { - if (c == ':') { + size_t lb_size = 0; + while ((st = ntsys_get_str(st, fp)) != NULL) { + char* cp = st; + ntsys_asm_save_t __save = create_ntsys_asm_save(cp); + ntsys_asm_cache_t sv = create_ntsys_asm_cache(__save); + char* str = ntsys_get_arg(sv); + if (str[strlen(str) - 1] == ':') { lb_size ++; } } + free(st); + char** labels = malloc(sizeof(char*) * lb_size); + word_t* labels_pos = malloc(sizeof(word_t) * lb_size); + size_t u = 0; + while (u < lb_size) { + labels[u] = NULL; + u ++; + } rewind(fp); + FILE* ff = tmp; + size_t labels_count = 0; while ((st = ntsys_get_str(st, fp)) != NULL) { - if (ntsys_asm_from_string(&mem_pos, st, fw) != EXIT_SUCCESS) { + if (ntsys_asm_from_string(&mem_pos, st, tmp, 0, labels, labels_pos, &labels_count) != EXIT_SUCCESS) { free(st); fclose(fp); + fclose(tmp); fclose(fw); + size_t i = 0; + while (i < lb_size) { + if (labels[i] != NULL) free(labels[i]); + i ++; + } + free(labels); + free(labels_pos); return EXIT_FAILURE; } } + ff = fw; + free(st); + rewind(fp); + while ((st = ntsys_get_str(st, fp)) != NULL) { + if (ntsys_asm_from_string(&mem_pos, st, ff, 1, labels, labels_pos, &labels_count) != EXIT_SUCCESS) { + free(st); + fclose(fp); + fclose(tmp); + fclose(fw); + size_t i = 0; + while (i < lb_size) { + if (labels[i] != NULL) free(labels[i]); + i ++; + } + free(labels); + free(labels_pos); + return EXIT_FAILURE; + } + } + fclose(tmp); free(st); fclose(fp); fclose(fw); + size_t i = 0; + while (i < lb_size) { + if (labels[i] != NULL) free(labels[i]); + i ++; + } + free(labels); + free(labels_pos); return EXIT_SUCCESS; } diff --git a/out.exe b/out.exe index b5bde7b..4fed40a 100644 Binary files a/out.exe and b/out.exe differ