3

for the program, local variables are defined and allocated in stack, but, I just wonder the order in defining the local variables is not the same with the order using it. For example, in the main function, int a b c is defined, as described, a b c is allocated in stack, which means if variable a is located in the bottom of stack, but when variable is used first, how pop a out from the stack? Or ebp point to the location where all variables has been stored?

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
lyndon
  • 43
  • 1
  • 4
  • 2
    Local variables stored *on the stack* aren't "popped" from the stack until the method returns. The stack is memory like everything else and what is pushed on the stack is a reserved area of a specific size, the variables just live inside this space but they are just memory accesses as any other, the whole memory area is removed when the method returns. – Lasse V. Karlsen May 25 '18 at 08:38
  • 5
    Think of the stack as a stack of papers. When a method is called a new sheet of paper is placed on top of the stack and on this paper all the local variables of the method is written down. When the method returns we remove the whole sheet. As long as the method is still on the call stack, the paper is still there. It doesn't matter if variables are no longer actually going to be used in this method. Though this could be an optimization, to reduce stack size as the method executes, I'm not sure I've ever heard of a compiler/runtime that does this. – Lasse V. Karlsen May 25 '18 at 08:40
  • 1
    Bear in mind that this whole thing is usually considered to be so low level that most developers never need to know the actual details of this. So my question is, why do you need to know? Do you have a problem you need to solve or are you just out digging for things to learn? – Lasse V. Karlsen May 25 '18 at 08:41
  • @LasseVågsætherKarlsen: The stack of paper analogy is very good analogy. Why don't you convert your comments into an answer? – phoxis May 25 '18 at 08:44
  • @LasseVågsætherKarlsen Your 1st comment is a very good answer indeed - turn it into an answer! – Michael Beer May 25 '18 at 08:54
  • @phoxis has already created an excellent answer, if you feel my comment adds value in addition to his answer, please leave a comment on his answer and he can add the relevant bits. – Lasse V. Karlsen May 25 '18 at 12:07

1 Answers1

8

Essentially within a function, local variables are stored on a stack-frame. Within the stack-frame, the order of access of the variables can be random. I will recommend reading this: http://www.cs.uwm.edu/classes/cs315/Bacon/Lecture/HTML/ch10s07.html

Consider the following code

int main (void)
{
  int a = 1, b = 2, c = 3;

  c = c + 55;
  a = a + 10;

  return 0;
}

A compiler can generate the following code

main:
.LFB0:
        .cfi_startproc
        push    rbp
        .cfi_def_cfa_offset 16
        .cfi_offset 6, -16
        mov     rbp, rsp
        .cfi_def_cfa_register 6
        mov     DWORD PTR [rbp-4], 1
        mov     DWORD PTR [rbp-8], 2
        mov     DWORD PTR [rbp-12], 3
        add     DWORD PTR [rbp-12], 55
        add     DWORD PTR [rbp-4], 10
        mov     eax, 0
        pop     rbp
        .cfi_def_cfa 7, 8
        ret
        .cfi_endproc

Note that the variable a , b and c are stored at location rbp-4, rbp-8 and rbp-12, therefore each variable gets 4 bytes (in my system). It is minus because the stack grows downward and the starting of the stack frame of this function is indicated by the contents of rbp.

Next, note that first c = c + 55 and then a = a + 10 does no push or pop operation, and just access the locations directly, using add DWORD PTR [rbp-12], 55 and add DWORD PTR [rbp-4], 10 respectively. The compiler will know where within a stack-frame these variables are.

Notice the push rbp before the variables are declared and accessed. This operation stored the present value of rbp (the base pointer, 64 bit), on the stack-frame. Next rbp is updated to get a new value indicating limits for this function. Now within this limit, all the local variables can be stored. Also note the pop rbp before the return. This restores the old value of rbp from the stack-frame, which was stored before, so that after ret, it can get back to the old state.

phoxis
  • 60,131
  • 14
  • 81
  • 117