Hybrid
Hybrid

Reputation: 321

Confuse about Assembly CALL,RET Statement

I want to know when "CALL" instrucion execute. It first push return address on stack or function arguments?

Thanks

Upvotes: 0

Views: 326

Answers (2)

Yakov Galka
Yakov Galka

Reputation: 72479

CALL does not push arguments at all. It pushes only the return address. You are responsible to push the arguments on your own, which happens before CALL, obviously. For example:

    push 2
    push 1
    push "%d"
    call printf
next_instruction:
    add esp, 12

When entering the printf function, assuming a near call in 32-bit, the stack will look like this:

esp+0:  address of next_instruction
esp+4:  address of "%d"
esp+8:  1
esp+12: 2

Edit: Regarding the order of the arguments, extending on what @Martin has said:

The interpretation of what's there on the stack is a contract between the caller and the callee (named 'calling convention'), and it depends on a lot of things, including language, architecture, compiler, and more. For C on x86 the arguments are pushed from the last to the first. So the above assembly snippet corresponds to the translated C statement:

printf("%d", 1, 2);

If you look at the stack above, you see that since we pushed the arguments in the reverse order, they got ordered from the first to the last relative to esp. This way printf can read the first argument "%d" without knowing how much arguments will follow, and then determine the rest from the format string. Also since in the C calling convention the caller is responsible for removing the arguments from the stack (the next_instruction), passing more arguments than necessary is harmless (although it is undefined behavior according to the standard).

Upvotes: 6

rcgldr
rcgldr

Reputation: 28826

If the function returns an object too large to fit in a register, then space for the returned object is preallocated:

        sub     esp,sizeof object
        push    ecx
        push    eax
        call    example
        add     esp,8     ;restore stack
;                         ;esp is now pointer to object
        add     esp,sizeof object    ;restore stack once object no longer needed

Upvotes: 2

Related Questions