Stack
Home * Programming * Data * Stack
A Stack is a linear data structure to collect data elements in last in, first out order (LIFO). The only elementary operations are push and pop. Push adds one element on the top of stack, while pop removes an entry from the top of the stack and returns that element to the caller. Entries are removed from the stack in the reverse order of their additions. In practice, there is often a third operation. Peek retrieves the top element without removing the entry from the stack.
The stack is a natural structure to remember where to continue after some work was interrupted to do some more important tasks, which itself might be interrupted again, even recursively and multiple times. This applies to depth-first tree traversals like minimax search or evaluating nested arithmetical expressions.
Contents
Software Stack
A stack can be implemented through an array or a linked list, for instance in C-like pseudo code with a fixed sized array in conjunction with typical pre-increment and post-decrement:
int tos = -1; // index top of stack int stack[STACKSIZE]; // fixed sized array void push (int element) { if (tos == STACKSIZE - 1) throw stack overflow exception; stack[++tos] = element; } int pop () { if (tos == -1 ) throw stack underflow exception; return stack[tos--]; }
Hardware Stack
Most central processing units support a hardware stack (processor stack, call stack) as part of the main memory. Processors have a special register, pointing to the top of stack (stack pointer), and push and pop instructions respectively. Intel processors from 8080 until x86-64 let the stack grow from higher to lower addresses via pre-decrement push and post-increment pop.
push(register) ::= stack[--sp] := register pop (register) ::= register := stack[sp++]
To implement such hardware stacks was motivated by control flow considerations of calling and returning from subroutines, possibly recursively as coined by Algol-like programming languages. A call instruction pushes the program address of the next instruction on the stack, just before it sets its instruction pointer register to the subroutine-address. After executing the subroutine, a trailing return instruction pops the return address from the stack into the instruction pointer, to continue the execution flow as expected. Additionally, high level procedural programming languages demanded local variables. While actual parameters were pushed before the call applying certain calling conventions of various platforms and compiler [2][3], the callee did accordant stack pointer manipulations, to reserve or allocate a stack frame for local, automatic variables. Intel's 16-bit 8086 introduced an additional register, intended as base pointer into a possible variable stack frame, and the option of dynamic frame re-allocation.
A typical 8086 stack frame with Pascal calling conventions, where the callee is responsible for balancing the stack. Similar stack layout appears in x86 with 32-bit extended registers (esp, ebp) and stack entries [4].
push word para1 push word para2 call foo ... foo proc near push bp mov bp, sp sub sp, 3*2 ; allocate space for three local 16-bit variables ... mov sp, bp pop bp ret 4 ; return and "pop" additional four bytes of the parameters
with following memory layout inside the scope of foo:
stack growth ^ <---- 16 bit ----> | +------------------+ +------+ | local variable 3 | [bp-6] <---| SP | +------------------+ +------+ | local variable 2 | [bp-4] +------------------+ | local variable 1 | [bp-2] +------------------+ +------+ | saved bp | <----------| BP | +------------------+ +------+ | return address | +------------------+ | parameter 2 | [bp+4] +------------------+ | parameter 1 | [bp+6] | +------------------+ v higher addresses
Applications
Stack Calculator
The Reverse Polish or Postfix notation scheme as proposed in 1954 by Burks, Warren, and Wright [5] , was independently reinvented by Friedrich L. Bauer, Klaus Samelson [6] and Edsger W. Dijkstra in the early 1960s to coin and utilize the stack data structure to efficiently evaluate expressions, likely after parsing infix notation recursively, which is actually a depth-first traversal of a expression tree.
Infix:
(1 + 2)*(3 + 4)
Infix Tree:
* + + 1 2 3 4
Postfix Stack:
push 1 push 2 add push 3 push 4 add mul
Many todays compiler and interpreter work that way, so does the Java Virtual Machine. Reverse Polish notation is further utilized in the Forth Stack-oriented programming language.
Depth-First Search
In computer game programming, a stack of nodes is also the appropriate data structure in depth-first tree search, like Minimax or Alpha-beta. Immediately before a move is made to search further, the node is pushed on the stack - and popped back while unmaking. Despite global state variables like a board representation, which are updated incrementally, programs implicitly use the processor stack by passing parameters to a recursive search routine with local variables. A software stack is obligatory for an iterative search, and likely implemented as array indexed by ply.
See also
- Array
- Forth
- Linked List
- Linked List on the Stack from Triangular PV-Table
- PV-List on the Stack from Principal variation
- Queue
Publications
- Arthur W. Burks, Don W. Warren, Jesse B. Wright (1954) An Analysis of a Logical Machine Using Parenthesis-Free Notation.
- Klaus Samelson, Friedrich L. Bauer (1960). Sequential Formula Translation. Communications of the ACM, Vol. 3 No. 2
- Craig A. Finseth (1980). Something is Missing (Implementing recursion and stacks in BASIC). The Best of Creative Computing Volume 3 » Basic
- Donald Knuth (1997). The Art of Computer Programming, Volume 1: Fundamental Algorithms (Third Edition), Addison-Wesley, ISBN 0-201-89683-4, 2.2.1: Stacks, Queues, and Deques
- Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, Clifford Stein (2009).Introduction to Algorithms, 3rd Edition
Forum Posts
- LIFO stack based parallel processing? by Srdja Matovic, CCC, September 22, 2011
External Links
- Stack from Wikipedia
- Stack (abstract data type) from Wikipedia
- Call stack from Wikipedia
- stack from Dictionary of Algorithms and Data Structures by Paul E. Black, National Institute of Standards and Technology
- LIFO (computing) from Wikipedia
- Call stack from Wikipedia
- Stack overflow from Wikipedia
- Stack-based memory allocation from Wikipedia
- Stack machine from Wikipedia
- Stack-oriented programming language from Wikipedia
x86
- x86 Disassembly/The Stack from Wikibooks
- x86 Disassembly/Functions and Stack Frames from Wikibooks
- Where the top of the stack is on x86 from Eli Bendersky's website, February 04, 2011
x86-64
- Stack frame layout on x86-64 from Eli Bendersky's website, September 06, 2011
C++
Java
.NET
References
- ↑ Stapelspeicher - Wikipedia.de (German)
- ↑ x86 calling conventions from Wikipedia
- ↑ Calling conventions for different C++ compilers and operating systems (pdf) by Agner Fog
- ↑ x86 Disassembly/Functions and Stack Frames from Wikibooks
- ↑ Arthur W. Burks, Don W. Warren, Jesse B. Wright (1954) An Analysis of a Logical Machine Using Parenthesis-Free Notation.
- ↑ Klaus Samelson, Friedrich L. Bauer (1960). Sequential Formula Translation. Communications of the ACM, Vol. 3 No. 2, pp. 76-83