If I compile this program:
#include <stdio.h>
int main(int argc, char** argv) {
printf("hello world!
");
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).
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…