I'm trying to fully understand the stack growth mechanism on function calls and I feel a bit confused. In order to better understand I wrote the following simple program:
#include <stdio.h>
#include <stdint.h>
void callee(uint32_t* p)
{
uint32_t tmp = 9;
printf("callee - tmp is located at address location:%p and p is:%p \n", &tmp, p);
}
void caller()
{
uint32_t tmp1 = 12;
printf("caller - address of tmp1:%p \n", &tmp1);
calle(&tmp1);
}
int main(int argc, char** argv)
{
caller();
return 0;
}
And using a online assembler converter I got the following assembly output (I left only the code of the callee function):
.LC0:
.string "callee - tmp is located at address location:%p and p is:%p \n"
calle:
push rbp
mov rbp, rsp
sub rsp, 32 // command 1
mov QWORD PTR [rbp-24], rdi
mov DWORD PTR [rbp-4], 9 // command 2
mov rdx, QWORD PTR [rbp-24]
lea rax, [rbp-4]
mov rsi, rax
mov edi, OFFSET FLAT:.LC0
mov eax, 0
call printf
nop
leave
ret
As I understand, taking into account commands 1 & 2 (noted above), the stack indeed grows down towards lower addresses, and a (sample) output of the compiled code, when I compile it using the command gcc myProg.c -o prog, is as follows:
caller - address of tmp1:0x7ffe423e8ed4
callee - tmp is located at address location:0x7ffe423e8eb4 and p is:0x7ffe423e8ed4
Where it can be seen, that indeed, the local variable allocated within the callee function is located in a lower memory address than the local variable within the caller function.So far so good.
Yet, when I compile the program with the -O2 option (i.e.: gcc -O2 myProg.c -o prog) , a (sample) output of the compiled code is something as follows:
caller - address of tmp1:0x7fff0d5bfa90
callee - tmp is located at address location:0x7fff0d5bfa94 and p is:0x7fff0d5bfa90
Which, this time, depicts that the local variable allocated within the callee stack frame is located in a higher memory address than the local variable within the caller function.
So my question is - the -O2 optimization option optimizes "up to" a situation where the stack growth mechanism actually changes or am I missing here something... ?
gcc version: 7.3
architecture: x86_64
OS: Ubuntu 18.04.
Appreciate your clarifications.
Guy.