So I saw some code
.LC0:
.string "Hello world"
main:
sub rsp, 8
mov edi, OFFSET FLAT:.LC0
call puts
xor eax, eax
add rsp, 8
ret
From what I've gathered, OFFSET FLAT is used when the memory model is flat. OFFSET would have translated to a segment selector (DS) and OFFSET, whereas OFFSET FLAT translates to an absolute address of the label LC0 relative to 0 (seeing as that's the base of the DS segment in flat mode), which the linker resolves after it is assembled.
But why edi
and not rdi
? Why wouldn't the instruction be mov rdi, moffs64
? The label will have a 64 bit address. I thought maybe it's because the ELF base will be at 4MiB on linux? (although I don't know much about Linux kernel, only Windows, where it''s at 0x140000000). So maybe this is a size optimisation of the instruction, but doesn't this preclude the data section from being larger than 4GB? (not that it ever would be). Is it just safely assumed that it won't be?