A direct-threaded representation of program code is simply a vector of procedure pointers to call, in the order they appear.  In x86 assembly language, the "inner interpreter" of such a representation is drop-dead trivially simple:

  LODSD
  JMP    EAX

This assumes that ESI contains the program's next-PC value.

Direct ''call'' threading (usually referred to as just "call threading") is also possible:

  ; in x86 assembly

  runVM:
    MOV    EAX,[ESI]
    ADD    ESI,4
    CALL   EAX
    JMP    runVM

  /* In C; if global state is kept in global variables, then there is no need for a specific environment. */

  void runVM(Instruction *virtualIP, Environment *env) {
    while(ShouldNotQuit(env)) {
      (*virtualIP++)(env);
    }
  }

Note that some C compilers permit computed goto expressions, such as GCC.  If these are available, then C can also be used to implement a true direct threaded interpreter as well, thus avoiding the overheads of subroutine threading.

----

Contrast with IndirectThreadedCode, SubroutineThreadedCode, TokenThreadedCode