SECD machine

The SECD machine is a highly influential ("see: ") virtual machine and abstract machine intended as a target for functional programming language compilers. The letters stand for Stack, Environment, Control, Dump—the internal registers of the machine. The registers Stack, Control, and Dump point to (some realisations of) stacks, and Environment points to (some realisation of) an associative array. 
The machine was the first to be specifically designed to evaluate lambda calculus expressions. It was originally described by Peter J. Landin in "The Mechanical Evaluation of Expressions" in 1964. The description published by Landin was fairly abstract, and left many implementation choices open (like an operational semantics). Hence the SECD machine is often presented in a more detailed form, such as Peter Henderson's Lispkit Lisp compiler, which has been distributed since 1980. Since then it has been used as the target for several other experimental compilers.
In 1989 researchers at the University of Calgary worked on a hardware implementation of the machine.
Landin's contribution.
D. A. Turner (2012) points out that "The Revised Report on Algol 60" (Naur 1963) specifies a procedure call by a copying rule that avoids variable capture with a systematic change of identifiers. This method works in the Algol 60 implementation, but in a functional programming language where functions are first-class citizens, a free variable on a call stack might be dereferenced in error.
Turner notes that Landin solved this with his SECD machine, in which a function is represented by a closure in the heap instead.
Informal description.
When evaluation of an expression begins, the expression is loaded as the only element of control codice_1. The environment codice_2, stack codice_3 and dump codice_4 begin empty.
During evaluation of codice_1 it is converted to reverse Polish notation (RPN) with codice_6 (for apply) being the only operator. For example, the expression codice_7 (a single list element) is changed to the list codice_8.
Evaluation of codice_1 proceeds similarly to other RPN expressions. If the first item in codice_1 is a value, it is pushed onto the stack codice_3. More exactly, if the item is an identifier, the value pushed onto the stack will be the binding for that identifier in the current environment codice_2. If the item is an abstraction, a closure is constructed to preserve the bindings of its free variables (which are in codice_2), and it is this closure which is pushed onto the stack.
If the item is codice_6, two values are popped off the stack and the application done (first applied to second). If the result of the application is a value, it is pushed onto the stack.
If the application is of an abstraction to a value, however, it will result in a lambda calculus expression that may itself be an application (rather than a value), and so cannot be pushed onto the stack. In this case, the current contents of codice_3, codice_2, and codice_1 are pushed onto the dump codice_4 (which is a stack of these triples), codice_3 is reinitialised to empty, and codice_1 is reinitialised to the application result with codice_2 containing the environment for the free variables of this expression, augmented with the binding that resulted from the application. Evaluation then proceeds as above.
Completed evaluation is indicated by codice_1 being empty, in which case the result will be on the stack codice_3. The last saved evaluation state on codice_4 is then popped, and the result of the completed evaluation is pushed onto the stack contents restored from codice_4. Evaluation of the restored state then continues as above.
If codice_1 and codice_4 are both empty, overall evaluation has completed with the result on the stack codice_3.
Registers and memory.
The SECD machine is stack-based. Functions take their arguments from the stack. The arguments to built-in instructions are encoded immediately after them in the instruction stream.
Like all internal data-structures, the stack is a list, with the codice_3 register pointing at the list's "head" or beginning. Due to the list structure, the stack need not be a continuous block of memory, so stack space is available as long as there is a single free memory cell. Even when all cells have been used, garbage collection may yield additional free memory. Obviously, specific implementations of the SECD structure can implement the stack as a canonical stack structure, so improving the overall efficiency of the virtual machine, provided that a strict bound be put on the dimension of the stack.
The codice_1 register points at the head of the code or instruction list that will be evaluated. Once the instruction there has been executed, the codice_1 is pointed at the next instruction in the list—it is similar to an "instruction pointer" (or program counter) in conventional machines, except that subsequent instructions are always specified during execution and are not by default contained in subsequent memory locations, as it is the case with the conventional machines.
The current variable environment is managed by the codice_2 register, which points at a list of lists. Each individual list represents one environment level: the parameters of the current function are in the head of the list, variables that are free in the current function, but bound by a surrounding function, are in other elements of codice_2.
The dump, at whose head the codice_4 register points, is used as temporary storage for values of the other registers, for example during function calls. It can be likened to the return stack of other machines.
The memory organization of the SECD machine is similar to the model used by most functional language interpreters: a number of memory cells, each of which can hold either an "atom" (a simple value, for example "13"), or represent an empty or non-empty list. In the latter case, the cell holds two pointers to other cells, one representing the first element, the other representing the list except for the first element. The two pointers are traditionally named "car" and "cdr" respectively—but the more modern terms "head" and "tail" are often used instead. The different types of values that a cell can hold are distinguished by a "tag". Often different types of atoms (integers, strings, etc.) are distinguished as well.
So, a list holding the numbers "1", "2", and "3", usually written as codice_35, might be represented as follows:
 Address Tag Content (value for integers, car & cdr for lists)
 9 [ integer | 2 ]
 8 [ integer | 3 ]
 7 [ list | 8 | 0 ]
 6 [ list | 9 | 7 ]
 2 [ list | 1 | 6 ]
 1 [ integer | 1 ]
 0 [ nil ]
The memory cells 3 to 5 do not belong to our list, the cells of which can be distributed randomly over the memory. Cell 2 is the head of the list, it points to cell 1, which holds the first element's value, and the list containing only "2" and "3" (beginning at cell 6). Cell 6 points at a cell holding 2 and at cell 7, which represents the list containing only "3". It does so by pointing at cell 8 containing the value "3", and pointing at an empty list ("nil") as cdr. In the SECD machine, cell 0 always implicitly represents the empty list, so no special tag value is needed to signal an empty list (everything needing that can simply point to cell 0).
The principle that the cdr in a list cell must point at another list is just a convention. If both car and cdr point at atoms, that will yield a pair, usually written like codice_36
Instructions.
A number of additional instructions for basic functions like car, cdr, list construction, integer addition, I/O, etc. exist. They all take any necessary parameters from the stack.