I'm trying to get my head around a function's call stack with some practical examples. In all of the diagrams explaining this, it is laid out like [Local variables][Return Address][Arguments] (low memory on the left). But when I'm in gdb and breakpoint inside a function, I get them in a different order:
(gdb) info args
arg1 = 0
arg2 = 0
arg3 = 32767
(gdb) p &arg1
0x7ffff3a4697ec
(gdb) p &arg2
0x7ffff3a4697e8
(gdb) p &arg3
0x7ffff3a4697e4
(gdb) info locals
local1 = 0
local2 = 0
local3 = 0
(gdb) p &local1
0x7ffff3a4697fc
(gdb) p &local2
0x7ffff3a4697f8
(gdb) p &local3
0x7ffff3a4697f4
(gdb) info frame
Stack level 0, frame at 0x7ffff3a469810:
...
Arglist at 0x7ffff3a469800, args: arg1=0, arg2=0, arg3=32767
Locals at 0x7ffff3a469800, Previous frame's sp is 0x7ffff3a469810
Saved registers:
rbp at 0x7ffff3a469800, rip at 0x7ffff3a469808
Why are the arguments of the function at lower memory addresses than both the local variables and the return pointer? All literature on the subject (e.g. diagrams like this https://upload.wikimedia.org/wikipedia/commons/thumb/d/d3/Call_stack_layout.svg/342px-Call_stack_layout.svg.png) imply that the arguments should be at higher memory address than the return address? And the return address should be between locals & arguments, whereas I have locals & arguments in a contiguous block with the return address at the end. Many thanks - apologies if I have completely misunderstood!
Edit: Example C program to generate this:
#include <stdio.h>
void func1(int arg1, int arg2, int arg3) {
int local1;
int local2;
int local3;
local1 = 2;
local2 = 3;
local3 = 4;
}
int main(){
int a;
int b;
int c;
func1(a, b, c);
}
Compile this code with gcc code.c -o code
on CentOS x86_64. Run with gdb and put a breakpoint in the func1. Look at address of arg variables, local variables, and return address.