diff --git a/example.asm b/example.asm index 7f06c72..6f40e40 100644 --- a/example.asm +++ b/example.asm @@ -1,4 +1,4 @@ main: - push "Hello, world!\n" + push.string "Hello, world!\n" # Записываем строку push byte 0x00 syscall \ No newline at end of file diff --git a/ntsys b/ntsys index c4b0bb9..803a5bc 100755 Binary files a/ntsys and b/ntsys differ diff --git a/ntsys-assembler.h b/ntsys-assembler.h new file mode 100644 index 0000000..93a89b1 --- /dev/null +++ b/ntsys-assembler.h @@ -0,0 +1,308 @@ +#if (!defined(NTSYS_ASSEMBLER_H___)) +#define NTSYS_ASSEMBLER_H___ + +#define __READ_FILE_WITH_EOF_OR_LN ((c = getc(fp)) != EOF && c != '\n' && c != '\r') +#define is_space(c) (c >= 0 && c <= 32) +#define __SPACE_SHIFT while (is_space(st[pos])) { pos ++; } +#define __NEXT_ARG {__e_byte_t isStr = 0;while (!is_space(st[save]) || isStr == 1) { if (st[save] == '"' && st[save - 1] != '\\') {isStr = !isStr;}save ++; }}while (is_space(st[save])) { save ++; }{size_t n_p = save;__e_byte_t isStr = 0;while (!is_space(st[n_p]) || isStr == 1) { if (st[n_p] == '"' && st[n_p - 1] != '\\') {isStr = !isStr;}n_p ++; }st[n_p] = '\0';} +#define get_mem_pos() *mem_pos = ftell(fp) == 0 ? 0 : ftell(fp) - 1; + +static char* get_str(char* ptr, FILE* fp) { + if (ptr != NULL) { + free(ptr); + } + unsigned long len = 0; + int c; + { + unsigned long save_ptr = ftell(fp); + while (__READ_FILE_WITH_EOF_OR_LN) { + len ++; + } + fseek(fp, save_ptr, SEEK_SET); + } + if (len == 0) return NULL; + ptr = malloc(len); + if (ptr == NULL) { + ntsys_error("Out of memory!"); + return NULL; + } + len = 0; + while (__READ_FILE_WITH_EOF_OR_LN) { + ptr[len] = c; + len ++; + } + return ptr; +} + +/* + * XX - шестнадцатиричное число + * :S - тип данных + * :D - сами данные + * :O - метка перехода + * + * ------------------ Формат ------------------- + * + * имя_комманды=описание + * + */ + +char __fun_names_ntsys[][20] = { + "push=00:S:D", + "pop=01:S", + "push.string=02:D" +}; + +static size_t __index_of(char* arr, char c) { + size_t i = 0; + while (i < strlen(arr)) { + if (arr[i] == c) break; + i ++; + } + return i; +} + +word_t* shfdiyde_labels = NULL; +char** shdgsjgdsjjgds_names = NULL; +size_t sfdfshgshgfs_lb_pos = 0; +#define labels_names shdgsjgdsjjgds_names +#define labels shfdiyde_labels +#define lb_pos sfdfshgshgfs_lb_pos + +int ntsys_asm_from_string(size_t* mem_pos, char* st, FILE* fp) { + if (st == NULL) { + ntsys_error("Null Pointer Exception!"); + return EXIT_FAILURE; + } + size_t len = strlen(st); + size_t pos = 0; + __e_byte_t isStr = 0; + while (pos < len) { + size_t sP = pos; + if (pos == 0) sP = 1; + if (st[pos] == '"' && st[sP - 1] != '\\') { + isStr = !isStr; + } + if (st[pos] == '#' && isStr == 0) { + st[pos] = '\0'; + break; + } + pos ++; + } + if (isStr == 1) { + ntsys_error("Find no close string!"); + return EXIT_FAILURE; + } + isStr = 0; + len = strlen(st); + pos = 0; + { + __SPACE_SHIFT; + size_t save = pos; + while (!is_space(st[pos])) { pos ++; } + st[pos] = '\0'; + size_t arr_len = sizeof(__fun_names_ntsys) / sizeof(__fun_names_ntsys[0]); + size_t i = 0; + while (i < arr_len) { + char eq[20]; + strcpy(eq, __fun_names_ntsys[i]); + size_t par_pos = 0; + { + size_t u = 0; + size_t d = strlen(__fun_names_ntsys[i]); + while (u < d) { + eq[u] = __fun_names_ntsys[i][u]; + if (eq[u] == '=') { + eq[u] = '\0'; + par_pos = u + 1; + break; + } + u ++; + } + } + char* h = (st + save); + if (h[strlen(st + save)] == ':') { + get_mem_pos(); + h[strlen(h - 1)] = '\0'; + labels_names[lb_pos] = h; + labels[lb_pos++] = ((word_t)*mem_pos + 1); + break; + }; + if (strcmp((st + save), eq) == 0) { + size_t d = strlen(__fun_names_ntsys[i] + par_pos); + size_t p = 0; + puts(st + save); + __e_byte_t data_type = 1; + while (p < d) { + char* str = &__fun_names_ntsys[i][par_pos]; + if (str[p] == ':') { + p ++; + switch (str[p]) { + case 'D': + { + __NEXT_ARG; + __e_byte_t sys_cnt = 10; + __e_byte_t is_str = 0; + if (st[save] == '"') { + is_str = 1; + size_t f = 0; + save ++; + while (1) { + if (st[save + f] == '"' && st[save + f - 1] != '\\') { + putc('\0', fp); + break; + } + if (st[save + f] == '\\' && st[save + f - 1] != '\\') { f ++; continue; } + if (st[save + f - 1] == '\\') { + switch (st[save + f]) { + case '0': + putc('\0', fp); break; + case 'a': + putc('\a', fp); break; + case 'b': + putc('\b', fp); break; + case 't': + putc('\t', fp); break; + case 'n': + putc('\n', fp); break; + case 'v': + putc('\v', fp); break; + case 'f': + putc('\f', fp); break; + case 'r': + putc('\r', fp); break; + case '\\': + putc('\\', fp); break; + default: + ntsys_error("Unknown ident!"); + return EXIT_FAILURE; + } + } else { + putc(st[save + f], fp); + } + f ++; + } + } else if (st[save + 1] == 'x') { + sys_cnt = 16; + } else if (st[save + 1] == 'b') { + sys_cnt = 2; + } + if (is_str == 0) { + if (sys_cnt != 10) { + save += 2; + } + char* arr = NULL; + long cnt = strtol(&st[save], &arr, sys_cnt); + switch (data_type) { + case 0x01: fwrite((__e_byte_t*)((byte_t*)&cnt), 1, sizeof(byte_t), fp); + break; + case 0x02: fwrite((__e_byte_t*)((word_t*)&cnt), 1, sizeof(word_t), fp); + break; + case 0x04: fwrite((__e_byte_t*)((dword_t*)&cnt), 1, sizeof(dword_t), fp); + break; + case 0x08: fwrite((__e_byte_t*)((qword_t*)&cnt), 1, sizeof(qword_t), fp); + break; + case 0xF1: fwrite((__e_byte_t*)((sbyte_t*)&cnt), 1, sizeof(sbyte_t), fp); + break; + case 0xF2: fwrite((__e_byte_t*)((sword_t*)&cnt), 1, sizeof(sword_t), fp); + break; + case 0xF4: fwrite((__e_byte_t*)((sdword_t*)&cnt), 1, sizeof(sdword_t), fp); + break; + case 0xF8: fwrite((__e_byte_t*)((sqword_t*)&cnt), 1, sizeof(sqword_t), fp); + break; + } + } + } + break; + case 'S': + { + __NEXT_ARG; + if (strcmp(&st[save], "byte") == 0) { + data_type = 0x01; + } else if (strcmp(&st[save], "word") == 0) { + data_type = 0x02; + } else if (strcmp(&st[save], "dword") == 0) { + data_type = 0x04; + } else if (strcmp(&st[save], "qword") == 0) { + data_type = 0x08; + } else if (strcmp(&st[save], "sbyte") == 0) { + data_type = 0xF1; + } else if (strcmp(&st[save], "sword") == 0) { + data_type = 0xF2; + } else if (strcmp(&st[save], "sdword") == 0) { + data_type = 0xF4; + } else if (strcmp(&st[save], "sqword") == 0) { + data_type = 0xF8; + } else { + ntsys_error("Incorrect datatype!"); + return EXIT_FAILURE; + } + fwrite((__e_byte_t*)&data_type, 1, sizeof(__e_byte_t), fp); + } + break; + case 'O': + { + + } + break; + } + } else { + char* hx = "0123456789ABCDEF"; + __e_byte_t hex = (__index_of(hx, str[p + 1])) | (__index_of(hx, str[p]) << 4); + fputc(hex, fp); + p ++; + } + p ++; + } + break; + } + i ++; + } + } + get_mem_pos(); + printf("Memory position: %zu\n", *mem_pos); + return EXIT_SUCCESS; +} + +int ntsys_compile_asm(char* filename, char* asm_out) { + FILE* fp = fopen(filename, "r"); + if (fp == NULL) { + ntsys_error("Cannot open assembler file!"); + return EXIT_FAILURE; + } + FILE* fw = fopen(asm_out, "wb"); + if (fw == 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 == ':') { + lb_size ++; + } + } + rewind(fp); + labels = malloc(sizeof(word_t) * lb_size); + labels_names = (char**)malloc(sizeof(char*) * lb_size); + while ((st = get_str(st, fp)) != NULL) { + if (ntsys_asm_from_string(&mem_pos, st, fw) != EXIT_SUCCESS) return EXIT_FAILURE; + } + free(st); + fclose(fp); + fclose(fw); + return EXIT_SUCCESS; +} + +#undef __READ_FILE_WITH_EOF_OR_LN +#undef __SPACE_SHIFTsize_t lb_size = 1; +#undef is_space +#undef __NEXT_ARG +#undef get_mem_pos +#undef labels +#undef labels_names +#undef lb_pos + +#endif /* NTSYS_ASSEMBLER_H___ */ \ No newline at end of file diff --git a/ntsys.h b/ntsys.h index 5ed74c2..89303d2 100644 --- a/ntsys.h +++ b/ntsys.h @@ -58,12 +58,13 @@ unsigned int __ntsys_buffer_ptr = 0; int fGH6VSEzu7qNiGVE_stat = EXIT_SUCCESS; -#include "ntfiles.h" - -static void ntsys_error(char* _err) { +void ntsys_error(char* _err) { printf("\033[1mntsys: \033[91m%s\033[0m\n", _err); } +#include "ntfiles.h" +#include "ntsys-assembler.h" + static void __help(void) { puts ( "BINARY Emulator - LICENSE GPL V3" "\n" @@ -193,10 +194,6 @@ int ntsys_api_call(char* filename, unsigned char debug) { return stat; } -int ntsys_compile_asm(char* in_file, char* out_file) { - return EXIT_SUCCESS; -} - int _lib_ntsys_main(int argc, char** argv) { unsigned int t = 1; char* filename = NULL; diff --git a/out.exe b/out.exe new file mode 100644 index 0000000..e89f83d Binary files /dev/null and b/out.exe differ