How can gcc/clang assume a string constant's address is 32-bit?

Viewed 681

If I compile this program:

#include <stdio.h>

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

for x86-64, the asm output uses movl $.LC0, %edi / call puts. (See full asm output / compile options on godbolt.)

My question is: How can GCC know that the the string's address can fit in a 32bit immediate operand? Why doesn't it need to use movabs $.LC0, %rdi (i.e. a mov r64, imm64, not a zero or sign-extended imm32).

AFAIK, there's nothing saying the loader has to decide to load the data section at any particular address. If the string is stored at some address above 1ULL << 32 then the higher bits will be ignored by the movl. I get similar behavior with clang, so I don't think this is unique to GCC.


The reason I care is I want to create my own data segment that lives in memory at any arbitrary address I choose (above 2^32 potentially).

2 Answers
Related