stack segements?
-
Sliver
RE:stack segements?
The stack segment is a part of the physical memory where are stored the values used via the pop* and push* instructions. The SS register of an x86 CPU points to the current stack segment, the SP points to the top of the stack so SS:SP will point to the top of the stack. The BP register points to the stack's base. The stack is also used by other instructions such as call.
Try reading some asm / x86 documents.
Ciprian
Try reading some asm / x86 documents.
Ciprian
-
Schol-R-LEA
RE:stack segements?
Well, let's start with a quick review of basic data structures (if you understand *what* stacks are, you can skip this part). Stacks, if you haven't learned by now, are a basic data structure in which items are 'stacked' or 'pushed' onto a conceptual pile or stack, and removed ('popped') in the exact order they were pushed in. In the simplest case, there is a block of memory already assigned for the stack to grow into, and the top of the stack is simply represented by a pointer to the most recently added item. For example, if you have an empty stack with room for four items:
| |
| |
| |
| | < - top = 0
---
if you push two items, a and b, it would then look like
| | | | | |
| | | | | |
| | | | |b|<- top = 1
| | |a|<- top = 0 |a|
---<- top = base --- ---
if you then pushed c, popped c and b back off, and pushed d, e and f, it would be
| | | | | | | | | | |f|<-top=3
|c|<- top = 2 | | | | | | |e|<-top=2 |e|
|b| |b|<-top=1 | | |d|<-top=1 |d| |d|
|a| |a| |a|<-top=0 |a| |a| |a|
--- --- --- --- --- ---
Notice that the stack is full; if you tries to push another item onto it, you get what is called a stack overflow. Some types f stacks will grow automatically to fit whatever size they need, but this simple stack - which can be implemented in hardware as two registers, one for the base of the stack and one for the top of the stack - is limited to the space allocated for it.
Stacks are an extremely useful data structure for two particular reasons, both having to do with function calls. First, if when you jump to a function or subroutine, you first push the address of the instruction following the jump onto the stack, the function then can pop that address off when it is done, and return to the place where it was invoked from without having the address hardwired into it - thus, you can call the same function from anywhere in the code, even recursively, and it will return correctly. This is the main reason that most CPUs implement a stack in hardware, and virtually all of them have a pair of special instructions for performing the function call and the function return as a single action; on the x86, these are CALL and RET, respectively (there is also a RETF, which is used to return from a 'far' call between two different code segments, but that's getting ahead of things).
Second, if the arguments and data for a function are stored on the stack, rather than at a fixed location in general data, it allows you to call functions recursively; each new call has it's own 'frame' on the stack, and the individual items are referenced using a special pointer call the frame pointer, or base pointer. When the function returns, it pops all of it's data and arguments back off, clearing the space away for reuse. See http://www.delorie.com/djgpp/doc/ug/asm/calling.html and http://www.osdev.org/developers/guide01/ for more details, if you want to.
But wait, there's more... To understand the x86 stack segment, you have to first understand the segmented memory architecture of the x86 CPUs. There are several explanations of segmentation on this board and in the various tutorials. My own best attempt at doing so (if you can ignore the typoes) is at http://204.215.248.28/board.jsp?message=1417 . A better introduction can be found in my favorite assembly language book, _Assembly Language Step By Step_ by Jeff Duntemann. The best source of detailed information is Intel's own documentation, which can be downloaded from their web site, http://www.intel.com/ .
Assuming you've read one of those now and undertsand about segmentation... a big assumption, I know... the purpose of the stack segment should be a bit clearer. It simply acts as a way of assigning an area of memory for the stack to operate in. The segmentation both protects the stack from memory overruns by the rest of the program, and also protects the rest of the program from stack overflows or underflows. Or that, at least, seems to have been the idea.
Comments and Corrections Welcome.
| |
| |
| |
| | < - top = 0
---
if you push two items, a and b, it would then look like
| | | | | |
| | | | | |
| | | | |b|<- top = 1
| | |a|<- top = 0 |a|
---<- top = base --- ---
if you then pushed c, popped c and b back off, and pushed d, e and f, it would be
| | | | | | | | | | |f|<-top=3
|c|<- top = 2 | | | | | | |e|<-top=2 |e|
|b| |b|<-top=1 | | |d|<-top=1 |d| |d|
|a| |a| |a|<-top=0 |a| |a| |a|
--- --- --- --- --- ---
Notice that the stack is full; if you tries to push another item onto it, you get what is called a stack overflow. Some types f stacks will grow automatically to fit whatever size they need, but this simple stack - which can be implemented in hardware as two registers, one for the base of the stack and one for the top of the stack - is limited to the space allocated for it.
Stacks are an extremely useful data structure for two particular reasons, both having to do with function calls. First, if when you jump to a function or subroutine, you first push the address of the instruction following the jump onto the stack, the function then can pop that address off when it is done, and return to the place where it was invoked from without having the address hardwired into it - thus, you can call the same function from anywhere in the code, even recursively, and it will return correctly. This is the main reason that most CPUs implement a stack in hardware, and virtually all of them have a pair of special instructions for performing the function call and the function return as a single action; on the x86, these are CALL and RET, respectively (there is also a RETF, which is used to return from a 'far' call between two different code segments, but that's getting ahead of things).
Second, if the arguments and data for a function are stored on the stack, rather than at a fixed location in general data, it allows you to call functions recursively; each new call has it's own 'frame' on the stack, and the individual items are referenced using a special pointer call the frame pointer, or base pointer. When the function returns, it pops all of it's data and arguments back off, clearing the space away for reuse. See http://www.delorie.com/djgpp/doc/ug/asm/calling.html and http://www.osdev.org/developers/guide01/ for more details, if you want to.
But wait, there's more... To understand the x86 stack segment, you have to first understand the segmented memory architecture of the x86 CPUs. There are several explanations of segmentation on this board and in the various tutorials. My own best attempt at doing so (if you can ignore the typoes) is at http://204.215.248.28/board.jsp?message=1417 . A better introduction can be found in my favorite assembly language book, _Assembly Language Step By Step_ by Jeff Duntemann. The best source of detailed information is Intel's own documentation, which can be downloaded from their web site, http://www.intel.com/ .
Assuming you've read one of those now and undertsand about segmentation... a big assumption, I know... the purpose of the stack segment should be a bit clearer. It simply acts as a way of assigning an area of memory for the stack to operate in. The segmentation both protects the stack from memory overruns by the rest of the program, and also protects the rest of the program from stack overflows or underflows. Or that, at least, seems to have been the idea.
Comments and Corrections Welcome.
-
Schol-R-LEA
Damn proportional fonts!
Unfortunately, my ASCII diagram got mangled by the difference in the font used by the editor and the one used to display the messages. If you cut and paste the diagram to a simple text editor like notepad or gnupad, it should be legible.
-
anton
RE:stack segements?
Well, strictly answering your question: a stack segment is a segment containing the stack of the
program(thread), used internaly by the CPU(and the program).
You probably ment : what is a stack.
Anton
program(thread), used internaly by the CPU(and the program).
You probably ment : what is a stack.
Anton