tags:

views:

71

answers:

3

Hello, I'm little bit confused with one thing about memory stack.

From what I know a stack is created for process/thread in higher address memory and continues to lower addresses. Now the problem part. When you Push something on stack it first decreases address and then stores something on stack. Isn't there some memory lost because Push instruction first decreases Stack Pointer's address? I would think that it be more logical to first store and then decrease Sp, where am I wrong?

Thank you for help

+1  A: 

Typically, the stack pointer is pointing at the boundary between unused stack space and the item at the top of the stack. On an architecture where the stack grows upwards (addresses grow downward), this would make it appear like the stack pointer is pointing directly at the top item. Since it can be viewed as pointing the to top item, it would have to change the pointer first, then store. Likewise during a pop, the item is loaded first, then the pointer is changed.

It would be clearer with an illustration:

//initially
|    |    [CCCC|BBBB|AAAA]
          ^
         esp

//push
|    [    |CCCC|BBBB|AAAA] //decrement
     ^

|    [DDDD|CCCC|BBBB|AAAA] //store
     ^

//pop
|    [DDDD|CCCC|BBBB|AAAA] //load
     ^

|    |DDDD[CCCC|BBBB|AAAA] //increment
          ^
Jeff M
+3  A: 

There are different conventions on whether to decrement first and then store or store first and then decrement. In any case, it doesn't matter at all, the stack pointer just gets initialized with the proper value (i.e: it points either to the address above where the first element will get stored, or to the address where the first element will get stored).

ninjalj
+1  A: 

More detail than you probably wanted to know.

Stacks can be both "descending" (growing down) or "ascending" (growing up). Stacks can also be either "full" (SP points to a "full" i.e. used entry in the stack) or "empty" (SP points to an "empty" i.e. unused entry in the stack.)

Most stacks are "full descending". I think a few are "empty ascending". The other two (FA,ED) don't see much use, if only because it's unclear which byte they should point at if you can push/pop values of different sizes.

EDIT: The naming above may be a bit ARM-specific, if only largely because most platforms don't let you pick a direction.

The canonical mnemonics for the relevant ARM instructions are actually LDMIA (load multiple increment after) and STMDB (store multiple decrement before) for a "full descending" stack, but ARM decided to add LDMFD/STMFD aliases so programmers only need to remember the type of stack in use. The increment/decrement before/after are the canonical names because the ARM architecture is (mostly) orthogonal; the use of a stack is by convention (i.e. EABI) instead of something perscribed by the architecture itself. The exceptions are r14 (LR), r15 (PC), and the set of registers which get shadowed between the different supervisor modes.

The "increment after" naming may be more sensible if you're using ldm/stm to implement something like memcpy().

(I'm ignoring Thumb, which has explicit push/pop instructions).

tc.
+1 for mentioning ARM naming conventions for STMxx, LDMxx instructions.
ninjalj
I left the ARM-specificness out to keep the answer short ;) Editing...
tc.