Which of the following indicates the current position of the top of the stack

Architecture

Joseph Yiu, in The Definitive Guide to Arm® Cortex®-M0 and Cortex-M0+ Processors [Second Edition], 2015

4.4 Stack Memory Operations

Stack memory is a memory usage mechanism that allows the system memory to be used as temporary data storage that behaves as a first-in-last-out buffer. One of the essential elements of stack memory operation is a register called the Stack Pointer. The stack pointer indicates where the current stack memory location is, and is adjusted automatically each time a stack operation is carried out.

In the Cortex®-M processors, the Stack Pointer is register R13 in the register bank. Physically there are two stack pointers in the Cortex-M processors, but only one of them is used at a time, depending on the current value of the CONTROL register and the state of the processor [see Figure4.8].

In common terms, storing data to the stack is called pushing [using the PUSH instruction] and restoring data from the stack is called popping [using the POP instruction]. Depending on processor architecture, some processors perform storing of new data to stack memory using incremental address indexing and some use decrement address indexing. In the Cortex-M processors, the stack operation is based on a “full-descending” stack model. This means the stack pointer always points to the last filled data in the stack memory, and the stack pointer predecrements for each new data store [PUSH] [Figure4.12].

Figure4.12. Stack PUSH and POP in the Cortex®-M processors.

PUSH and POP are commonly used at the beginning and at the end of a function or subroutine. At the beginning of a function, the current contents of the registers used by the calling program are stored onto the stack memory using PUSH operations, and at the end of the function, the data on the stack memory is restored to the registers using POP operations. Typically, each register PUSH operation should have a corresponding register POP operation; otherwise the stack pointer will not be able to restore registers to their original values. This can result in unpredictable behaviors, for example, function return to incorrect addresses.

The minimum data size to be transferred for each push and pop operations is one word [32-bit] and multiple registers can be pushed or popped in one instruction. The stack memory accesses in the Cortex-M processors are designed to be always word aligned [address values must be a multiple of 4, for example, 0x0, 0x4, 0x8,…] as this gives the best efficiency for minimum design complexity. For this reason, bit [1:0] of both stack pointers in the Cortex-M processors are hardwired to zeros and read as zeros.

In programming, the stack pointer can be accessed as either R13 or SP in the program codes. Depending on the processor state and the CONTROL register value, the stack pointer accessed can either be the MSP or the PSP. In many simple applications, only one stack pointer is needed and by default the MSP is used. The PSP is usually only required when an OS is used in the embedded application.

In a typical embedded application with an OS, the OS kernel uses the MSP and the application processes use the PSP. This allows the stack for the kernel to be separate from stack memory for the application processes. This allows the OS to carry out context switching quickly [switching from execution of one application process to another]. Also, since exception handlers only use main stack, each of the stack spaces allocated to application tasks do not need to reserve space needed for exception handler, thus allow better memory usage efficiency.

Even though the OS kernel only uses the MSP as its stack pointer, it can still access the value in PSP by using special register access instructions [MRS and MSR] [Table 4.4].

Table 4.4. Stack pointer usage definition

Processor stateCONTROL[1]=0 [default setting]CONTROL[1]=1 [OS has started]
Thread modeUse MSP [R13 is MSP]Use PSP [R13 is PSP]
Handler modeUse MSP [R13 is MSP]Use MSP [R13 is MSP]

Since the stack grows downward [full-descending], it is common for the initial value of the stack pointer to be set to the upper boundary of SRAM. For example, if the SRAM memory range is from 0x20000000 to 0x20007FFF, we can start the stack pointer at 0x20008000. In this case, the first stack PUSH will take place at address 0x20007FFC, the top word of the SRAM [see Figure4.13].

Figure4.13. Example of stack pointer initial value.

The initial value of MSP is stored at the beginning of the program memory. Here we will find the exception vector table, which is introduced in the next section. The initial value of PSP is undefined, and therefore the PSP must be initialized by software before using it.

In many software development environments, the stack pointer can be set up again during the C start-up code [before entering “main[]”]. This two-stage stack initialization sequence enables a system to boot up the system with the stack pointing to a small internal SRAM inside the chip, and then change the stack definition to a larger external memory space after the external memory controller has been initialized.

View chapterPurchase book
Read full chapter
URL://www.sciencedirect.com/science/article/pii/B9780128032770000047

Non-essential operationsEdit

In many implementations, a stack has more operations than the essential "push" and "pop" operations. An example of a non-essential operation is "top of stack", or "peek", which observes the top element without removing it from the stack.[17] This could be done with a "pop" followed by a "push" to return the same data to the stack, so it is not considered an essential operation. If the stack is empty, an underflow condition will occur upon execution of either the "stack top" or "pop" operations. Additionally, many implementations provide a check if the stack is empty and one that returns its size.

Software stacksEdit

ImplementationEdit

A stack can be easily implemented either through an array or a linked list. What identifies the data structure as a stack, in either case, is not the implementation but the interface: the user is only allowed to pop or push items onto the array or linked list, with few other helper operations. The following will demonstrate both implementations, using pseudocode.

ArrayEdit

An array can be used to implement a [bounded] stack, as follows. The first element, usually at the zero offset, is the bottom, resulting in array[0] being the first element pushed onto the stack and the last element popped off. The program must keep track of the size [length] of the stack, using a variable top that records the number of items pushed so far, therefore pointing to the place in the array where the next element is to be inserted [assuming a zero-based index convention]. Thus, the stack itself can be effectively implemented as a three-element structure:

structure stack: maxsize: integer top: integer items: array of item procedure initialize[stk: stack, size: integer]: stk.items ← new array of size items, initially empty stk.maxsize ← size stk.top ← 0

The push operation adds an element and increments the top index, after checking for overflow:

procedure push[stk: stack, x: item]: if stk.top = stk.maxsize: report overflow error else: stk.items[stk.top] ← x stk.top ← stk.top + 1

Similarly, pop decrements the top index after checking for underflow, and returns the item that was previously the top one:

procedure pop[stk: stack]: if stk.top = 0: report underflow error else: stk.top ← stk.top − 1 r ← stk.items[stk.top] return r

Using a dynamic array, it is possible to implement a stack that can grow or shrink as much as needed. The size of the stack is simply the size of the dynamic array, which is a very efficient implementation of a stack since adding items to or removing items from the end of a dynamic array requires amortized O[1] time.

Linked listEdit

Another option for implementing stacks is to use a singly linked list. A stack is then a pointer to the "head" of the list, with perhaps a counter to keep track of the size of the list:

structure frame: data: item next: frame or nil structure stack: head: frame or nil size: integer procedure initialize[stk: stack]: stk.head ← nil stk.size ← 0

Pushing and popping items happens at the head of the list; overflow is not possible in this implementation [unless memory is exhausted]:

procedure push[stk: stack, x: item]: newhead ← new frame newhead.data ← x newhead.next ← stk.head stk.head ← newhead stk.size ← stk.size + 1 procedure pop[stk: stack]: if stk.head = nil: report underflow error r ← stk.head.data stk.head ← stk.head.next stk.size ← stk.size - 1 return r

Stacks and programming languagesEdit

Some languages, such as Perl, LISP, JavaScript and Python, make the stack operations push and pop available on their standard list/array types. Some languages, notably those in the Forth family [including PostScript], are designed around language-defined stacks that are directly visible to and manipulated by the programmer.

The following is an example of manipulating a stack in Common Lisp [">" is the Lisp interpreter's prompt; lines not starting with ">" are the interpreter's responses to expressions]:

> [setf stack [list 'a 'b 'c]] ;; set the variable "stack" [A B C] > [pop stack] ;; get top [leftmost] element, should modify the stack A > stack ;; check the value of stack [B C] > [push 'new stack] ;; push a new top onto the stack [NEW B C]

Several of the C++ Standard Library container types have push_back and pop_back operations with LIFO semantics; additionally, the stack template class adapts existing containers to provide a restricted API with only push/pop operations. PHP has an SplStack class. Java's library contains a Stack class that is a specialization of Vector. Following is an example program in Java language, using that class.

import java.util.Stack; class StackDemo { public static void main[String[]args] { Stack stack = new Stack[]; stack.push["A"]; // Insert "A" in the stack stack.push["B"]; // Insert "B" in the stack stack.push["C"]; // Insert "C" in the stack stack.push["D"]; // Insert "D" in the stack System.out.println[stack.peek[]]; // Prints the top of the stack ["D"] stack.pop[]; // removing the top ["D"] stack.pop[]; // removing the next top ["C"] } }

DescriptionEdit

Since the call stack is organized as a stack, the caller pushes the return address onto the stack, and the called subroutine, when it finishes, pulls or pops the return address off the call stack and transfers control to that address. If a called subroutine calls on yet another subroutine, it will push another return address onto the call stack, and so on, with the information stacking up and unstacking as the program dictates. If the pushing consumes all of the space allocated for the call stack, an error called a stack overflow occurs, generally causing the program to crash. Adding a subroutine's entry to the call stack is sometimes called "winding"; conversely, removing entries is "unwinding".

There is usually exactly one call stack associated with a running program [or more accurately, with each task or thread of a process], although additional stacks may be created for signal handling or cooperative multitasking [as with setcontext]. Since there is only one in this important context, it can be referred to as the stack [implicitly, "of the task"]; however, in the Forth programming language the data stack or parameter stack is accessed more explicitly than the call stack and is commonly referred to as the stack [see below].

In high-level programming languages, the specifics of the call stack are usually hidden from the programmer. They are given access only to a set of functions, and not the memory on the stack itself. This is an example of abstraction. Most assembly languages, on the other hand, require programmers to be involved with manipulating the stack. The actual details of the stack in a programming language depend upon the compiler, operating system, and the available instruction set.

Stack Class

  • Reference
Is this page helpful?

Is this page helpful?

Yes No
Any additional feedback?

Feedback will be sent to Microsoft: By pressing the submit button, your feedback will be used to improve Microsoft products and services. Privacy policy.

Submit

Thank you.

stack pointer

A stack pointer is a smallregisterthat stores the address of the last program request in a stack. A stack is a specialized buffer which stores data from the top down. The most recently entered request always resides at the top of the stack.

TechTarget Contributor
29 May 2012

A stack pointer is a smallregisterthat stores the address of the last program request in a stack. A stack is a specialized buffer which stores data from the top down. As new requests come in, they "push down" the older ones. The most recently entered request always resides at the top of the stack, and the program always takes requests from the top.

A stack [also called a pushdown stack] operates in a last-in/first-out sense. When a new data item is entered or "pushed" onto the top of a stack, the stack pointer increments to the next physical memory address, and the new item is copied to that address. When a data item is "pulled" or "popped" from the top of a stack, the item is copied from the address of the stack pointer, and the stack pointer decrements to the next available item at the top of the stack.

Continue Reading About stack pointer

  • The Department of Computer Science at the University of Maryland explains the operation of a stack and stack pointer in more technical terms.
  • Stack Exchange offers several examples to show how a stack pointer works.
  • Stack overflows versus stack overruns

Related Terms

  • processing in memory [PIM]
  • Scalable Processor Architecture [SPARC]
  • smart card

Implement a stack using singly linked list

To implement a stack using singly linked list concept , all the singly linked list operations are performed based on Stack operations LIFO[last in first out] and with the help of that knowledge we are going to implement a stack using single linked list. Using singly linked lists , we implement stack by storing the information in the form of nodes and we need to follow the stack rules and implement using singly linked list nodes . So we need to follow a simple rule in the implementation of a stack which is last in first out and all the operations can be performed with the help of a top variable .Let us learn how to perform Pop , Push , Peek ,Display operations in the following article .

A stack can be easily implemented using the linked list. In stack Implementation, a stack contains a top pointer. which is “head” of the stack where pushing and popping items happens at the head of the list. First node have null in link field and second node link have first node address in link field and so on and last node address in “top” pointer.
The main advantage of using linked list over an arrays is that it is possible to implement a stack that can shrink or grow as much as needed. In using array will put a restriction to the maximum capacity of the array which can lead to stack overflow. Here each new node will be dynamically allocate. so overflow is not possible.
Stack Operations:

  1. push[] : Insert a new element into stack i.e just inserting a new element at the beginning of the linked list.
  2. pop[] : Return top element of the Stack i.e simply deleting the first element from the linked list.
  3. peek[]: Return the top element.
  4. display[]: Print all elements in Stack.

Below is the implementation of the above approach:

C++




// C++ program to Implement a stack
//using singly linked list
#include
using namespace std;
// Declare linked list node
struct Node
{
int data;
Node* link;
};
Node* top;
// Utility function to add an element
// data in the stack insert at the beginning
void push[int data]
{
// Create new node temp and allocate memory in heap
Node* temp = new Node[];
// Check if stack [heap] is full.
// Then inserting an element would
// lead to stack overflow
if [!temp]
{
cout data = data;
// Put top pointer reference into temp link
temp->link = top;
// Make temp as top of Stack
top = temp;
}
// Utility function to check if
// the stack is empty or not
int isEmpty[]
{
//If top is NULL it means that
//there are no elements are in stack
return top == NULL;
}
// Utility function to return top element in a stack
int peek[]
{
// If stack is not empty , return the top element
if [!isEmpty[]]
return top->data;
else
exit[1];
}
// Utility function to pop top
// element from the stack
void pop[]
{
Node* temp;
// Check for stack underflow
if [top == NULL]
{
cout 33->22->11-> Top element is 44 22->11-> Top element is 22

Time Complexity:

The time complexity for all push[], pop[], and peek[] operations is O[1] as we are not performing any kind of traversal over the list. We perform all the operations through the current pointer only.




Article Tags :
Linked List
Stack
Technical Scripter
Technical Scripter 2018
Practice Tags :
Linked List
Stack
Read Full Article

Stack Class in Java

Java Collection framework provides a Stack class that models and implements a Stack data structure. The class is based on the basic principle of last-in-first-out. In addition to the basic push and pop operations, the class provides three more functions of empty, search, and peek. The class can also be said to extend Vector and treats the class as a stack with the five mentioned functions. The class can also be referred to as the subclass of Vector.The below diagram shows the hierarchy of the Stack class:

The class supports one default constructor Stack[] which is used to create an empty stack.

Declaration:



public class Stack extends Vector

All Implemented Interfaces:

  • Serializable: It is a marker interface that classes must implement if they are to be serialized and deserialized.
  • Cloneable: This is an interface in Java which needs to be implemented by a class to allow its objects to be cloned.
  • Iterable: This interface represents a collection of objects which is iterable — meaning which can be iterated.
  • Collection: A Collection represents a group of objects known as its elements. The Collection interface is used to pass around collections of objects where maximum generality is desired.
  • List: The List interface provides a way to store the ordered collection. It is a child interface of Collection.
  • RandomAccess: This is a marker interface used by List implementations to indicate that they support fast [generally constant time] random access.

How to Create a Stack?

In order to create a stack, we must import java.util.stack package and use the Stack[] constructor of this class. The below example creates an empty Stack.

Stack stack = new Stack[];

Here E is the type of Object.

Example:

Java




// Java code for stack implementation
import java.io.*;
import java.util.*;
class Test
{
// Pushing element on the top of the stack
static void stack_push[Stack stack]
{
for[int i = 0; i < 5; i++]
{
stack.push[i];
}
}
// Popping element from the top of the stack
static void stack_pop[Stack stack]
{
System.out.println["Pop Operation:"];
for[int i = 0; i < 5; i++]
{
Integer y = [Integer] stack.pop[];
System.out.println[y];
}
}
// Displaying element on the top of the stack
static void stack_peek[Stack stack]
{
Integer element = [Integer] stack.peek[];
System.out.println["Element on stack top: " + element];
}
// Searching element in the stack
static void stack_search[Stack stack, int element]
{
Integer pos = [Integer] stack.search[element];
if[pos == -1]
System.out.println["Element not found"];
else
System.out.println["Element is found at position: " + pos];
}
public static void main [String[] args]
{
Stack stack = new Stack[];
stack_push[stack];
stack_pop[stack];
stack_push[stack];
stack_peek[stack];
stack_search[stack, 2];
stack_search[stack, 6];
}
}

Output:

Pop Operation: 4 3 2 1 0 Element on stack top: 4 Element is found at position: 3 Element not found

Performing various operations on Stack class

1. Adding Elements: In order to add an element to the stack, we can use the push[] method. This push[] operation place the element at the top of the stack.

Java




// Java program to add the
// elements in the stack
import java.io.*;
import java.util.*;
class StackDemo {
// Main Method
public static void main[String[] args]
{
// Default initialization of Stack
Stack stack1 = new Stack[];
// Initialization of Stack
// using Generics
Stack stack2 = new Stack[];
// pushing the elements
stack1.push[4];
stack1.push["All"];
stack1.push["Geeks"];
stack2.push["Geeks"];
stack2.push["For"];
stack2.push["Geeks"];
// Printing the Stack Elements
System.out.println[stack1];
System.out.println[stack2];
}
}

Output:

[4, All, Geeks] [Geeks, For, Geeks]

2. Accessing the Element: To retrieve or fetch the first element of the Stack or the element present at the top of the Stack, we can use peek[] method. The element retrieved does not get deleted or removed from the Stack.

Java




// Java program to demonstrate the accessing
// of the elements from the stack
import java.util.*;
import java.io.*;
public class StackDemo {
// Main Method
public static void main[String args[]]
{
// Creating an empty Stack
Stack stack = new Stack[];
// Use push[] to add elements into the Stack
stack.push["Welcome"];
stack.push["To"];
stack.push["Geeks"];
stack.push["For"];
stack.push["Geeks"];
// Displaying the Stack
System.out.println["Initial Stack: " + stack];
// Fetching the element at the head of the Stack
System.out.println["The element at the top of the"
+ " stack is: " + stack.peek[]];
// Displaying the Stack after the Operation
System.out.println["Final Stack: " + stack];
}
}

Output:

Initial Stack: [Welcome, To, Geeks, For, Geeks] The element at the top of the stack is: Geeks Final Stack: [Welcome, To, Geeks, For, Geeks]

3. Removing Elements: To pop an element from the stack, we can use the pop[] method. The element is popped from the top of the stack and is removed from the same.

Java




// Java program to demonstrate the removing
// of the elements from the stack
import java.util.*;
import java.io.*;
public class StackDemo {
public static void main[String args[]]
{
// Creating an empty Stack
Stack stack = new Stack[];
// Use add[] method to add elements
stack.push[10];
stack.push[15];
stack.push[30];
stack.push[20];
stack.push[5];
// Displaying the Stack
System.out.println["Initial Stack: " + stack];
// Removing elements using pop[] method
System.out.println["Popped element: "
+ stack.pop[]];
System.out.println["Popped element: "
+ stack.pop[]];
// Displaying the Stack after pop operation
System.out.println["Stack after pop operation "
+ stack];
}
}

Output:

Initial Stack: [10, 15, 30, 20, 5] Popped element: 5 Popped element: 20 Stack after pop operation [10, 15, 30]

Methods in Stack Class

METHOD

DESCRIPTION

empty[]

It returns true if nothing is on the top of the stack. Else, returns false.

peek[]

Returns the element on the top of the stack, but does not remove it.

pop[]

Removes and returns the top element of the stack. An ‘EmptyStackException’

An exception is thrown if we call pop[] when the invoking stack is empty.

push[Object element]

Pushes an element on the top of the stack.

search[Object element]

It determines whether an object exists in the stack. If the element is found,

It returns the position of the element from the top of the stack. Else, it returns -1.

Methods inherited from class java.util.Vector

METHOD

DESCRIPTION

add[Object obj] Appends the specified element to the end of this Vector.
add[int index, Object obj] Inserts the specified element at the specified position in this Vector.
addAll[Collection c]

Appends all of the elements in the specified Collection to the end of this Vector,

in the order that they are returned by the specified Collection’s Iterator.

addAll[int index, Collection c] Inserts all the elements in the specified Collection into this Vector at the specified position.
addElement[Object o] Adds the specified component to the end of this vector, increasing its size by one.
capacity[] Returns the current capacity of this vector.
clear[] Removes all the elements from this Vector.
clone[] Returns a clone of this vector.
contains[Object o] Returns true if this vector contains the specified element.
containsAll[Collection c] Returns true if this Vector contains all the elements in the specified Collection.
copyInto[Object []array] Copies the components of this vector into the specified array.
elementAt[int index] Returns the component at the specified index.
elements[] Returns an enumeration of the components of this vector.
ensureCapacity[int minCapacity]

Increases the capacity of this vector, if necessary, to ensure that it can hold

at least the number of components specified by the minimum capacity argument.

equals[] Compares the specified Object with this Vector for equality.
firstElement[] Returns the first component [the item at index 0] of this vector.
get[int index] Returns the element at the specified position in this Vector.
hashCode[] Returns the hash code value for this Vector.
indexOf[Object o]

Returns the index of the first occurrence of the specified element in this vector, or -1

if this vector does not contain the element.

indexOf[Object o, int index] Returns the index of the first occurrence of the specified element in this vector, searching forwards from the index, or returns -1 if the element is not found.
insertElementAt[Object o, int index] Inserts the specified object as a component in this vector at the specified index.
isEmpty[] Tests if this vector has no components.
iterator[] Returns an iterator over the elements in this list in proper sequence.
lastElement[] Returns the last component of the vector.
lastIndexOf[Object o]

Returns the index of the last occurrence of the specified element in this vector, or -1

If this vector does not contain the element.

lastIndexOf[Object o, int index]

Returns the index of the last occurrence of the specified element in this vector,

searching backward from the index, or returns -1 if the element is not found.

listIterator[] Returns a list iterator over the elements in this list [in proper sequence].
listIterator[int index]

Returns a list iterator over the elements in this list [in proper sequence],

starting at the specified position in the list.

remove[int index] Removes the element at the specified position in this Vector.
remove[Object o] Removes the first occurrence of the specified element in this Vector If the Vector does not contain the element, it is unchanged.
removeAll[Collection c] Removes from this Vector all of its elements that are contained in the specified Collection.
removeAllElements[] Removes all components from this vector and sets its size to zero.
removeElement[Object o] Removes the first [lowest-indexed] occurrence of the argument from this vector.
removeElementAt[int index] Deletes the component at the specified index.
removeRange[int fromIndex, int toIndex] Removes from this list all the elements whose index is between fromIndex, inclusive, and toIndex, exclusive.
retainAll[Collection c] Retains only the elements in this Vector that are contained in the specified Collection.
set[int index, Object o] Replaces the element at the specified position in this Vector with the specified element.
setElementAt[Object o, int index] Sets the component at the specified index of this vector to be the specified object.
setSize[int newSize] Sets the size of this vector.
size[] Returns the number of components in this vector.
subList[int fromIndex, int toIndex] Returns a view of the portion of this List between fromIndex, inclusive, and toIndex, exclusive.
toArray[] Returns an array containing all of the elements in this Vector in the correct order.
toArray[Object []array]

Returns an array containing all of the elements in this Vector in the correct order; the runtime

type of the returned array is that of the specified array.

toString[] Returns a string representation of this Vector, containing the String representation of each element.
trimToSize[] Trims the capacity of this vector to be the vector’s current size.

Note: Please note that the Stack class in Java is a legacy class and inherits from Vector in Java. It is a thread-safe class and hence involves overhead when we do not need thread safety. It is recommended to use ArrayDeque for stack implementation as it is more efficient in a single-threaded environment.

Java




// A Java Program to show implementation
// of Stack using ArrayDeque
import java.util.*;
class GFG {
public static void main [String[] args] {
Deque stack = new ArrayDeque[];
stack.push['A'];
stack.push['B'];
System.out.println[stack.peek[]];
System.out.println[stack.pop[]];
}
}

Output:

B B




Article Tags :
Java
Stack
Java - util package
Java-Collections
Java-Stack
Practice Tags :
Stack
Java
Java-Collections
Read Full Article

Video liên quan

Bài Viết Liên Quan

Bài mới nhất

Chủ Đề