0

Initially, ESP refers to the empty space of memory.

When I push something such as push 1, then it will refers to the memory location of 1, or next empty space?

here is the example

push    ebp
mov ebp, esp
/*
---------
(empty space)    <- esp, ebp
---------
ebp     (initially stack pointer was here)
---------
*/

Another question is that when I make an empty stack space, which point ESP will points?

Here is the example: (each memory location is 4 bytes)

/*
  --------
1        <- initial esp
  --------
*/
sub esp, 12
; now esp points to this one 
/*
  --------
4          <- esp
  --------
3
  --------
2  
  --------
1        
  --------
*/
; or this one
/*
  --------
3           <- esp
  --------
2  
  --------
1        
  --------
*/

Assume that numbers are the memory location addresses

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
monstereo
  • 830
  • 11
  • 31

1 Answers1

4

The Operation section in the manual (https://www.felixcloutier.com/x86/push) shows that push modifies ESP before storing to [ESP].

            ESP ← ESP – 4;
            Memory[SS:ESP] ← SRC;
                (* push dword *)

pop does the reverse: load from [ESP] and then modify ESP.

Like many other ISAs (e.g. ARM), x86 uses a "full" stack where the stack pointer normally points to the last thing pushed, not to empty space below it.


Fun fact: pop esp overwrites ESP after incrementing, so it's like mov esp, [esp].
push esp reads the value to be stored before decrementing ESP. Intel's manual entries document this, but their pseudocode doesn't match. See What is an assembly-level representation of pushl/popl %esp? for proper push/pop pseudocode that works for all cases, even push esp and pop esp.


re: part2: add esp, 12 moves ESP by 12 bytes, or 12B/4B = 3 "stack slots". 1+3 = 4.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847