-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathvm_run_sample.c
More file actions
132 lines (117 loc) · 3.04 KB
/
Copy pathvm_run_sample.c
File metadata and controls
132 lines (117 loc) · 3.04 KB
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
#include <stdio.h>
#include <stdint.h>
__declspec(dllexport) const uint8_t* vpc = NULL;
typedef enum {
VM_HALT = 0,
VM_MOV_IMM,
VM_MOV,
VM_ADD,
VM_SUB,
VM_MUL,
VM_DIV,
VM_TEST,
VM_JG,
VM_JL,
VM_JGE,
VM_JLE,
VM_EQ
} VmOpcode;
int32_t R[4] = {0};
int32_t cmp_flag = 0;
void vm_run(const uint8_t* code) {
vpc = code;
while (1) {
uint8_t opcode = *vpc++;
switch (opcode) {
case VM_HALT:
return;
case VM_MOV_IMM:
R[*vpc] = *(const int32_t*)(vpc + 1);
vpc += 5;
break;
case VM_MOV:
R[*vpc] = R[*(vpc + 1)];
vpc += 2;
break;
case VM_ADD:
R[*vpc] += R[*(vpc + 1)];
vpc += 2;
break;
case VM_SUB:
R[*vpc] -= R[*(vpc + 1)];
vpc += 2;
break;
case VM_MUL:
R[*vpc] *= R[*(vpc + 1)];
vpc += 2;
break;
case VM_DIV:
R[*vpc] /= R[*(vpc + 1)];
vpc += 2;
break;
case VM_TEST:
cmp_flag = R[*vpc] - R[*(vpc + 1)];
vpc += 2;
break;
case VM_JG:
if (cmp_flag > 0) {
vpc += *(const int32_t*)vpc;
} else {
vpc += 4;
}
break;
case VM_JL:
if (cmp_flag < 0) {
vpc += *(const int32_t*)vpc;
} else {
vpc += 4;
}
break;
case VM_JGE:
if (cmp_flag >= 0) {
vpc += *(const int32_t*)vpc;
} else {
vpc += 4;
}
break;
case VM_JLE:
if (cmp_flag <= 0) {
vpc += *(const int32_t*)vpc;
} else {
vpc += 4;
}
break;
case VM_EQ:
if (cmp_flag == 0) {
vpc += *(const int32_t*)vpc;
} else {
vpc += 4;
}
break;
default:
printf("Error: Unknown Opcode 0x%02X\n", opcode);
return;
}
}
}
uint8_t program[] = {
VM_MOV_IMM, 0, 0x00, 0x00, 0x00, 0x00,
VM_MOV_IMM, 1, 0x01, 0x00, 0x00, 0x00,
VM_MOV_IMM, 2, 0x0A, 0x00, 0x00, 0x00,
VM_MOV_IMM, 3, 0x01, 0x00, 0x00, 0x00,
VM_TEST, 1, 2,
VM_JG, 0x12, 0x00, 0x00, 0x00,
VM_ADD, 0, 1,
VM_ADD, 1, 3,
VM_TEST, 3, 3,
VM_EQ, 0xEE, 0xFF, 0xFF, 0xFF,
VM_HALT
};
int main(void) {
printf("Starting VM Execution...\n");
vm_run(program);
printf("VM execution finished.\n");
printf("Result in R0 (Sum 1 to 10): %d\n", R[0]);
printf("Final vpc pointer address: %p\n", (void*)vpc);
return 0;
}