Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

LEA is extremely useful on x86-64 for a different reason: it lets you determine your program counter.

For example, imagine you have code like this:

  static int foo;
  int *func(void) { return &foo; }
If you build it as position-independent code, on x86-64, you get:

  leaq	foo(%rip), %rax
  ret
Here, "foo" turns into the offset from the end of the LEA instruction to the variable foo. The x86 address calculation engine does the rest.

On x86-32, there's no IP-relative addressing, so you can't use LEA like this, and you get a mess, which I've trimmed into readability:

  ; x86-32 has no instruction that reads EIP.  Fake it.
  __x86.get_pc_thunk.ax:
  	movl	(%esp), %eax
  	ret
  
  func:
        call    __x86.get_pc_thunk.ax ; <-- this sucks
        addl    $_GLOBAL_OFFSET_TABLE_, %eax
        leal    foo@GOTOFF(%eax), %eax  <-- ???
        ret
I don't know why this is as indirect as it is on x86-32, but this really is what gcc generates. The ??? is a GOT reference.

Edit: fixed formatting



> I don't know why this is as indirect as it is on x86-32, but this really is what gcc generates.

Possibly because the ELF relocs require that exact instruction sequence.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: