tags:

views:

72

answers:

5

Hi, very quick question for you. When I store some automatic variable in C, asm output is like this: MOV ESP+4,#25h , and I just want to know why can´t compiler calculate that ESP+4 adress itself.

I thought this through, and I really cant find reason for this. I mean, isnt compiler aware of the esp value? It should be. And when using another object file, this should not be problem either, since variables could just be represent by adress and linked later, when all automatic variables are known, and therefore proper adress could be assigned. Thanks.

+3  A: 

No, the compiler is not aware of the value of ESP at runtime - it's the stack pointer. It is potentially different every time the function is called. Perhaps the simplest example to think about is a recursive function - every time it calls itself, the stack gets a little bit deeper to accommodate the local variables for the new call. Every stack frame has its own local variable, every stack frame is at a different position on the stack, and therefore has its own address (in ESP, normally).

Carl Norum
+1  A: 

This is really rather fundamental to the way the stack works. To reason it out for yourself, imagine how you'd implement a recursive function.

Hans Passant
+3  A: 

No, it cannot know the value of esp in advance.

Take for example a recursive function, ie. a function that calls itself. Assume such a function has several parameters that are passed in via the stack. This means that each argument takes some space on the stack, thereby changing the value of the esp register.

Now, when the function is entered, the exact value of esp will depend on how many times the function has called itself previously, and there is no way the compiler could know this at compile time. If you doubt this, take a function such as this:

void foobar(int n)
{
    if (rand() % n != 17)
        foobar(n + 1);
}

There's no way the compiler would be smart enough in advance to figure out if the function will call itself once more.

If the compiler wanted to determine esp in advance, it would effectively have to create a version of the function for each possible value for esp.

The above explanation only takes into account one function. In a real-world scenario, a program has many functions which interdepend on one another, which results in fairly complex "call graphs". This together with (among other things) unpredicable program logic means the compiler would have to create a huge array of versions of each function, just to optimise on esp -- which clearly doesn't make sense.


P.S.: Now something else. You don't actually need to optimise [esp+N] at all, because it should not take any more CPU time than the simpler [esp]... at least not on Intel Pentium CPUs. You could say that they already contain optimizations for exactly this and even more complicated scenarios. If you're interested in the Intel CPUs, I suggest you look up the documentation for something called the MOD R/M and the SIB byte of a machine instruction, e.g. here for the SIB byte or here or, of course, in Intel's official CPU developer documentation.

stakx
Just one more question, if you used no recursive function call in whole program, could it be done without using indirect adressing?
B.Gen.Jack.O.Neill
_@b-gen-jack-o-neill:_ It would make things easier. Let's say it is clear that one function `caller` calls your target function `f`. Then, `esp` might be computed based on the assumed `esp` value for `caller`, plus perhaps space required by local variables of `caller` and arguments of `f`. (It may in fact not be that simple.) The recursive function above could essentially be transformed into *n* + 1 almost identical functions (one per iteration, where *n* is the number of times the function calls itself; identical except for the value assumed for `esp`).
stakx
_@b-gen-jack-o-neill:_ Please also read the added P.S. to my answer. It addresses the quite important question whether you need to "optimise" `[esp+N]` at all.
stakx
+2  A: 

The Stack Pointer cannot be calculated at compile time. For a simple example why this is not possible, just think of a recursive function: The same variable has a different address for each call, but it's always the same code that is run.

FRotthowe
+2  A: 

No, the compiler doesn't know the value ahead of time. In a few extremely basic programs (where there's only one possible "route" from main to any other particular function being called) it could, but I don't know of a compiler that attempts to compute this. If you have any recursion, or a function is called from more than one place, the the stack pointer will have different values depending on where it was called from.

There's not much point to doing so in any case -- since the stack pointer is so heavily used, most CPUs are designed to make indirect addressing from the stack pointer extremely efficient. In fact, it's often more efficient than supplying an absolute address would be.

Jerry Coffin