Newer
Older
} Registers;
typedef enum {
FLAG_ZERO = 1,
FLAG_NEGATIVE = 1 << 1,
} Flags;
typedef enum {
OP_ADD,
OP_ADD_VALUE,
OP_HALT,
OP_JMP_REL,
OP_JMP_REL_NEGATIVE,
OP_JMP_REL_NOT_EQUAL,
} OpCode;
static void
set_flags(int value, int *flags_register)
{
new_flags |= FLAG_NEGATIVE;
*flags_register = new_flags;
}
int main() {
int program[] = {
OP_LOAD, A, 3,
OP_LOAD, B, 5,
OP_ADD, B,
OP_PRINT, A,
OP_LOAD, B, 1,
OP_ADD, B,
OP_PRINT, A,
OP_LOAD, A, 0,
OP_LOAD, B, 0,
OP_PRINT, A,
OP_ADD_VALUE, 3,
OP_XCHG, A, B,
OP_ADD_VALUE, 1,
OP_TEST, 10,
OP_XCHG, A, B,
OP_JMP_REL_NOT_EQUAL, -16,
int flags_register = 0;
int *ip = program;
while (1) {
OpCode op = *ip++;
switch (op) {
case OP_LOAD: {
int idx = *ip++;
registers[idx] = *ip++;
set_flags(registers[idx], &flags_register);
break;
}
case OP_ADD: {
int val = registers[*ip++];
registers[A] += val;
set_flags(registers[A], &flags_register);
break;
}
case OP_ADD_VALUE: {
int val = *ip++;
registers[A] += val;
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
break;
}
case OP_TEST: {
int val = *ip++;
int new_val = val - registers[A];
set_flags(new_val, &flags_register);
break;
}
case OP_JMP_REL_NOT_EQUAL: {
int val = *ip++;
if (!(flags_register & FLAG_ZERO)) {
ip += val;
}
break;
}
case OP_JMP_REL_NEGATIVE: {
int val = *ip++;
if (!(flags_register & FLAG_NEGATIVE)) {
ip += val;
}
break;
}
case OP_MOV: {
int dst = *ip++;
int src = *ip++;
registers[dst] = registers[src];
break;
}
case OP_XCHG: {
int r1 = *ip++;
int r2 = *ip++;
int tmp = registers[r1];
registers[r1] = registers[r2];
registers[r2] = tmp;