0

I thought the stack in x86_64 would grow down hence from the max. address of the processes virtuell memory till the end of the stack size (https://www.google.com/url?sa=i&url=https%3A%2F%2Fen.wikibooks.org%2Fwiki%2FX86_Disassembly%2FThe_Stack&psig=AOvVaw3PNsHC2wRGe3XfCCsCi9Kd&ust=1631093147793000&source=images&cd=vfe&ved=0CAkQjRxqFwoTCNiH6c_F7PICFQAAAAAdAAAAABBY).

However in the following C programm the the first char of b, which I thought should be pushed on the stack after a and thereby should have a lower address, can be accessed by adding a positive offset instead of a negative one. Why is that?

I also don't understand why the addresses of the pointers to the stings a and b as well as the long long int c are stored ad much higher addresses. Whats in between the 0x7ff... and the 0x55f... addresses? A gap in the Stack?

#include <stdio.h>

int main() {
    char *a = "abcdefg";
    char *b = "mnopqrs";
    printf("address a: %p\n", a);
    printf("address &a: %p\n", &a);
    printf("address b: %p\n", b);
    printf("address &b: %p\n", &b);
    
    printf("Char at addr %p: %c\n", a+8, *(a+8));

    long long c = 0;
    printf("address c: %p\n", &c);
    return 0;
}

Output:

address a: 0x55fa2e1c8004
address &a: 0x7ffc148d29b0
address b: 0x55fa2e1c800c
address &b: 0x7ffc148d29b8
Char at addr 0x55fa2e1c800c: m
address c: 0x7ffc148d29c0
Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
Simon Rechermann
  • 467
  • 3
  • 18
  • 2
    The compiler is free to arrange the stack as it likes. Your assumption that the order in the stack must always be the same as shown in the C code is not correct. – kaylum Sep 07 '21 at 10:16
  • 2
    String literals aren't stored on the stack. They are usually stored in a read only section of the program. The 0x7f... addresses are in the stack. The 0x55... addresses are in sections of the program not on the stack. The order of variables in your source code are not necessarily the order generated by the compiler. – Michael Petch Sep 07 '21 at 10:17
  • 2
    `a` and `b` are pointers that are stored on the stack. The strings they actually point at are stored in section of memory that is usually read only (section `.rodata` as an example). Observe what happens when you change things to be `char a[] = "abcdefg";` `char b[] = "mnopqrs"; ` . This behaviour is noted in the C documentation https://en.cppreference.com/w/c/language/string_literal – Michael Petch Sep 07 '21 at 10:24
  • thank you. So that the addesses &a, &b and c are stored in the opposite direction than I thought doesn't mean the stack is growing from low to high addresses but only that the compiler has reversed the execution order? – Simon Rechermann Sep 07 '21 at 10:28
  • No, the compiler reversed the *allocation* order. It might still execute their initializers in source order, especially in a debug build. Look at the compiler's asm output on https://godbolt.org/. ([How to remove "noise" from GCC/clang assembly output?](https://stackoverflow.com/q/38552116)) – Peter Cordes Sep 07 '21 at 10:39

0 Answers0