title: gcc: asm syntax 'mov eax, OFFSET FLAT: .LC0'?
body: <p>So I saw some <a href="https://stackoverflow.com/questions/52442415/in-c-am-i-paying-for-what-i-am-not-eating/52445395">code</a></p>
  
  <pre><code>.LC0:
          .string "Hello world"
  main:
          sub     rsp, 8
          mov     edi, OFFSET FLAT:.LC0
          call    puts
          xor     eax, eax
          add     rsp, 8
          ret
  </code></pre>
  
  <p>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. </p>
  
  <p>But why <code>edi</code> and not <code>rdi</code>? Why wouldn't the instruction be <code>mov rdi, moffs64</code>? 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? </p>