52

I am preparing for a microprocessor exam. If the use of a program counter is to hold the address of the next instruction, what is use of stack pointer?

Mangu Singh Rajpurohit
  • 8,894
  • 2
  • 50
  • 76

9 Answers9

100

A stack is a LIFO (last in, first out - the last entry you push on to the stack is the first one you get back when you pop) data structure that is typically used to hold stack frames (bits of the stack that belong to the current function).

This includes, but is not limited to:

  • the return address.
  • a place for a return value.
  • passed parameters.
  • local variables.

You push items onto the stack and pop them off. In a microprocessor, the stack can be used for both user data (such as local variables and passed parameters) and CPU data (such as return addresses when calling subroutines).

The actual implementation of a stack depends on the microprocessor architecture. It can grow up or down in memory and can move either before or after the push/pop operations.

Operation which typically affect the stack are:

  • subroutine calls and returns.
  • interrupt calls and returns.
  • code explicitly pushing and popping entries.
  • direct manipulation of the SP register.

Consider the following program in my (fictional) assembly language:

Addr  Opcodes   Instructions    ; Comments
----  --------  --------------  ----------
                                ; 1: pc<-0000, sp<-8000
0000  01 00 07  load r0,7       ; 2: pc<-0003, r0<-7
0003  02 00     push r0         ; 3: pc<-0005, sp<-7ffe, (sp:7ffe)<-0007
0005  03 00 00  call 000b       ; 4: pc<-000b, sp<-7ffc, (sp:7ffc)<-0008
0008  04 00     pop r0          ; 7: pc<-000a, r0<-(sp:7ffe[0007]), sp<-8000
000a  05        halt            ; 8: pc<-000a
000b  06 01 02  load r1,[sp+2]  ; 5: pc<-000e, r1<-(sp+2:7ffe[0007])
000e  07        ret             ; 6: pc<-(sp:7ffc[0008]), sp<-7ffe

Now let's follow the execution, describing the steps shown in the comments above:

  1. This is the starting condition where the program counter is zero and the stack pointer is 8000 (all these numbers are hexadecimal).
  2. This simply loads register r0 with the immediate value 7 and moves to the next step (I'll assume that you understand the default behavior will be to move to the next step unless otherwise specified).
  3. This pushes r0 onto the stack by reducing the stack pointer by two then storing the value of the register to that location.
  4. This calls a subroutine. What would have been the program counter is pushed on to the stack in a similar fashion to r0 in the previous step and then the program counter is set to its new value. This is no different to a user-level push other than the fact it's done more as a system-level thing.
  5. This loads r1 from a memory location calculated from the stack pointer - it shows a way to pass parameters to functions.
  6. The return statement extracts the value from where the stack pointer points and loads it into the program counter, adjusting the stack pointer up at the same time. This is like a system-level pop (see next step).
  7. Popping r0 off the stack involves extracting the value from where the stack pointer points then adjusting that stack pointer up.
  8. Halt instruction simply leaves program counter where it is, an infinite loop of sorts.

Hopefully from that description, it will become clear. Bottom line is: a stack is useful for storing state in a LIFO way and this is generally ideal for the way most microprocessors do subroutine calls.

Unless you're a SPARC of course, in which case you use a circular buffer for your stack :-)

Update: Just to clarify the steps taken when pushing and popping values in the above example (whether explicitly or by call/return), see the following examples:

LOAD R0,7
PUSH R0
                     Adjust sp       Store val
sp-> +--------+      +--------+      +--------+
     |  xxxx  |  sp->|  xxxx  |  sp->|  0007  |
     |        |      |        |      |        |
     |        |      |        |      |        |
     |        |      |        |      |        |
     +--------+      +--------+      +--------+

POP R0
                     Get value       Adjust sp
     +--------+      +--------+  sp->+--------+
sp-> |  0007  |  sp->|  0007  |      |  0007  |
     |        |      |        |      |        |
     |        |      |        |      |        |
     |        |      |        |      |        |
     +--------+      +--------+      +--------+
Community
  • 1
  • 1
paxdiablo
  • 772,407
  • 210
  • 1,477
  • 1,841
  • 3
    This answer is all kinds of win. – Paul Nathan Sep 23 '09 at 05:45
  • I love SPARC and its register windows :) – Polaris878 Sep 23 '09 at 16:15
  • So stack overflow happens when someone would reach FFFF+1 bit in the SP? And what would happen then? – Denys S. Feb 10 '13 at 10:28
  • 1
    @DenysS, a stack overflow happens when you _push_ too many things - that's going to be a decresing SP assuming the stack grows downward. What happens depends on what it runs into. If it runs into your data, your program will be suspect. If it runs into your code it will probably be catastrophic as the code instructions are set to arbitrary values. The stack going above ffff would actually be a stack underflow (too many pops). In any case, what happens is pretty much a crapshoot - anything _could_ happen so you want to avoid it. – paxdiablo Feb 10 '13 at 10:32
  • @paxdiablo, that was a actually another strange behavior (to me at least), why do we start at 8000 if we are sure that nothing is in the stack at that point, why don't we start at 0000? In other words, why do we subtract 2 when we push or why does a stack grow downwards? – Denys S. Feb 10 '13 at 10:36
  • @DenysS, see http://stackoverflow.com/questions/2035568/why-do-stacks-typically-grow-downwards/2035592#2035592 for some informed spuculation. – paxdiablo Feb 10 '13 at 10:41
  • 1
    This is one of the best answers I've ever seen. – suprjami Sep 13 '14 at 12:36
  • Great answer! Unless I'm misunderstanding something, I think 000b in 4th line should read 0008 and 000a in 6th line should read 000b. – dust Jun 14 '18 at 19:16
  • 1
    @dust, l don't think so. Line 4 calls 000b so that's what ends up in the PC. The halt is the only instruction that doesn't update PC so it effectively halts the program. That's why it sets PC to 000a. Let me know if that clears it up or I've misunderstood. – paxdiablo Jun 14 '18 at 23:32
14

The stack pointer stores the address of the most recent entry that was pushed onto the stack.

To push a value onto the stack, the stack pointer is incremented to point to the next physical memory address, and the new value is copied to that address in memory.

To pop a value from the stack, the value is copied from the address of the stack pointer, and the stack pointer is decremented, pointing it to the next available item in the stack.

The most typical use of a hardware stack is to store the return address of a subroutine call. When the subroutine is finished executing, the return address is popped off the top of the stack and placed in the Program Counter register, causing the processor to resume execution at the next instruction following the call to the subroutine.

http://en.wikipedia.org/wiki/Stack_%28data_structure%29#Hardware_stacks

Robert Harvey
  • 168,684
  • 43
  • 314
  • 475
6

You got more preparing [for the exam] to do ;-)

The Stack Pointer is a register which holds the address of the next available spot on the stack.

The stack is a area in memory which is reserved to store a stack, that is a LIFO (Last In First Out) type of container, where we store the local variables and return address, allowing a simple management of the nesting of function calls in a typical program.

See this Wikipedia article for a basic explanation of the stack management.

mjv
  • 67,473
  • 12
  • 100
  • 152
4

For 8085: Stack pointer is a special purpose 16-bit register in the Microprocessor, which holds the address of the top of the stack.

The stack pointer register in a computer is made available for general purpose use by programs executing at lower privilege levels than interrupt handlers. A set of instructions in such programs, excluding stack operations, stores data other than the stack pointer, such as operands, and the like, in the stack pointer register. When switching execution to an interrupt handler on an interrupt, return address data for the currently executing program is pushed onto a stack at the interrupt handler's privilege level. Thus, storing other data in the stack pointer register does not result in stack corruption. Also, these instructions can store data in a scratch portion of a stack segment beyond the current stack pointer.

Read this one for more info.

General purpose use of a stack pointer register

rahul
  • 174,563
  • 47
  • 223
  • 254
  • 1
    Good Lord, do people really patent this stuff? What a crock. I should patent the posting of programming questions and answers to a Q*A site. Then all of you would have to pay me royalties. – Robert Harvey Sep 23 '09 at 05:36
2

The Stack is an area of memory for keeping temporary data. Stack is used by the CALL instruction to keep the return address for procedures The return RET instruction gets this value from the stack and returns to that offset. The same thing happens when an INT instruction calls an interrupt. It stores in the Stack the flag register, code segment and offset. The IRET instruction is used to return from interrupt call.

The Stack is a Last In First Out (LIFO) memory. Data is placed onto the Stack with a PUSH instruction and removed with a POP instruction. The Stack memory is maintained by two registers: the Stack Pointer (SP) and the Stack Segment (SS) register. When a word of data is PUSHED onto the stack the the High order 8-bit Byte is placed in location SP-1 and the Low 8-bit Byte is placed in location SP-2. The SP is then decremented by 2. The SP addds to the (SS x 10H) register, to form the physical stack memory address. The reverse sequence occurs when data is POPPED from the Stack. When a word of data is POPPED from the stack the the High order 8-bit Byte is obtained in location SP-1 and the Low 8-bit Byte is obtained in location SP-2. The SP is then incremented by 2.

Nitish Upreti
  • 5,931
  • 9
  • 46
  • 85
1

The stack pointer holds the address to the top of the stack. A stack allows functions to pass arguments stored on the stack to each other, and to create scoped variables. Scope in this context means that the variable is popped of the stack when the stack frame is gone, and/or when the function returns. Without a stack, you would need to use explicit memory addresses for everything. That would make it impossible (or at least severely difficult) to design high-level programming languages for the architecture. Also, each CPU mode usually have its own banked stack pointer. So when exceptions occur (interrupts for example), the exception handler routine can use its own stack without corrupting the user process.

1

Should you ever crave deeper understanding, I heartily recommend Patterson and Hennessy as an intro and Hennessy and Patterson as an intermediate to advanced text. They're pricey, but truly non-pareil; I just wish either or both were available when I got my Masters' degree and entered the workforce designing chips, systems, and parts of system software for them (but, alas!, that was WAY too long ago;-). Stack pointers are so crucial (and the distinction between a microprocessor and any other kind of CPU so utterly meaningful in this context... or, for that matter, in ANY other context, in the last few decades...!-) that I doubt anything but a couple of thorough from-the-ground-up refreshers can help!-)

Alex Martelli
  • 762,786
  • 156
  • 1,160
  • 1,345
  • nonpariel - a small, flat chocolate drop covered with white pellets of sugar. Mmm, chocolate and sugar. Oh, you meant the *adjective*, "without equal"? Well, there's my word learned for the week. – paxdiablo Sep 23 '09 at 06:04
  • 1
    @pax, pariel != pareil. I before E except when it's not!-) – Alex Martelli Sep 23 '09 at 06:07
  • +1 but I have evil flashback about that book late at night when I'm all alone. The book is excellent... I still have it on my shelf. It's the class associated with it that did it to me. – beggs Sep 24 '09 at 02:03
0

On some CPUs, there is a dedicated set of registers for the stack. When a call instruction is executed, one register is loaded with the program counter at the same time as a second register is loaded with the contents of the first, a third register is be loaded with the second, and a fourth with the third, etc. When a return instruction is executed, the program counter is latched with the contents of the first stack register and the same time as that register is latched from the second; that second register is loaded from a third, etc. Note that such hardware stacks tend to be rather small (many the smaller PIC series micros, for example, have a two-level stack).

While a hardware stack does have some advantages (push and pop don't add any time to a call/return, for example) having registers which can be loaded with two sources adds cost. If the stack gets very big, it will be cheaper to replace the push-pull registers with an addressable memory. Even if a small dedicated memory is used for this, it's cheaper to have 32 addressable registers and a 5-bit pointer register with increment/decrement logic, than it is to have 32 registers each with two inputs. If an application might need more stack than would easily fit on the CPU, it's possible to use a stack pointer along with logic to store/fetch stack data from main RAM.

supercat
  • 69,493
  • 7
  • 143
  • 184
-2

A stack pointer is a small register that stores the address of the top of stack. It is used for the purpose of pointing address of the top of the stack.

rashedcs
  • 2,709
  • 2
  • 29
  • 32