Onde as constantes de string são armazenadas pelo GCC e de onde esses ponteiros são mapeados?

Quando eu compilar e executar o seguinte programa C na minha máquina Linux x86_64, compilado pelo GCC:

#include <stdio.h>

int main(void)
{
    char *p1 = "hello";               // Pointers to strings
    char *p2 = "hello";               // Pointers to strings
    if (p1 == p2) {                   // They are equal
    printf("equal %p %p\n", p1, p2);  // equal 0x40064c 0x40064c
                                      // This is always the output on my machine
    }
    else {
    printf("NotEqual %p %p\n", p1, p2);
    }
}

Eu sempre recebo a saída como:

0x40064c 0x40064c igual

Eu entendo que as strings são armazenadas em uma tabela constante, mas o endereço é muito baixo quando comparado à memória alocada dinamicamente.

Compare com o seguinte programa:

#include <stdio.h>

int main(void)
{
    char p1[] = "hello";                // char arrar
    char p2[] = "hello";                // char array
    if (p1 == p2) {
    printf("equal %p %p\n", p1, p2);
    }
    else {                              // Never equal
    printf("NotEqual %p %p\n", p1, p2); // NotEqual 0x7fff4b25f720 0x7fff4b25f710
                                        // Different pointers every time
                                        // Pointer values too large
    }
}

Os dois ponteiros não são iguais, porque esses são dois arrays que podem ser manipulados independentemente.

Eu quero saber como o GCC gera o código para esses dois programas e como eles são mapeados para a memória durante a execução. Como isso já estaria documentado, muitas vezes qualquer link para documentação também é bem-vindo.

questionAnswers(1)

yourAnswerToTheQuestion