Implement the Universal Machine emulator The goal is to write a full program that emulates the Universal Machine from ICFP 2006 with the shortest code. The Universal Machine has a very simple instruction set explained here. The emulator has to read a filename from command-line argument, and run the file as the program, so your language has to support command-line arguments and stdin/out in some way. The emulator has to complete the sandmark within a reasonable time (not decades).
Here's a short explanation of the instruction set:


  The machine has eight registers each holding an 32-bit unsigned integer.
  The machine holds an indexed set of arrays of 32-bit unsigned integer cells.
  Shortly speaking, the allocation instruction returns an opaque 32-bit uint which is the handle to the created array, which has a static size, and holds 32-bit uint elements.
  The 0'th array denotes the program. It is loaded from a big-endian file on startup.
  There is also an Instruction Pointer which points to a cell in the 0 array.
  On each step, an instruction is read from the cell the Pointer points to, and the Pointer is inceremented before anything is done.
  The 4 most significant bits represent the opcode.
  If the opcode is 13, then the next 3 bits represent the register, and the other 25 represent the number that is written into the said register.
  Otherwise the 9 least significant bits represent three registers, say, A, B, and C, where C is represented by the 3 least significant bits.
  Then depending on the opcode, the following happens:
  0. A = B unless C == 0
  1. A = B[C]
  2. A[B] = C
  3. A = B + C
  4. A = B * C
  5. A = B / C
  6. A = ~(B &amp; C)
  7. The emulator exits
  8. B = allocate(C)
  9. deallocate(C)
  10. output a character from C to stdout
  11. input a character from stdin into C
  12. copy the array B into the 0 array and set the Pointer to C  


I have written a needlessly complex but totally fast implementation (ab)using x86_64 jitted assembly (the fun starts in emit()), which would for sure help you if you misunderstand some of the Machine's aspects.
PHP: 443 416 &nbsp;384 bytes

&lt;?php @eval(ereg_replace('[U-Z]','$\0',strtr('for(Y=[unpack("N*",join(file($argv[1])))];;A|=0){{W=Y[V=0][++U]
C&amp;&amp;A=B
A=Y[B][C+1]
Y[A][B+1]=C
A=B+C
A=B*C
A=bcdiv(PB),PC))*1
A=~B|~C
die
B=++Z
unset(Y[C])
echo chr(C)
C=fgetc(STDIN);C=ord(C)-(C=="")
Y[0]=Y[B|0];U=C
X[W&gt;&gt;25&amp;7]=W&amp;33554431;}}',['
'=&gt;';}if((W&gt;&gt;28&amp;15)==V++){',A=&gt;'X[W&gt;&gt;6&amp;7]',B=&gt;'X[W&gt;&gt;3&amp;7]',C=&gt;'X[W&amp;7]',P=&gt;'sprintf("%u",'])));


*Revamped again*. It's as small as I can possibly get it now. I kept some variables down the far end of the alphabet so that the regex that inserts the $ signs doesn't mangle the STDIN constant, so here's a little glossary:


U: instruction pointer
V: index of opcode that's currently being tested
W: current instruction word
X: the 8 general purpose registers
Y: main memory (each block is 1-based, since that's how unpack() returns arrays)
Z: id of next free memory block (will eventually overflow, but the sandmark only uses ~92 million)
A,B,C are the registers of the current instruction as in the spec


Unsigned division is a subtle nuisance (the *1 is needed to ensure that large numbers cast back to the correct int) but the rest of the arithmetic is easy to keep 32-bit by ORing the arithmetic register with 0 (A|=0) after each instruction.



I found this project really interesting but striving to minimize the character count made it slow and inelegant, so I also made a simple (not golfed) Java version, that can complete the sandmark in a few minutes instead of taking all day:

import java.io.*;
import java.util.HashMap;

public class UniversalMachine {
    public static void main(String[] args) throws IOException {
        if (args.length == 0) {
            System.err.println("Program not specified.");
            System.exit(1);
        }

        int[] program;
        try (RandomAccessFile raf = new RandomAccessFile(args[0], "r")) {
            program = new int[(int)(raf.length() / 4)];
            for (int i = 0; i &lt; program.length; i++) {
                program[i] = raf.readInt();
            }
        }

        HashMap&lt;Integer,int[]&gt; memory = new HashMap&lt;&gt;();
        memory.put(0, program);
        int nextMemKey = 1;

        int[] R = new int[8]; // Registers
        int IP = 0; // Execution Finger (Instruction Pointer)

        loop: for (;;) {
            int ins = program[IP++];
            int op = ins &gt;&gt;&gt; 28;
            if (op == 13) { // Orthography
                int A = (ins &gt;&gt; 25) &amp; 7;
                int num = ins &amp; 0x01FF_FFFF;
                R[A] = num;
            } else {
                final int A = (ins &gt;&gt; 6) &amp; 7;
                final int B = (ins &gt;&gt; 3) &amp; 7;
                final int C = (ins &gt;&gt; 0) &amp; 7;
                switch (op) {
                case 0: // Conditional Move
                    if (R[C] != 0) R[A] = R[B];
                    break;
                case 1: // Array Index
                    R[A] = memory.get(R[B])[R[C]];
                    break;
                case 2: // Array Amendment
                    memory.get(R[A])[R[B]] = R[C];
                    break;
                case 3: // Addition
                    R[A] = R[B] + R[C];
                    break;
                case 4: // Multiplication
                    R[A] = R[B] * R[C];
                    break;
                case 5: // Division
                    R[A] = (int)((R[B] &amp; 0xFFFF_FFFFL) / (R[C] &amp; 0xFFFF_FFFFL));
                    break;
                case 6: // Not-And
                    R[A] = ~(R[B] &amp; R[C]);
                    break;
                case 7: // Halt
                    break loop;
                case 8: // Allocation
                    // note: must use C before setting B, as they may be the same reg
                    memory.put(nextMemKey, new int[R[C]]);
                    R[B] = nextMemKey++;
                    break;
                case 9: // Abandonment
                    memory.remove(R[C]);
                    break;
                case 10: // Output
                    System.out.print((char)R[C]);
                    break;
                case 11: // Input
                    R[C] = System.in.read();
                    break;
                case 12: // Load Program
                    IP = R[C];
                    if (R[B] != 0) {
                        memory.put(0, program = memory.get(R[B]).clone());
                    }
                    break;
                }
            }
        }
    }
}