2

I'm reading Professional Assembly Language by Richard Blum,and I am confusing about a Inconsistency in the book and I wondering what exactly is program stack's growth direction? This is the picture from page 312, which is suggesting that program stack grows up.

enter image description here

But when I reached page 322,I see another version, which suggesting that program stack grows down. enter image description here

and this

enter image description here

nrz
  • 10,435
  • 4
  • 39
  • 71
ssj
  • 1,737
  • 2
  • 16
  • 28
  • Possible duplicate of [Does stack grow upward or downward?](http://stackoverflow.com/questions/1677415/does-stack-grow-upward-or-downward) – Frédéric Hamidi Dec 08 '13 at 11:26
  • I am talking about inconsistent between the two version of the book. – ssj Dec 08 '13 at 11:33
  • Since there are two conventions of drawing the stack, the terms up and down are a bit misleading. But the easiest way to find out in any architecture is to compile a simple function with -O0 and check what is the instruction that creates the stack frame. In the current system I work with, it's `sub r1, #xxx`; so the stack grows to lesser addresses. Another is to find the interpretation of "push x" from the ISA manual. – Aki Suihkonen Dec 08 '13 at 11:34
  • Related: http://stackoverflow.com/questions/14296088/what-is-this-assembly-code-doing/14298164#14298164 (for x86-64, replace `rsp`->`esp`, 8 -> 4). – nrz Dec 08 '13 at 11:57
  • 1
    To determine which way a stack grows, compare the stack pointer before and after a "push" instruction. – Kerrek SB Dec 08 '13 at 13:11
  • possible duplicate of [What is the direction of stack growth in most modern systems?](http://stackoverflow.com/questions/664744/what-is-the-direction-of-stack-growth-in-most-modern-systems) – artless noise Dec 09 '13 at 15:38

4 Answers4

4

The book is not inconsistent; each drawing shows higher addresses at the top.

The first drawing illustrates a stack that grows downward. The caller pushes parameters onto the stack, then calls the new function. The act of calling pushes the return address onto the stack. The callee then pushes the current value of the base pointer onto the stack, copies the stack pointer into the base pointer, and decrements the stack pointer to make room for the callee's local variables.

Mark Plotnick
  • 9,598
  • 1
  • 24
  • 40
  • And in this case, function parameters are pushed from right to left; C does this to support functions with a variable number of parameters, like `printf`. – CL. Dec 08 '13 at 14:00
2

Some background:

For different processors the meaning of the stack pointer and the direction of the stack may differ. For TMS Piccolo controllers stack is growing up so that "PUSH" will increment the stack pointer. The stack pointer may point to the value last pushed or to the location where the next value to be pushed is written to. The ARM processor allows all 4 possible combinations for the stack so there must be a convention on how to use the stack pointer.

On x86 processors:

On x86 processors stack ALWAYS grows downwards so a "PUSH" instruction will decrement the stack pointer; the stack pointer always points to the last value pushed.

The first picture shows you that the addresses after the stack pointer (address > stack pointer) already contain values. If you store more values to the stack they are stored to locations below the stack pointer (the next value will be stored to address -16(%ebp)). This means that the picture from page 312 also shows a down-growing stack.

-- Edit --

If a processor has a "PUSH" instruction the direction of stack growth is given by the CPU. For CPUs that do not have a "PUSH" instruction (like PowerPC or ARM without ARM-THUMB code) the Operating System has to define the direction of stack growth.

Martin Rosenau
  • 17,897
  • 3
  • 19
  • 38
1

Stack growth direction varies with OS, CPU architecture, and probably a number of other things.

The most common layout has the stack start at the top of memory and grow down, while the heap starts at the bottom and grows up. Sometimes it's the other way around, eg. MacOS prior to OSX put the stack just above the code area, growing up, while the heap started at the top of memory and grew down.

Mark
  • 2,792
  • 2
  • 18
  • 31
0

Even more compelling definition of stack growth direction is (if the processor has it) interrupt stack. Some architectures (like PowerPC) don't really have a HW stack at all. Then the system designer can decide which way to implement the stack: Pre-incrementing, post-incrementing. pre-decrementing or post-decrementing.

In PPC the calls use link register, and next call overwrites it, if the return address is not programmatically saved.

PPC interrupts use 2 special registers - the "return address" and machine status. That's because instructions can be "restarted" after interrupt - a way to handle interrupts in pipelined architecture.

pre-increment: stack pointer is incremented before store in push - stack pointer points to the last used item. Seen in few more strange 8-bit architectures (some forth-processors and the like).

post-incrementing: store is done before stack pointer incrementing - stack pointer points to the first free stack element.

pre- and post decrementins: similar to the above, but stack grows downwards (more common).

Most common is post-decrementing.

turboscrew
  • 676
  • 4
  • 13