-2

Under Visual Studio masm:

    mov ecx,270
l1: pop eax
    loop l1
    push eax

The point of this code is to find out if there is and what is the initial value of ESP. I try to pop immediately after the program starts, and experiment that after how many pop a push will create some memory reading related error. The result of the experiment is somehow unstable, even with exactly same number for ecx. Generally, greater than 512 will always(in my limited times of experiments) create an error, less than 128 is always "safe", and values around 250 to 400 will sometimes create error. It seem that there is no initial value for ESP. If there is, my experiment should create some stable result.

OK I run 127 for other 10 more times and now it start to crash. I am trying to experiment more numbers about this.

Let us just say using Windows-x86, on an average moment of starting a program like my experiment's program. How Windows determine what will be the initial value of esp? Is this difficult to determine(because I could imagine simply put the last address of stack segement in esp)? Is there a common practice of how to do this?

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
Zackham
  • 45
  • 5
  • What do you mean? `esp` always has a value. You can read it with `mov eax, esp` or similar. – Nate Eldredge Nov 23 '21 at 19:30
  • @NateEldredge I am asking if there is a INITIAL value for `esp`. That is, where would `esp` point to when a program first start? – Zackham Nov 23 '21 at 19:36
  • @NateEldredge If I start a program and immediately start to pop, will I pop out something or program crashes? IF something is pop out, what will be these things? – Zackham Nov 23 '21 at 19:38
  • 3
    @Zackham That depends on the state of the processor, operating system, all kinds of things. It has a value and you shouldn’t pop unless you’ve pushed. That’s it. – Sami Kuhmonen Nov 23 '21 at 19:47
  • 2
    @Zackham …no, it explains exactly how things are. You haven’t said which OS, which moment, which situation. It’s like asking “what’s the price of ice cream?” Either you’ll have to actually provide information, or that’s the only answer anyone can give you. – Sami Kuhmonen Nov 23 '21 at 20:01
  • @SamiKuhmonen Let's see if my added information is enough to get a more specific answer? – Zackham Nov 23 '21 at 20:11
  • Still depends on linker, which memory model is used etc. Default stack is usually 1MB so the value is “1048576 less than the maximum value it can have.” – Sami Kuhmonen Nov 23 '21 at 20:21
  • @SamiKuhmonen So overall, there INDEED is someone/something that has to decide and initialize `ESP` for each program, so programmer cannot edit `ESP` in dangerous way(like poping at the beginning of program). And according to my experiment, this value should be very close to the bottom of stack(less that 512*4= 2KB). What is contained in the stack at the beginning may change at different time when program is loaded/linked, and these are some information that OS need. Programmer should consider the initial value that OS allocated as the beginning(bottom) of stack. Shall we conclude like this? – Zackham Nov 23 '21 at 20:35
  • @SamiKuhmonen: On Linux for example, at process startup ESP points at `argc`, then above that is the `argv` array, then `envp`. It's fully valid to use `pop eax` to loop through those arrays and read + discard one pointer at a time, if that's what you want to be doing. It's not something a C program would ever do, of course. And if you just want to see what's above `main`'s incoming ESP up to the top of the stack mapping, a debugger memory dump would be easier. – Peter Cordes Nov 23 '21 at 23:20
  • @PeterCordes That's a useful information, thank you! – Zackham Nov 24 '21 at 18:59

1 Answers1

0

The initial value is wherever the OS put the stack in the process's virtual address space. In modern operating systems it's random.

What is above the top of the stack at _start is architecture-dependent. On Windows, you get an actual return address to something that will exit the current thread. On Linux, you get the command line and the environment variables. In any case, popping stuff from the stack that you didn't push is not going to be ABI compliant and will get you into trouble. The only rules that remain at that point are the security rules.

Joshua
  • 40,822
  • 8
  • 72
  • 132
  • 1
    So overall, there INDEED is someone/something that has to decide and initialize ESP for each program, so programmer cannot edit ESP in dangerous way(like poping at the beginning of program). And according to my experiment, this value should be very close to the bottom of stack(less that 512*4= 2KB). What is contained in the stack at the beginning may change at different time when program is loaded/linked, and these are some information that OS need. Programmer should consider the initial value that OS allocated as the beginning(bottom) of stack. Shall we conclude like this – Zackham Nov 23 '21 at 20:50