¿Cómo puede gcc / clang asumir que la dirección de una constante de cadena es de 32 bits?

Si compilo este programa:

#include <stdio.h>

int main(int argc, char** argv) {
    printf("hello world!\n");
    return 0;
}

para x86-64, la salida asm usamovl $.LC0, %edi / call puts. (Ver opciones completas de salida / compilación de asm en godbolt.)

Mi pregunta es: ¿cómo puede GCC saber que la dirección de la cadena puede caber en un operando inmediato de 32 bits? ¿Por qué no necesita usarmovabs $.LC0, %rdi (es decir, unmov r64, imm64, no un cero o signo extendidoimm32)

AFAIK, no hay nada que diga que el cargador tiene que decidir cargar la sección de datos en cualquier dirección en particular. Si la cadena se almacena en alguna dirección anterior1ULL << 32 entonces los bits más altos serán ignorados por el movl. Tengo un comportamiento similar con el sonido metálico, así que no creo que sea exclusivo de GCC.

La razón por la que me importa es que quiero crear mi propio segmento de datos que vive en la memoria en cualquier dirección arbitraria que elija (por encima de 2 ^ 32 potencialmente).

Respuestas a la pregunta(2)

Su respuesta a la pregunta