From 2f6a51855571ee12bad247ac026aa02a061800f0 Mon Sep 17 00:00:00 2001 From: Charles Cabergs Date: Tue, 16 Nov 2021 18:42:30 +0100 Subject: Updated to generate correct assembly (segfaults) --- bfc.c | 71 +++++++++++++++++++++++++++++++++------------ examples/add_2_5.bf | 20 +++++++++++++ examples/getchar_putchar.bf | 1 + 3 files changed, 74 insertions(+), 18 deletions(-) create mode 100644 examples/add_2_5.bf create mode 100644 examples/getchar_putchar.bf diff --git a/bfc.c b/bfc.c index cb1b0f9..2d4c8f9 100644 --- a/bfc.c +++ b/bfc.c @@ -2,52 +2,87 @@ #include #include -const size_t buffer_size = 256; -const char* asm_filename = "out.asm"; +static const size_t buffer_size = 256; +static const char* asm_filename = "out.asm"; + +static const char *write_syscall = "0x2000004"; +static const char *read_syscall = "0x2000003"; + +#define LABEL_COUNT_STACK_SIZE 256 +static size_t label_stack[LABEL_COUNT_STACK_SIZE + 1] = {0}; +static size_t label_stack_frame = 0; int main(int argc, char *argv[]) { - FILE* file = fopen(asm_filename, "w"); + FILE *input_file = NULL; + if (argc == 2) + input_file = fopen(argv[1], "r"); + else + input_file = stdin; + + /* FILE* output_file = fopen(asm_filename, "w"); */ + FILE *output_file = stdout; fprintf( - file, + output_file, + "global _start\n" "section .bss\n" - "buffer: resb %zu\n" - "section .text\n", - "mov rax buffer\n", + "\tbuffer: resb %zu\n\n" + "section .text\n" + "_start:\n" + "\tmov rbx, buffer\n", buffer_size ); + size_t label_frame_id; char c; - while ((c = fgetc(file)) != EOF) + while ((c = fgetc(input_file)) != EOF) { switch (c) { case '>': - fputs("inc rax"); + fprintf(output_file, " inc rbx ; >\n"); break; case '<': - fputs("dec rax"); + fprintf(output_file, " dec rbx ; <\n"); break; case '+': - fputs("inc [rax]"); + fprintf(output_file, " inc byte [rbx] ; +\n"); break; case '-': - fputs("dec [rax]"); + fprintf(output_file, " dec byte [rbx] ; -\n"); break; case '.': - // putchar + fprintf(output_file, " mov rdi, 1 ; .\n"); + fprintf(output_file, " mov rsi, rbx ; .\n"); + fprintf(output_file, " mov rdx, 1 ; .\n"); + fprintf(output_file, " mov rax, %-10s ; .\n", write_syscall); + fprintf(output_file, " syscall ; .\n"); break; case ',': - // getchar + fprintf(output_file, " mov rdi, 0 ; ,\n"); + fprintf(output_file, " mov rsi, rbx ; ,\n"); + fprintf(output_file, " mov rdx, 1 ; ,\n"); + fprintf(output_file, " mov rax, %-10s ; ,\n", read_syscall); + fprintf(output_file, " syscall ; ,\n"); break; case '[': - // jump to next ] if byte at data ptr is 0 + label_frame_id = label_stack[label_stack_frame]; + fprintf(output_file, "label_open_%03d_%03d: ; [\n", label_stack_frame, label_frame_id); + fprintf(output_file, " cmp byte [rbx], 0 ; [\n"); + fprintf(output_file, " je label_close_%03d_%03d ; [\n", label_stack_frame, label_frame_id); + label_stack_frame++; break; - case '[': - // jump to prev [ if byte at data ptr is not 0 + case ']': + label_stack_frame--; + label_frame_id = label_stack[label_stack_frame]; + fprintf(output_file, "label_close_%03d_%03d: ; ]\n", label_stack_frame, label_frame_id); + fprintf(output_file, " cmp byte [rbx], 0 ; ]\n"); + fprintf(output_file, " jne label_open_%03d_%03d ; ]\n", label_stack_frame, label_frame_id); + label_stack[label_stack_frame]++; break; case ';': - // comment + while (c != EOF && c != '\n') + c = fgetc(input_file); break; default: // error diff --git a/examples/add_2_5.bf b/examples/add_2_5.bf new file mode 100644 index 0000000..a6425d7 --- /dev/null +++ b/examples/add_2_5.bf @@ -0,0 +1,20 @@ +++ ; Cell c0 = 2 +> +++++ ; Cell c1 = 5 + +[ ; Start your loops with your cell pointer on the loop counter (c1 in our case) +< + ; Add 1 to c0 +> - ; Subtract 1 from c1 +] ; End your loops with the cell pointer on the loop counter + +; At this point our program has added 5 to 2 leaving 7 in c0 and 0 in c1 +; but we cannot output this value to the terminal since it is not ASCII encoded. + +; To display the ASCII character "7" we must add 48 to the value 7. +; We use a loop to compute 48 = 6 * 8. + +++++ ++++ ; c1 = 8 and this will be our loop counter again +[ +< +++ +++ ; Add 6 to c0 +> - ; Subtract 1 from c1 +] +< . ; Print out c0 which has the value 55 which translates to "7"! diff --git a/examples/getchar_putchar.bf b/examples/getchar_putchar.bf new file mode 100644 index 0000000..f36f02a --- /dev/null +++ b/examples/getchar_putchar.bf @@ -0,0 +1 @@ +,. -- cgit