1

Here is a simple C program:

#include <stdio.h>
int main(int argc, char* argv[] ){
    int x = 10;
    int* ptr = &x;
    ptr++;
    printf("%x   %d \n",  ptr,  *ptr);
}

Using a GNU debugger on Ubuntu 64-bit, I debugged the program step by step from the beginning of main function and this is the result of the debugger:

Temporary breakpoint 1, main (argc=1, argv=0x7fffffffe0f8) at sigseg4.c:28
28  int main(int argc, char* argv[] ){
(gdb) display /a $sp
1: /a $sp = 0x7fffffffdfe0
(gdb) display /a $bp
2: /a $bp = 0xffffffffffffe010
(gdb) display /a &x
3: /a &x = 0x7fffffffdffc
(gdb) display /d x
4: /d x = 21845
(gdb) display /a &ptr
5: /a &ptr = 0x7fffffffe000
(gdb) display /a ptr
6: /a ptr = 0x7fffffffe0f0
(gdb) display /d *ptr
7: /d *ptr = 1
(gdb) next
29      int x = 10;
1: /a $sp = 0x7fffffffdfe0
2: /a $bp = 0xffffffffffffe010
3: /a &x = 0x7fffffffdffc
4: /d x = 21845
5: /a &ptr = 0x7fffffffe000
6: /a ptr = 0x7fffffffe0f0
7: /d *ptr = 1
(gdb) next
30      int* ptr = &x;
1: /a $sp = 0x7fffffffdfe0
2: /a $bp = 0xffffffffffffe010
3: /a &x = 0x7fffffffdffc
4: /d x = 10
5: /a &ptr = 0x7fffffffe000
6: /a ptr = 0x7fffffffe0f0
7: /d *ptr = 1
(gdb) next
31      ptr++;
1: /a $sp = 0x7fffffffdfe0
2: /a $bp = 0xffffffffffffe010
3: /a &x = 0x7fffffffdffc
4: /d x = 10
5: /a &ptr = 0x7fffffffe000
6: /a ptr = 0x7fffffffdffc
7: /d *ptr = 10
(gdb) 
32      printf("%x   %d \n",  ptr,  *ptr);
1: /a $sp = 0x7fffffffdfe0
2: /a $bp = 0xffffffffffffe010
3: /a &x = 0x7fffffffdffc
4: /d x = 10
5: /a &ptr = 0x7fffffffe000
6: /a ptr = 0x7fffffffe000
7: /d *ptr = -8192
(gdb) next
ffffe000   -8192 
33  }
1: /a $sp = 0x7fffffffdfe0
2: /a $bp = 0xffffffffffffe010
3: /a &x = 0x7fffffffdffc
4: /d x = 10
5: /a &ptr = 0x7fffffffe000
6: /a ptr = 0x7fffffffe000
7: /d *ptr = -8192
(gdb) next
__libc_start_main (main=0x5555555546aa <main>, argc=1, argv=0x7fffffffe0f8, 
    init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, 
    stack_end=0x7fffffffe0e8) at ../csu/libc-start.c:344
344 ../csu/libc-start.c: No such file or directory.
1: /a $sp = 0x7fffffffe020
2: /a $bp = 0x4720
(gdb) next
[Inferior 1 (process 9922) exited normally]
(gdb) 

As we can see, the stack pointer doesn't change during the program when initializing x and ptr. What I found online is that x and ptr are actually stored in the red zone of the stack segment of memory.

However, the part that confuses me is this: First, we declare x and set it to 10. Adress of x is: 0x7fffffffdffc. Then we initialize a pointer ptr to x, resulting in ptr having the same value as address of x. However, what caught my eye is that the address of the pointer itself: 0x7fffffffe0f0 is 4 bytes bigger than the address of x (e0f0-dffc = 4), which is contradictory to what I've learned about stack, that it grows downwards in memory, not upwards.
Does the red zone somehow behave differently than stack?

A6SE
  • 260
  • 1
  • 3
  • 13
  • 1
    The stack grows downward, but `ptr++` still adds, it doesn't subtract. – Barmar Mar 20 '19 at 23:47
  • 1
    Nothing you're doing here grows the stack, so growth direction is not relevant. C compilers generally allocate all the local variables in a function at once, rather than growing it for each variable. – Barmar Mar 20 '19 at 23:50
  • I don't think the red zone is relevant at all. That's used for temporaries during calculations, not declared variables. – Barmar Mar 20 '19 at 23:51
  • 1
    There are no guarantees that the order variables are declared are the order they are placed on the stack. – AShelly Mar 20 '19 at 23:56
  • Oh, I see. One more question: Why doesn't the stack pointer have the same value as the address of x then? There's 28 bytes difference between those addresses and I'm not sure what occupied those bytes. – A6SE Mar 20 '19 at 23:57
  • There's other stuff in the stack. – Barmar Mar 20 '19 at 23:58
  • 1
    Like the return address of the function. – Barmar Mar 20 '19 at 23:59

0 Answers0