-
Notifications
You must be signed in to change notification settings - Fork 1
/
assembler.c
executable file
·121 lines (112 loc) · 2.63 KB
/
assembler.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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#include "assembler.h"
#include "args.h"
#include "compiler.h"
#include "var.h"
void token_head(FILE *file)
{
if (get_output() == OUTPUT_INTEL_X64_ASM)
{
if (get_target_platform() == TARGET_PLATFORM_LINUX)
{
fputs(".globl main\nmain:\n", file);
}
else if (get_target_platform() == TARGET_PLATFORM_WIN)
{
fputs(".code\nmain proc\n", file);
}
}
}
void token_tail(FILE *file)
{
if (get_output() == OUTPUT_INTEL_X64_ASM)
{
if (get_target_platform() == TARGET_PLATFORM_WIN)
{
fputs("main endp\nend", file);
}
}
}
void token_return(struct token *t, FILE *file)
{
if (get_output() == OUTPUT_INTEL_X64_ASM)
{
if (get_target_platform() == TARGET_PLATFORM_LINUX)
{
fprintf(file, " movq %%r%d, %%rax\n ret\n", read_var((char)t->value));
}
else if (get_target_platform() == TARGET_PLATFORM_WIN)
{
fprintf(file, " mov rax, r%d\n ret\n", read_var((char)t->value));
}
}
else if (get_output() == OUTPUT_EXECUTABLE)
{
if (get_target_platform() == TARGET_PLATFORM_LINUX)
{
// mov eax, 1 (sys_exit)
fputc(0xB8, file);
fputc(0x01, file);
fputc(0x00, file);
fputc(0x00, file);
fputc(0x00, file);
// mov ebx, value (return code)
fputc(0xBB, file);
fputc(/*read_var((char)t->value)*/0x05, file);
fputc(0x00, file);
fputc(0x00, file);
fputc(0x00, file);
// Interrupt 0x80
fputc(0xCD, file);
fputc(0x80, file);
}
// TODO: Implement for Windows
}
}
void token_var(/*struct token *t*/)
{
//write_var((char)t->value, 11);
}
void token_call(struct token *t, FILE *file)
{
if (get_output() == OUTPUT_INTEL_X64_ASM)
{
if (get_target_platform() == TARGET_PLATFORM_LINUX)
{
fprintf(file, " movq $%d, %%r%d\n", t->value2, read_var((char)t->value));
}
else if (get_target_platform() == TARGET_PLATFORM_WIN)
{
fprintf(file, " mov r%d, %d\n", read_var((char)t->value), t->value2);
}
}
else if (get_output() == OUTPUT_EXECUTABLE)
{
write_var((char)t->value, t->value2);
}
}
void assemble(struct token *t, FILE *file)
{
while (t)
{
switch (t->type)
{
case TOKEN_TYPE_HEAD:
token_head(file);
break;
case TOKEN_TYPE_TAIL:
token_tail(file);
break;
case TOKEN_TYPE_RETURN:
token_return(t, file);
break;
case TOKEN_TYPE_VAR:
token_var(/*t*/);
break;
case TOKEN_TYPE_CALL:
token_call(t, file);
default:
break;
}
t = t->next;
}
}