You are on page 1of 4

Stack machine

What is a stack machine?

Contrast to an ordinary processor of contemporary design which use registers a stack machine
uses stack. Stack is a LIFO (last in first out) storage with two abstract operations : push, pop.
Push will put an item into stack at the top. Pop retrieve an item at the top of stack.

Calculations using stack.

Because a stack is LIFO, any operation must access data item from the top. Stack doesn't need
'addressing' as it is implicit in the operators which use stack. Any expression can be transforms
into a postfix order and stack can be use to evaluate that expression without the need for explicitly
locate any variable. For example,
B + C - D ==>
B C + D - (post fix)
push val B, push val C, add, push val D, sub.
A = B ==>
push ads A, push val B, store.
Where add, takes top two items from stack add them and push the result back to stack, similarly
sub operators. Store takes one value and one address from stack and store value to address.

Let's compare the above expression to the calculation using registers.

load r0, B
load r1, C
add r0, r1 ;; r0+r1 -> r0
load r2, D
sub r0, r2

load r0, ads A
load r1, val B
store r1, (r0) ;; r1 --> (r0)

One can see that the main difference is that registers must be allocated, for example, r0 is used
to store temporary result while in stack machine the temporary storage is implicit.

Calling subroutines
The stack structure also plays an important role in the calling of subroutines (or function calls).
When a program transfers the control to another section of program, the current state of
computation is saved (composed of Program Counter, local variables, and other values). The
place where the state of computation is saved is called 'activation record'. When an execution of a
subroutine is completed the previous state of computation is restored (this action is called 'return
from subroutines'). Because many of today programming languages are 'structured' or 'block
oriented' the creation and deletion of activation records behave like LIFO. Stack is used to store
activation records.

f(A) call g(B,C)

Act Rec: fp',sp',pc', A, ...
fp, sp, pc , B, C,... <-- TOP
where fp is frame pointer, sp is stack pointer, pc is current program pointer, pc' is previous pc
A is local variable of f. B,C are local variables of g. frame pointer link activation records
together. Stack pointer points to current stack, use for storing temporary value of current

Current languages that use stack

There are a number of contemporary programming languages that use stack abstraction, for
example, Forth, Postscript. Also many languages use 'virtual machine' model to implement their
executable representations.

Pure stack machine

If we don't have local variables how can operands in the computation stack are accessed? With
exception for the top two items all other items are difficult to get to. We need to be able to reorder
and copy a number of items in the stack in order to use them. The following instructions did that :
dup ;; duplicate TOP
swap ;; swap TOP and NEXT
rot ;; 1,2,3 -> 3,1,2 get the third item to the top
over ;; copy NEXT to TOP , 1,2 -> 2,1,2

These are just some of the possible instructions. An example of their use:
f(X,Y) = X*X + Y*Y
X and Y are the top two items on computation stack when call f().
dup mul ;; X*X
swap ;; Y, X*X
dup mul add ;; Y*Y + X*X

Thinking about rearranging items on stack make it difficult to use pure stack instructions. Having
variables avoids the reordering of items on stack because a variable can be accessed by using
its name. However, current compilation techniques can handle the ordering of stack items
therefore it frees a programmer from this low level detail.

Advantages of stack machine instruction sets

Very compact object code

Stack machines have much smaller instructions than the other styles of machines. Loads and stores
to memory are separate and so stack code requires roughly twice as many instructions as the
equivalent code for register machines. The total code size (in bytes) is still less for stack machines.

Simple compilers

Compilers for stack machines are simpler and quicker to build than compilers for other machines.
Code generation is trivial and independent of prior or subsequent code.

Simple interpreters
Some stack machine instruction sets are intended for interpretive execution of a virtual machine,
rather than driving hardware directly. Interpreters for virtual stack machines are easier to build than
interpreters for register or memory-to-memory machines; the logic for handling memory address
modes is in just one place rather than repeated in many instructions.

A virtual machine (VM) is a high level abstraction on top of the native operating system, that
emulates a physical machine. Here, we are talking about process virtual machines and not system
virtual machines. A virtual machine enables the same platform to run on multiple operating systems
and hardware architectures. The Interpreters for Java and Python can be taken as examples, where
the code is compiled into their VM specific bytecode.

Stack Based Virtual Machines

A stack based virtual machine implements the general features described as needed by a virtual
machine in the points above, but the memory structure where the operands are stored is a stack
data structure. Operations are carried out by popping data from the stack, processing them and
pushing in back the results in LIFO (Last in First Out) fashion.

Register Based Virtual Machines

In the register based implementation of a virtual machine, the data structure where the operands
are stored is based on the registers of the CPU. There is no PUSH or POP operations here, but the
instructions need to contain the addresses (the registers) of the operands. That is, the operands for
the instructions are explicitly addressed in the instruction, unlike the stack based model where we
had a stack pointer to point to the operand.

The problem with a register based model is that the average register instruction is larger than an
average stack instruction, as we need to specify the operand addresses explicitly. Whereas the
instructions for a stack machine is short due to the stack pointer, the respective register machine
instructions need to contain operand locations, and results in larger register code compared to stack

Fast operand access

Since there are no operand fields to decode, stack machines fetch each instruction and its operands
at same time. Stack machines can omit the operand fetching stage of a register machine.

Performance disadvantages of stack machines

More memory references

Some in the industry believe that stack machines execute more data cache cycles for temporary
values and local variables than do register machines.

On stack machines, temporary values often get spilled into memory, whereas on machines with
many registers these temps usually remain in registers. (However, these values often need to be
spilled into "activation frames" at the end of a procedure's definition, basic block, or at the very
least, into a memory buffer during interrupt processing). Values spilled to memory add more cache
cycles. This spilling effect depends on the number of hidden registers used to buffer top-of-stack
values, upon the frequency of nested procedure calls, and upon host computer interrupt processing

High cost of factoring out common subexpressions

In register machines, a common subexpression (a subexpression which is used multiple times with
the same result value) can be evaluated just once and its result saved in a fast register. The
subsequent reuses have no time or code cost, just a register reference. This optimization speeds
simple expressions (for example, loading variable X or pointer P) as well as less-common complex
expressions. With stack machines, in contrast, this is not feasible.

Hybrid machines

Pure stack machines are quite inefficient for procedures which access multiple fields from the same
object. A common fix for this is to add some register-machine features to the stack machine: a
visible register file dedicated to holding addresses, and register-style instructions for doing loads and
simple address calculations. It is uncommon to have the registers be fully general purpose, because
then there is no strong reason to have an expression stack and postfix instructions.

Stack machines are arguable almost the simplest kind architecture. Its LIFO structure is quite
suitable for block-oriented language. The code size for a stack machine can be very compact
because most instructions have no operand field. Stack architecture used to be very popular
method to implement high level language machine. Most of modern register machines are faster
but there is some 'renewal' effort to improve stack architecture.