Search code examples
assemblyx86returnstacknasm

CALL and RET don't work as expected


I still get lost with the stack related operations often and in this case the problem is the RET instruction, which pops a wrong address for the eip register. I use NASM and my code looks like this:

start:
    call GiveMeAHandler
    call GetCommandLine
    ret

GiveMeAHandler:
    push ebp
    mov ebp, esp
    push edi
    push esi
    push dword -11
    call dword [F_GetStdHandle] ; It executes correctly and returns
    mov [StdHandler], eax ; StdHandler is stored in BSS
    add esp, 4
    pop esi
    pop edi
    pop ebp
    ret ; This returns to some weird address

GetCommandLine:
    ; ...
    ; I don't get here because the function above wrong return

Maybe I have exaggerated a little with the ebp, edi, esi pushing and popping (they are not altered after all) but even if I remove them the ret instruction still returns a wrong address (77AE7094) instead of 0040100A, where I call the second function.


Solution

  • By default, Windows uses the stdcall calling convention, where function arguments are pushed onto the stack (right to left), and the callee cleans up the stack. In other words, when GetStdHandle returns, the stack will already be restored to before your push dword -11 instruction. Try removing the add esp, 4 line and see if that fixes it.