#include <stdio.h>
int R[8], mem[256]; int pc = 16;

void dump()
  {
    int i, j;
    printf("pc: %04X\n", pc);
    printf("regs: ");
    for (i = 0; i < 8; i++) 
      printf("%04X ", R[i]);
    printf("\n");
    for (i = 0; i < 32; i++)
      {
        printf("\n%04X: ", 8*i);
        for (j = 0; j < 8; j++) 
          printf("%04X ", mem[8*i+j]);
      }
    printf("\n");
  }

int main()
{
  int i, inst, op, addr, r0, r1, r2;
  for (i = 0; i < 256; i++) mem[i] = 0;
  for (i = 16; i < 256; i++)
    if (scanf("%X", &mem[i]) == EOF) break;
  do
    {
      inst = mem[pc++];
      op = (inst >> 12) & 0XF; 
      addr = inst & 0XFF;
      r0 = (inst >> 8) & 0X7; 
      r1 = (inst >> 4) & 0X7; r2 = inst & 0X7; 
      if (inst & 0X0800) addr = R[r1]+R[r2];
      switch (op)
      {
        case  0: break;
        case  1: R[r0] = R[r1] + R[r2];  break;
        case  2: R[r0] = R[r1] - R[r2];  break;
        case  3: R[r0] = R[r1] * R[r2];  break;
/*          case  4: printf("%X\n", addr);   break; */
        case  4: printf("%X\n", R[r0]);  break; 
        case  5: pc = addr;              break;
        case  6: if (R[r0]>0) pc = addr; break;
        case  7: if (--R[r0]) pc = addr; break;
        case  8: R[r0] = pc; pc = addr;  break;
        case  9: R[r0] = mem[addr];      break;
        case 10: mem[addr] = R[r0];      break;
        case 11: R[r0] = addr;           break;
        case 12: R[r0] = R[r1] ^ R[r2];  break;
        case 13: R[r0] = R[r1] & R[r2];  break;
        case 14: R[r0] = R[r0] >> addr;  break;
        case 15: R[r0] = R[r0] << addr;  break;
      }
    }
  while (op != 0);

  dump();
  
  return 0;
}      
