2

I have a question about the order of variable being stored in this small program.

void foo(int a0) {
    printf("%#x, %d\n", &a0, a0);
    int l0 = a0;
    if (a0 > 0) {
        foo(a0-1);
    }
    printf("%d\n", l0);
}

I have that the output being:

0xafe809fc, 3  // why address of 3 is higher than 2, 1, and 0?
0xafe809cc, 2
0xafe8099c, 1
0xafe8096c, 0 // shouldn't 0 get the higher address since 3 seems to be the first input too f00, then 2, then 1, then 0. So shouldn't the address order be the other way around?
0
1
2
3

my question is about why the address of 0 is higher than 1, 2, 3? shouldn't the order be the other way around?

also I think an int is 4 bytes, so why the address-distance is apart by 48 bytes? like for example address at 3 is 0xafe809fc, and address at 2 is 0xafe809cc. So the difference is 48 bytes apart? So it means int takes up 48 bytes in here?

could someone explains?

Oh I forgot to say that I call the function with the parameter a0 =3:

foo(3)

thanks

john_w
  • 693
  • 1
  • 6
  • 25

2 Answers2

1

why the address of 0 is higher than 1, 2, 3? shouldn't the order be the other way around?

It's common for the stack to grow inwards from the last address in your program's available stack space. That is what's happening here.

also I think an int is 4 bytes, so why the address-distance is apart by 48 bytes?

A function call may store additional information on the stack. The amount of information (if any) may also depend on what compiler you use and what level of optimization it applies.

So when you call recursively, each call might push extra state onto the stack. There may also be padding added if your compiler wants to align memory for any reason, or add sentinel values for buffer overflow detection.

paddy
  • 60,864
  • 6
  • 61
  • 103
  • so does it mean actually the allocation to the memory of variable a0 doesn't happen until the compiler actually determines all the pieces of information? For example, if the compiler sees a0 = 3, so it means the inner loop will run when a0 = 3, a0=2, a0=1. So it now calculates that there will be 3 inner loops happening. But at this stage still not yet allocate the memory address when a0=3, or a0=2 or a0=1,.... it will wait until the end. Then after it gathers all pieces of information (like how many time the loop runs). Then it finally assigns address to each variables instance? – john_w Feb 20 '22 at 22:36
  • Firstly, there is no loop. Secondly, no: not unless the compiler has high level of optimization enabled, it won't do any kind of analysis of your recursion, except perhaps to flatten tail-recursion. There is no magic here. You're just making recursive calls and stuff is pushed/popped on the stack. – paddy Feb 20 '22 at 22:40
0

As you know, you take advantage of the stack structure in this recursion case. The direction is which stacks grow is architecture specific. It may be as your expectation as well. However, seemingly, it works against your expectation-direction (: For more, what is the direction of stack growth in most modern systems?

also I think an int is 4 bytes

No, there is no guarantee.

so why the address-distance is apart by 48 bytes? like for example address at 3 is 0xafe809fc, and address at 2 is 0xafe809cc. So the difference is 48 bytes apart? So it means int takes up 48 bytes in here?

How can you be so sure that there is no anything between the address spaces of the integers? There is no guarantee at all that all integers are juxtaposed with their memory spaces in the stack.

As a side note, you should use %p specifier to print pointers like printf("%p, %d\n", (void*)&a0, a0);

  • so does it mean actually the allocation to the memory of variable a0 doesn't happen, until the compiler actually determines all the pieces of information? For example, if the compiler sees a0 = 3, so it means the inner loop will run when a0 = 3, a0=2, a0=1. So it now calculates that there will be 3 inner loops happening. But at this stage still not yet allocate the memory address when a0=3, or a0=2 or a0=1,.... it will wait until the end. Then after it gathers all pieces of information (like how many time the loop runs). Then it finally assigns address to each variables instance? – john_w Feb 20 '22 at 22:35