forked from jserv/jit-construct
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcompiler-x86.c
85 lines (82 loc) · 1.92 KB
/
compiler-x86.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#include <stdio.h>
#include <stdlib.h>
#include "util.h"
#include "stack.h"
void compile(const char * const text_body)
{
int num_brackets = 0;
int matching_brackets = 0;
struct stack stack = { .size = 0, .items = {0}};
const char * const prologue =
".section .text\n"
".global main\n"
"main:\n"
" pushl %ebp\n"
" movl %esp, %ebp\n"
" addl $-3008, %esp\n"
" leal (%esp), %edi\n"
" movl $0, %esi\n"
" movl $3000, %edx\n"
" call memset\n"
" movl %esp, %ecx";
puts(prologue);
for (unsigned long i = 0; text_body[i] != '\0'; ++i) {
switch (text_body[i]){
case '>':
puts(" inc %ecx");
break;
case '<':
puts(" dec %ecx");
break;
case '+':
puts(" incb (%ecx)");
break;
case '-':
puts(" decb (%ecx)");
break;
case '.':
puts(" call putchar");
break;
case ',':
puts(" call getchar");
puts(" movb %al, (%ecx)");
break;
case '[':
if (stack_push(&stack, num_brackets)==0) {
puts (" cmpb $0, (%ecx)");
printf(" je bracket_%d_end\n", num_brackets);
printf("bracket_%d_start:\n", num_brackets++);
} else {
err("out of stack space");
}
break;
case ']':
if (stack_pop(&stack, &matching_brackets)==0) {
puts ("cmpb $0, (%ecx)");
printf(" jne bracket_%d_start\n", matching_brackets);
printf("bracket_%d_end:\n", matching_brackets);
} else {
err("stack underflow, unmatched");
}
break;
}
}
const char * const epilogue =
" addl $3008, %esp\n"
" popl %ebp\n"
" ret\n"
"putchar:\n"
" mov $4, %eax\n"
" mov $1, %ebx\n"
" mov $1, %edx\n"
" int $0x80\n";
puts(epilogue);
}
int main(int argc, char *argv[])
{
if (argc != 2) err("Usage: compile-x86 inputfile");
char *text_body = read_file(argv[1]);
if (text_body == NULL) err("unable to read file");
compile(text_body);
free(text_body);
}