3

The accepted answer of this StackOverflow post gives the following solution:

get_eip: mov eax, [esp]
         ret

But I don't understand why this works. Why is the saved EIP pointed to by ESP? Shouldn't ESP be pointing to SFP (the old EBP value) at the time we execute the mov instruction? The prologue of a subroutine call in x86 assembly looks like:

push ebp      ; Save the old base pointer value
mov ebp, esp  ; Set the new base pointer value
sub esp, ...  ; Make room for local variable

So shouldn't the saved EIP sit one more word above the address where ESP is pointing to?

Community
  • 1
  • 1
Zizheng Tai
  • 6,170
  • 28
  • 79
  • Yes, but this function as you can see has no such prologue. – Jester Feb 16 '17 at 10:56
  • @Jester Is that an exception for functions without local variables or something...? – Zizheng Tai Feb 16 '17 at 10:57
  • That prologue is optional, and not typically used in optimized code. You only need the `sub esp` to allocate locals. – Jester Feb 16 '17 at 10:58
  • @ZizhengTai Nothing forces you to add a subroutine prologue and as you see, the `get_eip` function doesn't have such a prologue. – fuz Feb 16 '17 at 10:59
  • 4
    @fuz Oh, I see. The prologue is for functions written in higher-level languages (e.g., C/C+). We can write assembly functions however we like. – Zizheng Tai Feb 16 '17 at 11:00
  • @ZizhengTai Good compilers for high-level languages too omit the function prologue when it is not needed or explicitly requested. – fuz Feb 16 '17 at 11:03
  • 1
    @ZizhengTai - You can think of it this way: Just before the `ret`, we *better have* `esp` point at the return address. Otherwise we will end up in the wrong place. – Bo Persson Feb 16 '17 at 15:59

0 Answers0