| 命令番号 | p0 | p1 | p2 | 機能 |
| 00 | プログラムの終端・終了 | |||
| 01 | ジャンプ先ラベル定義 | |||
| 02 | lb | 無条件ジャンプ(lbはラベル番号) | ||
| 05 | r1 | 値を出力(r1) | ||
| 10 | r0 | r1/imm | OR_ r0,r1/imm | |
| 11 | r0 | r1/imm | XOR r0,r1/imm | |
| 12 | r0 | r1/imm | AND r0,r1/imm | |
| 14 | r0 | r1/imm | ADD r0,r1/imm | |
| 15 | r0 | r1/imm | SUB r0.r1/imm | |
| 16 | r0 | r1/imm | MUL r0,r1/imm | |
| 17 | r0 | r1/imm | LET r0,r1/imm | |
| 18 | r0 | r1/imm | SHL r0,r1/imm | |
| 19 | r0 | r1/imm | SAR r0,r1/imm | |
| 1a | r0 | r1/imm | DIV r0,r1/imm | |
| 1b | r0 | r1/imm | MOD r0,r1/imm | |
| 20 | r0 | r1/imm | lb | CMPJE_ r0,r1/imm,lb |
| 21 | r0 | r1/imm | lb | CMPJNE r0,r1/imm,lb |
| 22 | r0 | r1/imm | lb | CMPJL_ r0,r1/imm,lb |
| 23 | r0 | r1/imm | lb | CMPJGE r0,r1/imm,lb |
| 24 | r0 | r1/imm | lb | CMPJLE r0,r1/imm,lb |
| 25 | r0 | r1/imm | lb | CMPJG_ r0,r1/imm,lb |
#define INVALID ((int) 0x800055aa)
#define REG 0x80005a00
int dst[] = { 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, INVALID }; // 要求している出力: フィボナッチ数列(例).
long long tc = 0LL;
int test(int *p, int t1)
{
int v[64], i, c, sr;
if ((tc & 0xffffff) == 0) // 中間報告用の簡易表示.
printf(" %d (%02x %02x %02x %02x) \r", (int) tc, p[0], p[4], p[12], p[16]);
tc++; // テストした回数.
for (i = 0; i < 64; i++)
v[i] = INVALID;
int lb[100], lbn = 0, l, dp = 0;
for (i = 0; p[i] != 0; ) {
if (p[i] == 0x01) { lb[lbn++] = i; } // LB
i += 4;
}
for (i = 0; p[i] != 0; ) {
t1--; if (t1 <= 0) return -3; // (timeout)
c = p[i];
sr = p[i + 2];
i += 4;
if ((sr & ~0x3f) == REG)
sr = v[sr & 0x3f];
if (sr == INVALID) return -2; // (未定義参照).
if (c == 0x01) { continue; } // LB
if (c == 0x02) { // JMP
jmp: l = p[i + (-4 + 3)];
if (l >= lbn) return -1; // (未完成プログラム).
i = lb[l];
continue;
}
if (c == 0x05) { // OUT
if (dst[dp] != sr) return -4; // (正しくない結果の出力).
if (dst[++dp] == INVALID) return t1; // 残り時間をスコアとして返す.
continue;
}
int j = p[i + (-4 + 1)];
if (0x10 <= c && c <= 0x1b && v[j] == INVALID && c != 0x17) return -2; // (未定義参照).
if (0x20 <= c && c <= 0x25 && v[j] == INVALID) return -2; // (未定義参照).
if (0x1a <= c && c <= 0x1b && sr <= 0) return -5; // (div0). 本来のdiv0対策なら負の場合を除外する必要はないが、gccでは除外しておかないとたまにハングアップになる.
if (c == 0x10) { v[j] |= sr; continue; } // OR
if (c == 0x11) { v[j] ^= sr; continue; } // XOR
if (c == 0x12) { v[j] &= sr; continue; } // AND
if (c == 0x14) { v[j] += sr; continue; } // ADD
if (c == 0x15) { v[j] -= sr; continue; } // SUB
if (c == 0x16) { v[j] *= sr; continue; } // MUL
if (c == 0x17) { v[j] = sr; continue; } // LET
if (c == 0x18) { v[j] <<= sr; continue; } // SHL
if (c == 0x19) { v[j] >>= sr; continue; } // SAR
if (c == 0x1a) { v[j] /= sr; continue; } // DIV
if (c == 0x1b) { v[j] %= sr; continue; } // MOD
if (c == 0x20) { if (v[j] == sr) goto jmp; continue; }
if (c == 0x21) { if (v[j] != sr) goto jmp; continue; }
if (c == 0x22) { if (v[j] < sr) goto jmp; continue; }
if (c == 0x23) { if (v[j] >= sr) goto jmp; continue; }
if (c == 0x24) { if (v[j] <= sr) goto jmp; continue; }
if (c == 0x25) { if (v[j] > sr) goto jmp; continue; }
kerrorExit("test: internal error : c=0x%02x", c); // これはエラー終了させる自作ライブラリ関数.
}
return 0; // (十分な出力をする前に終わってしまった).
}1 1 2 3 5 8 13 21 34 55 89 144 ...
#0: [LET v0, 0] [LET v1, 1] [LB 0] [OUT v1] [LET v2, v1] [ADD v1, v0] [LET v0, v2] [JMP 0]
// C言語で書くと・・・
int i = 0, j = 1, k;
for (;;) {
printf("%d ", j);
k = j;
j += i;
i = k;
}#1: [LET v0, 0] [LET v1, 1] [LB 0] [OUT v1] [ADD v0, v1] [OUT v0] [ADD v1, v0] [JMP 0]
// C言語で書くと・・・
int i = 0, j = 1;
for (;;) {
printf("%d ", j);
i += j;
printf("%d ", i);
j += i;
}1 2 2 3 3 3 4 4 4 4 5 5 5 5 5 ...
#2: [LET v0, 1] [LB 0] [LET v1, 0] [LB 1] [OUT v0] [ADD v1, 1] [CMPJNE v0, v1, 1] [ADD v0, 1] [JMP 0]
// C言語で書くと・・・
int i = 1, j;
for (;;) {
j = 0;
do {
printf("%d ", i);
j++;
} while (i != j);
i++;
}#3: [LET v0, 1] [LET v1, 0] [LB 0] [OUT v0] [ADD v1, 1] [CMPJNE v0, v1, 0] [ADD v0, 1] [LET v1, 0] [JMP 0]
// C言語で書くと・・・
int i = 1, j = 0;
for (;;) {
do {
printf("%d ", i);
j++;
} while (i != j);
i++;
j = 0;
}2 3 5 7 11 13 19 21 23 29 31 37 ...
1 4 9 16 25 36 49 64 81 ...
#4: [LET v0, 1] [LB 0] [LET v1, v0] [MUL v1, v0] [OUT v1] [ADD v0, 1] [JMP 0]
// C言語で書くと・・・
int i = 1, j;
for (;;) {
j = i;
j *= i;
printf("%d ", j);
i++;
}#5: [LET v0, -1] [LET v1, 0] [LB 0] [ADD v0, 2] [ADD v1, v0] [OUT v1] [JMP 0]
// C言語で書くと・・・
int i = -1, j = 0;
for (;;) {
i += 2;
j += i;
printf("%d ", j);
}| コメント | お名前 | NameLink | |