2

I am slightly confused on how a compiler stores variable on the stack. I read that c++ can store local variables on the stack, but if the stack is LIFO, how could it make sure to call the right variable when the variable is called in the program?

user207421
  • 305,947
  • 44
  • 307
  • 483
Franklin V
  • 230
  • 1
  • 6
  • @snieguu So why not say LIFO like everybody else? and avoid the question? – user207421 Feb 11 '20 at 05:53
  • 1
    The compiler knows where in the stack frame each variable is, so all it needs is a pointer to the current stack frame, and it can access each variable via its offset from there. – user207421 Feb 11 '20 at 05:54
  • Have you read through the various answers to this question? See [What are the stack and heap?](https://stackoverflow.com/questions/79923/what-and-where-are-the-stack-and-heap) – alter_igel Feb 11 '20 at 06:08
  • Operating systems manages storing variables both stack and heap. Compiler only produces output and define where to store the variables. – Nazim Feb 11 '20 at 06:13
  • 1
    This part "Note that these locations are referred to as offsets from %ebp." in this answer https://stackoverflow.com/a/20227860/7733418 should go to the point of answering your question, since you ask about how variabls on the stack are accessed (and not about what a stack is, which you seem to already know). So I am proposing this as a duplicate. – Yunnosch Feb 11 '20 at 06:41
  • 1
    Does this answer your question? [How we access stack variables without poping them?](https://stackoverflow.com/questions/20222058/how-we-access-stack-variables-without-poping-them) – Yunnosch Feb 11 '20 at 06:41
  • 1
    @Nazim "Operating systems manages storing variables both stack and heap." I wouldn't say that. The OS gives you memory for the stack and assigns the stack pointer to point to it at the start of the program, but it doesn't do anything related to storing variables on it. Variables are allocated on the stack by incrementing the stack pointer when a function is called and the code for that is generated by the compiler as is the code for keeping track of the frame pointer, restoring the stack pointer on return etc. - none of that involves the OS. – sepp2k Feb 11 '20 at 09:33
  • 1
    As far as the heap is concerned, the only involvement of the OS is to provide new pages when more memory is needed. Other than that the heap is managed by `malloc` and `free`, which are implemented in `libc` and implement the logic for finding free memory, keeping track of available memory all by themselves (except for, as mentioned, requesting new pages from the OS when they run out). – sepp2k Feb 11 '20 at 09:33
  • @Nazim If you don't understand the question you should ask the OP to clarify it. It's not my problem in any way. – user207421 Feb 11 '20 at 09:49
  • 1
    To clarify further, what is LIFO about the runtime stack is not variables but entire stack frames, every time you call a method. – user207421 Feb 11 '20 at 09:52

1 Answers1

0

The run-time stack isn't simply a LIFO structure; it's a complex structure which supports random access.

Typically how it works on many platforms is that whe na function is entered, a new stack frame is pushed onto the stack (LIFO fashion). Local variables are stored within the frame and are accessed relative to a more or less stable pointer stored in a register.

When other functions are called, they push their own frames, but they restore everything before returning.

Run-time stacks also typically support the ad hoc pushing and popping of individual values, for the purpose of temporarily saving register values or for parameter passing.

A common implementation strategy for that is to allocate the frame first. For instance if a 512 byte stack frame is needed, the stack pointer is moved by 512 bytes. The stack pointer is then used freely for pushing and popping, provided it doesn't pop too far and start gobbling into the frame.

A separate frame pointer may be used which tracks the location of the frame. The frame is then accessed relative to that frame pointer, which allows the stack pointer to move without interfering with those accesses.

Compilers can generate code without the use of frame pointers also; if the stack pointer only moves in ways that a compiler knows about, it can adjust all the variable references. Over an area of the code where the compiler knows that the stack pointer has moved by four bytes due to something being pushed on it, it can adjust the stack-pointer-relative frame references by four bytes.

The basic principle is that when a given function is executing, then the stack is in the right state that is expected by that function (unless something has gone horribly wrong due to a bug causing corruption or something). The LIFO allocation strategy of the stack frames closely tracks the function calls and returns. Functions that are called must save and restore certain registers (the "callee-saved registers"), which helps to maintain the stable stack environment.

Kaz
  • 55,781
  • 9
  • 100
  • 149