-
Notifications
You must be signed in to change notification settings - Fork 5
/
executor.c
157 lines (119 loc) · 5.63 KB
/
executor.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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#include "executor.h"
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <string.h>
// 虚拟机寄存器
static int *bp, ax, cycle;
static int* stack;
static double* fstack;
int executor_init()
{
// 运行是会需要,该部分只要虚拟机运行就行了
if (!(stack = malloc(STACK_SIZE * sizeof(int)))) {
printf("could not malloc(%d) for stack area\n", STACK_SIZE);
return -1;
}
// 运行是会需要,该部分只要虚拟机运行就行了
if (!(fstack = malloc(STACK_SIZE * sizeof(double)))) {
printf("could not malloc(%d) for stack area\n", STACK_SIZE);
return -1;
}
}
void run_code(int* code_start)
{
// 初始化堆栈
int* sp = (int *)(stack + STACK_SIZE);
double* fsp = (double *)(fstack + STACK_SIZE);
eval(code_start, sp, fsp);
}
static int eval(int* pc, int* sp, double *fsp) {
int op, *args;
cycle = 0;
// 临时增加用来保存浮点数的
double bx;
while (true) {
cycle ++;
// 在有main函数的时候是从main函数开始执行的,如果要去掉main函数的化
// 就要正确设置pc否则就会内存错误
op = *pc++;
// TODO 使用switch 减少无效的if/else判断,因为在调试的时候发现要查找某个
// op的时候 如果op很后面那么前面就需要进行很多的if/else的条件判断
if (true) {
printf("%d> %.4s", cycle,
& "LEA ,IMM ,FIMM,JMP ,CALL,JZ ,JNZ ,ENT ,ADJ ,LEV ,LD ,"
"LF ,LI ,LC ,SD ,SF ,SI ,SC ,ATOB,BTOA,PUSF,PUSH,OR ,XOR ,AND ,"
"EQF ,EQ ,NEF ,NE ,LTF ,LT ,GTF ,GT ,LEF ,LE ,GEF ,GE ,SHL ,SHR ,ADDF,ADD ,SUB ,MULF,MUL ,DIVF,DIV ,MOD ,"
"NOP ,OPEN,READ,CLOS,PRTF,MALC,MSET,MCMP,EXIT"[op * 5]);
if (op <= ADJ)
printf(" %0x\n", *pc);
else
printf("\n");
}
// 加载立即数到寄存器ax中,加载整数以及地址
if (op == IMM) {ax = *pc++;}
// TODO 加载float类型的常量,这里的常量是内部的而不是外部导入的
// 外部导入的都是通过地址去加载的
else if (op == FIMM) {double* addr = (double*)pc; bx = *addr; pc += 2;}
// 加载字符类型数据到ax中,原来ax中保存的是地址
else if (op == LC) {ax = *(char *)ax;}
// 加载整型数据到ax中,原来ax中保存的是地址
else if (op == LI) {ax = *(int *)ax;}
else if (op == LF) {bx = *(float *)ax; printf("bx is %lf\n", bx);}
else if (op == LD) {bx = *(double *)ax;}
else if (op == SC) {ax = *(char *)*sp++ = ax;}
else if (op == SI) {*(int *)*sp++ = ax; printf("ax %d\n", ax);}
// 因为外部注入的变量类型可能是float类型的也可能是double类型的
// 所以存储的时候需要区分开来因此设计了两条指令存储float类型的
else if (op == SF) {*(float*)*sp++ = bx; printf("bx is %lf\n", bx);}
else if (op == SD) {*(double*)*sp++ = bx;}
else if (op == ATOB) { bx = (double)ax;}
else if (op == BTOA) { ax = (int)bx;}
else if (op == NOP) { ;}
else if (op == PUSH) {*--sp = ax;}
else if (op == PUSF) {*--fsp = bx;}
else if (op == JMP) {pc = (int *)*pc;}
else if (op == JZ) {pc = ax ? pc + 1 : (int *)*pc;}
else if (op == JNZ) {pc = ax ? (int *)*pc : pc + 1;}
else if (op == CALL) {*--sp = (int)(pc+1); pc = (int *)*pc;}
else if (op == ENT) {*--sp = (int)bp; bp = sp; sp = sp - *pc++;}
// 清理函数调用传递进来的参数
else if (op == ADJ) {sp = sp + *pc++;}
else if (op == LEV) {sp = bp; bp = (int *)*sp++; pc = (int *)*sp++;}
else if (op == LEA) {ax = (int)(bp + *pc++);}
// 逻辑运算符
else if (op == OR) ax = *sp++ | ax;
else if (op == XOR) ax = *sp++ ^ ax;
else if (op == AND) ax = *sp++ & ax;
// 比较运算符
else if (op == EQ) ax = *sp++ == ax;
else if (op == EQF) {ax = (*fsp++ == bx);}
else if (op == NE) ax = *sp++ != ax;
else if (op == NEF) {ax = (*fsp++ != bx);}
else if (op == LT) ax = *sp++ < ax;
else if (op == LTF) {ax = (*fsp++ < bx);}
else if (op == LE) ax = *sp++ <= ax;
else if (op == LEF) {ax = (*fsp++ <= bx);}
else if (op == GT) ax = *sp++ > ax;
else if (op == GTF) {ax = (*fsp++ > bx);}
else if (op == GE) ax = *sp++ >= ax;
else if (op == GEF) {ax = (*fsp++ >= bx);}
else if (op == SHL) ax = *sp++ << ax;
else if (op == SHR) ax = *sp++ >> ax;
else if (op == ADD) ax = *sp++ + ax;
else if (op == ADDF) { bx = *fsp++ + bx; }
else if (op == SUB) ax = *sp++ - ax;
// else if (op == SUBF) bx = *fsp++ - bx;
else if (op == MUL) ax = *sp++ * ax;
else if (op == MULF) bx = *fsp++ * bx;
else if (op == DIV) {if (ax == 0) exit(-1); ax = *sp++ / ax;}
else if (op == DIVF){if (bx == 0.0)exit(-1); bx = *fsp++ / bx;}
else if (op == MOD) ax = *sp++ % ax;
// 唯一退出的代码
else if (op == EXIT) { printf("exit(%d)\n", *sp); return *sp;}
else {
printf("unknown instruction:%d\n", op);
return -1;
}
}
}