#include #include #include #include #include typedef unsigned int u32; u32 *codex = 0; u32 pc = 0; u32 *seg = NULL; u32 regs[8] = {0,0,0,0,0,0,0,0}; u32 my_alloc(u32 size){ u32* p = (u32*) calloc(size+1, 4); *p = size; return ((u32) (p+1)); } void my_free(u32 u) { u32* p = (u32*) (u-4); free(p); } u32 my_getsize(u32 u) { u32* p = (u32*) (u-4); return p[0]; } void run() { seg = codex; pc = 0; while(1) { u32 w = seg[pc++]; u32 opcode = w >> 28; u32 a = (w >> 6) & 7; u32 b = (w >> 3) & 7; u32 c = w & 7; u32 sa = (w >> 25) & 7; u32 dat = (w << 7) >> 7; //printf("pc=%d opcode=%d a=%d b=%d c=%d sa=%d dat=%d\n", pc,opcode, a,b,c,sa,dat); switch (opcode) { case 0: if (regs[c]) regs[a] = regs[b]; break; case 1: if (regs[b]==0) regs[a] = seg[regs[c]]; else regs[a] = ((u32 *)(regs[b]))[regs[c]]; break; case 2: if (regs[a]==0) seg[regs[b]] = regs[c]; else ((u32 *)(regs[a]))[regs[b]] = regs[c]; break; case 3: regs[a] = regs[b] + regs[c]; break; case 4: regs[a] = regs[b] * regs[c]; break; case 5: regs[a] = regs[b] / regs[c]; break; case 6: regs[a] = (~(regs[b] & regs[c])); break; case 7: exit(0); return; case 8: regs[b] = my_alloc(regs[c]); break; case 9: assert(regs[c]>0); my_free(regs[c]); break; case 10: printf("%c", regs[c]); break; case 11: regs[c] = getchar(); if (regs[c] == EOF) regs[c] = 0xffffffff; break; case 12: if (regs[b]!=0) { if (seg != codex) my_free((u32) seg); int size = my_getsize(regs[b]); seg = (u32*) my_alloc(size); memcpy(seg, (void*) regs[b], size*4); } pc = regs[c]; break; case 13: regs[sa] = dat; break; } } } int main(int argc, char**argv) { FILE* f = fopen( argv[1], "rb");; assert(f); fseek(f,0,SEEK_END); int cdxlen = ftell(f); rewind(f); codex = (u32 *) malloc(cdxlen+4); fread(codex,1,cdxlen,f); fclose(f); for (int i=0; i< cdxlen/4; i++) codex[i] = ntohl(codex[i]); run(); return 0; }