How is the stack set up in a Windows function call?

To begin, I'd like to say I have sufficient background in assembly to understand most of what one needs to know to be a functional assembly programmer. Unfortunately I do not understand how a Windows API call works in terms of the return address.

Here's some example code written in GAS assembly for Windows using MinGW's as as the assembler and MinGW's ld as the linker...

    .extern _ExitProcess@4
    .text
    .globl _main
_main:
     pushl $0
     call _ExitProcess@4

This code compiles and runs after assembling...

as program.s -o program.o

And linking it...

ld program.o -o program.exe -lkernel32

From my understanding, Windows API calls take arguments via push instructions, as can be seen above. Then during the call;

call _ExitProcess@4

the return address for the function is placed on the stack. Then, and this is where I'm confused, the function pops all the arguments off the stack.

I am confused because, since the stack is last in first out, in my mind while popping the arguments on the stack it would pop off the return address first. The arguments came first and the return address came next so it would technically be popped off first.

My question is, what does the layout of the stack look like after passing arguments via push operations to the function call and the return address placed on the stack? How are the arguments and the return address popped off the stack by the function as it executes? And finally, how is the return address popped off the stack and the function call rerturns to the address specified in the return addresss?


Almost all Windows API functions use the stdcall calling convention. This works like the normal "cdecl" convention, except as you've seen the called function is responsible for removing the argument when it returns. It does this using the RET instruction, which takes an optional immediate operand. This operand is the number of bytes to pop off the stack after first popping off the return value.

In both the cdecl and stdcall calling convention the arguments to a function aren't popped off the stack while the function is executing. They're left on the stack and accessed using ESP or EBP relative addressing. So when ExitProcess needs to access its argument it uses an instruction like mov 4(%esp), %eax or mov 4(%ebp), %eax .

链接地址: http://www.djcxy.com/p/14108.html

上一篇: 组装调用堆栈

下一篇: 如何在Windows函数调用中设置堆栈?