|
@@ -0,0 +1,145 @@
|
|
1
|
+#include <stdio.h>
|
|
2
|
+#include "instructions.h"
|
|
3
|
+
|
|
4
|
+struct instruction {
|
|
5
|
+ char ins;
|
|
6
|
+ int arg1;
|
|
7
|
+ int arg2;
|
|
8
|
+ int arg3;
|
|
9
|
+};
|
|
10
|
+
|
|
11
|
+struct instruction instructions[MAX_INSTRUCTIONS_SIZE];
|
|
12
|
+int current_line;
|
|
13
|
+int has_error;
|
|
14
|
+
|
|
15
|
+int memory[MAX_MEMORY_SIZE];
|
|
16
|
+
|
|
17
|
+int exec(int ip);
|
|
18
|
+int valid_memory_addr(int address);
|
|
19
|
+
|
|
20
|
+/***** Public funciton *****/
|
|
21
|
+
|
|
22
|
+void asm_init() {
|
|
23
|
+ current_line = 0;
|
|
24
|
+ has_error = 0;
|
|
25
|
+}
|
|
26
|
+
|
|
27
|
+void asm_add_3(char ins, int arg1, int arg2, int arg3) {
|
|
28
|
+ if (current_line >= MAX_INSTRUCTIONS_SIZE) {
|
|
29
|
+ fprintf(stderr, "ERROR readfile : Too much instructions, please modify value of MAX_INSTRUCTIONS_SIZE.\n");
|
|
30
|
+ has_error = 1;
|
|
31
|
+ return;
|
|
32
|
+ }
|
|
33
|
+
|
|
34
|
+ // ip are validated at runtime; memory addr are validated here
|
|
35
|
+ if (ins == AFC || ins == JMF) {
|
|
36
|
+ if (!valid_memory_addr(arg1)) {
|
|
37
|
+ fprintf(stderr, "ERROR readfile : INVALID addr at line %d, please verify that addr is in range 0 to MAX_MEMORY_SIZE\n", current_line);
|
|
38
|
+ has_error = 1;
|
|
39
|
+ return;
|
|
40
|
+ }
|
|
41
|
+ } else if (ins == JMP) {
|
|
42
|
+ // do nothing
|
|
43
|
+ } else {
|
|
44
|
+ if (!(valid_memory_addr(arg1) && valid_memory_addr(arg2)
|
|
45
|
+ && valid_memory_addr(arg3))) {
|
|
46
|
+ fprintf(stderr, "ERROR readfile : INVALID addr at line %d, please verify that addr is in range 0 to MAX_MEMORY_SIZE\n", current_line);
|
|
47
|
+ has_error = 1;
|
|
48
|
+ return;
|
|
49
|
+ }
|
|
50
|
+ }
|
|
51
|
+
|
|
52
|
+ // When OK
|
|
53
|
+ instructions[current_line].ins = ins;
|
|
54
|
+ instructions[current_line].arg1 = arg1;
|
|
55
|
+ instructions[current_line].arg2 = arg2;
|
|
56
|
+ instructions[current_line].arg3 = arg3;
|
|
57
|
+ current_line++;
|
|
58
|
+}
|
|
59
|
+
|
|
60
|
+void asm_add_2(char ins, int arg1, int arg2) {
|
|
61
|
+ asm_add_3(ins, arg1, arg2, 0);
|
|
62
|
+}
|
|
63
|
+
|
|
64
|
+void asm_add_1(char ins, int arg1) {
|
|
65
|
+ asm_add_3(ins, arg1, 0, 0);
|
|
66
|
+}
|
|
67
|
+
|
|
68
|
+void asm_run() {
|
|
69
|
+ int ip = 0;
|
|
70
|
+ if (has_error) {
|
|
71
|
+ fprintf(stderr, "ERROR run : abandoned due to previous error.\n");
|
|
72
|
+ return;
|
|
73
|
+ }
|
|
74
|
+ printf("INFO run : begin\n");
|
|
75
|
+ while (ip >= 0 && ip < current_line) {
|
|
76
|
+ // wait for user input
|
|
77
|
+ //getchar();
|
|
78
|
+ // execution
|
|
79
|
+ ip = exec(ip);
|
|
80
|
+ }
|
|
81
|
+ printf("INFO run : end\n");
|
|
82
|
+}
|
|
83
|
+
|
|
84
|
+/***** Private funciton *****/
|
|
85
|
+
|
|
86
|
+int valid_memory_addr(int addr) {
|
|
87
|
+ return addr >= 0 && addr < MAX_MEMORY_SIZE;
|
|
88
|
+}
|
|
89
|
+
|
|
90
|
+int exec(int ip) {
|
|
91
|
+ int next_ip = ip + 1;
|
|
92
|
+ char ins = instructions[ip].ins;
|
|
93
|
+ int arg1 = instructions[ip].arg1;
|
|
94
|
+ int arg2 = instructions[ip].arg2;
|
|
95
|
+ int arg3 = instructions[ip].arg3;
|
|
96
|
+ printf("%d : ", ip);
|
|
97
|
+
|
|
98
|
+ // execute inst
|
|
99
|
+ switch (ins) {
|
|
100
|
+ case ADD:
|
|
101
|
+ printf("ADD @%d = @%d[%d] + @%d[%d]\n", arg1, arg2, memory[arg2], arg3, memory[arg3]);
|
|
102
|
+ memory[arg1] = memory[arg2] + memory[arg3]; break;
|
|
103
|
+ case MUL:
|
|
104
|
+ printf("MUL @%d = @%d[%d] * @%d[%d]\n", arg1, arg2, memory[arg2], arg3, memory[arg3]);
|
|
105
|
+ memory[arg1] = memory[arg2] * memory[arg3]; break;
|
|
106
|
+ case SOU:
|
|
107
|
+ printf("SOU @%d = @%d[%d] - @%d[%d]\n", arg1, arg2, memory[arg2], arg3, memory[arg3]);
|
|
108
|
+ memory[arg1] = memory[arg2] - memory[arg3]; break;
|
|
109
|
+ case DIV:
|
|
110
|
+ printf("DIV @%d = @%d[%d] / @%d[%d]\n", arg1, arg2, memory[arg2], arg3, memory[arg3]);
|
|
111
|
+ memory[arg1] = memory[arg2] / memory[arg3]; break;
|
|
112
|
+ case COP:
|
|
113
|
+ printf("COP @%d = @%d[%d]\n", arg1, arg2, memory[arg2]);
|
|
114
|
+ memory[arg1] = memory[arg2]; break;
|
|
115
|
+ case AFC:
|
|
116
|
+ printf("AFC @%d = %d\n", arg1, arg2);
|
|
117
|
+ memory[arg1] = arg2; break;
|
|
118
|
+ case JMP:
|
|
119
|
+ printf("JMP to %d\n", arg1);
|
|
120
|
+ next_ip = arg1; break;
|
|
121
|
+ case JMF:
|
|
122
|
+ printf("JMF cond@%d[%d] to %d\n", arg1, memory[arg1], arg2);
|
|
123
|
+ if (memory[arg1] == 0) next_ip = arg2;
|
|
124
|
+ break;
|
|
125
|
+ case INF:
|
|
126
|
+ printf("INF @%d = @%d[%d] < @%d[%d] ? 1 : 0\n", arg1, arg2, memory[arg2], arg3, memory[arg3]);
|
|
127
|
+ memory[arg1] = memory[arg2] < memory[arg3] ? 1 : 0;
|
|
128
|
+ break;
|
|
129
|
+ case SUP:
|
|
130
|
+ printf("SUP @%d = @%d[%d] > @%d[%d] ? 1 : 0\n", arg1, arg2, memory[arg2], arg3, memory[arg3]);
|
|
131
|
+ memory[arg1] = memory[arg2] > memory[arg3] ? 1 : 0;
|
|
132
|
+ break;
|
|
133
|
+ case EQU:
|
|
134
|
+ printf("EQU @%d = @%d[%d] == @%d[%d] ? 1 : 0\n", arg1, arg2, memory[arg2], arg3, memory[arg3]);
|
|
135
|
+ memory[arg1] = memory[arg2] == memory[arg3] ? 1 : 0;
|
|
136
|
+ break;
|
|
137
|
+ case PRI:
|
|
138
|
+ printf("PRI @%d[%d]\n", arg1, memory[arg1]);
|
|
139
|
+ break;
|
|
140
|
+ default:
|
|
141
|
+ fprintf(stderr, "ERROR run : unknown inst.\n");
|
|
142
|
+ }
|
|
143
|
+
|
|
144
|
+ return next_ip;
|
|
145
|
+}
|