For example if I pushed ax is [SP] points to my value of ax or the word after ax? Also is it differs from real mode to protected mode? I ask this because the Art of assembly book illustrates and explains as the sp points to last pushed data, and on this page OSDev Wiki - Stack it illustrated as it points to empty word after last pushed data.

- 328,167
- 45
- 605
- 847

- 338
- 1
- 4
- 11
-
2Intel reference manuals include pseudocode for each instruction. To answer your question, it points to the topmost value on the stack. – DCoder Dec 27 '12 at 19:59
-
For 8086 SP pointed to the next free stack position, and for later x86 CPUs (starting with 80186 I think) it was changed so that SP points to the last used stack position. Because of this change there technically isn't one behavior that is correct for "all x86" (but in practice it's reasonable assume all x86 CPUs that you care about are new enough to have the same/new behavior). – Brendan Apr 02 '22 at 10:26
4 Answers
Wikipedia says here:
The stack is implemented with an implicitly decrementing (push) and incrementing (pop) stack pointer. In 16-bit mode, this implicit stack pointer is addressed as SS:[SP], in 32-bit mode it is SS:[ESP], and in 64-bit mode it is [RSP]. The stack pointer actually points to the last value that was stored, under the assumption that its size will match the operating mode of the processor (i.e., 16, 32, or 64 bits) to match the default width of the push/pop/call/ret instructions.
This is the way my way-back memory says it works, too.

- 12,829
- 2
- 36
- 42
-
Ok thank you but do you have any idea why osdev wiki illustrates esp at after the end of the stack. Is that a mistake? – user1180619 Dec 27 '12 at 20:59
-
You can try it. Push something weird on the stack and then see if [esp] is the same value. Try it with several values to make sure it isn't an accident. – Lee Meador Dec 27 '12 at 21:59
-
@user1180619: Stacks work upside down. They start at the high address, and work down from there. Don't know why, but that's how it is. – Linuxios Dec 27 '12 at 23:55
-
1I went and looked at osdev wiki and you are right. It does show SP and ESP pointing at the empty spot after the top of the stack. (Well ... since the stack grows into lower memory addresses, it points 'before' the top stack entry.) I don't know why it does that. Perhaps they stole the diagrams from some other type of processor and failed to fix them up. If you notice all the descriptions and the code examples still work since they never show a move out of [ESP]. – Lee Meador Dec 28 '12 at 16:13
-
I am concerned that the examples on osdev showing how to reference parameters and stack variables are wrong for simple function calling. (Remember that some languages will pass arguments in registers depending on compile options. If they do that, the arguments take no stack space and the code runs faster. But there are only so many registers.) – Lee Meador Dec 28 '12 at 16:13
push eax
Is equivalent to:
sub esp, 4
mov [esp], eax
So after a push, esp
will hold the address of the pushed value.

- 29,236
- 5
- 72
- 110
As per Lee Meador's and Cory Nelson's answers, the stack pointer points on the last value that was pushed.
From the Intel® 64 and IA-32 Architectures Software Developer’s Manual Volume 2 (2A, 2B & 2C): Instruction Set Reference, A-Z, the first line from the description of the PUSH instruction reads as follow:
Decrements the stack pointer and then stores the source operand on the top of the stack.

- 1,031
- 1
- 9
- 22
I think I understand why OP is asking this question. Why is the first variable 8 bytes from SP and not 4?
After some research I found this which indicates that:
SP+0 is the old EBP SP+4 is the old EIP (instruction pointer)
Hence, naturally, the first parameter is at SP+8.

- 1,389
- 1
- 11
- 31