Thread: How does __stdcall work?

  1. #1
    Registered User
    Join Date
    Jan 2009
    Posts
    31

    Question How does __stdcall work?

    I am curious how the __stdcall keyword works to link a win32 application to the windows operating system. What is literally happening inside the computer when this instruction is executed? I read somewhere that __stdcall puts the WndProc() function into another function, how does that work?

    Thank you for any input on my question.

  2. #2
    int x = *((int *) NULL); Cactus_Hugger's Avatar
    Join Date
    Jul 2003
    Location
    Banks of the River Styx
    Posts
    902
    __stdcall is not an instruction, per se. __stdcall is a calling convention on x86-architectures.

    A calling convention specifies where the arguments to a function are located in memory, how return values are communicated, and who is responsible for cleaning up the arguments. Wikipedia has an article about x86 calling conventions.
    long time; /* know C? */
    Unprecedented performance: Nothing ever ran this slow before.
    Any sufficiently advanced bug is indistinguishable from a feature.
    Real Programmers confuse Halloween and Christmas, because dec 25 == oct 31.
    The best way to accelerate an IBM is at 9.8 m/s/s.
    recursion (re - cur' - zhun) n. 1. (see recursion)

  3. #3
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    __stdcall is not an instruction, it is a type modifier which tells the compiler to use the "standard" calling convention for invokations of the function it applies to.

    When a function is called, the parameters are pushed onto the stack. These parameters must be cleaned up after the function call returns. This could be done by the calling code (caller) or the function which is called (callee).

    For __stdcall, the callee cleans the stack. For __cdecl, the caller cleans it. There are other calling conventions as well.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  4. #4
    Registered User
    Join Date
    Jan 2009
    Posts
    31
    Quote Originally Posted by Cactus_Hugger View Post
    __stdcall is not an instruction, per se. __stdcall is a calling convention on x86-architectures.

    A calling convention specifies where the arguments to a function are located in memory, how return values are communicated, and who is responsible for cleaning up the arguments. Wikipedia has an article about x86 calling conventions.
    Hmmm, how does the calling convention know what arguments should be passed to the function? Where does it go to retrieve the arguments? Also, does that mean any function using __stdcall should always have 4 parameters?
    Last edited by RaisinToe; 04-30-2009 at 09:47 PM.

  5. #5
    Registered User valaris's Avatar
    Join Date
    Jun 2008
    Location
    RING 0
    Posts
    507
    It "knows" what arguments will be passed to the function by the function prototype. With the __stdcall convention the compiler knows that arguments will be passed (pushed) right to left, and when the function pops the return address off the stack, it will also add so much space to the stack pointer to clear the arguments passed by the callee (the local paramaters). No you don't have to have 4 paramaters with a __stdcall. Depending on what paramaters you use in your function the compiler will emit the proper instructions to access the proper offfset into the stack where the argumets should be according to the convention.

  6. #6
    int x = *((int *) NULL); Cactus_Hugger's Avatar
    Join Date
    Jul 2003
    Location
    Banks of the River Styx
    Posts
    902
    To... elaborate.

    A calling convention is just that - a convention. It's a way that it's done. There are multiple ways that one could potentially pass arguments to a function at the machine code level, but this particular way is called "stdcall". (Another particular way is called "cdecl", etc.)

    The compiler knows about stdcall & cdecl - the programmers who wrote the compiler wrote the code for these calling conventions. When your C function, marked as stdcall is called, the compiler will generate the assembly instructions that correspond to a function call, doing the function call as "stdcall" says a function call should be done.
    long time; /* know C? */
    Unprecedented performance: Nothing ever ran this slow before.
    Any sufficiently advanced bug is indistinguishable from a feature.
    Real Programmers confuse Halloween and Christmas, because dec 25 == oct 31.
    The best way to accelerate an IBM is at 9.8 m/s/s.
    recursion (re - cur' - zhun) n. 1. (see recursion)

  7. #7
    Registered User
    Join Date
    Jan 2009
    Posts
    31

    Question

    Quote Originally Posted by valaris View Post
    It "knows" what arguments will be passed to the function by the function prototype. With the __stdcall convention the compiler knows that arguments will be passed (pushed) right to left,
    The windows operating system calls the __stdcall WndProc() function, right? So how does the program know when to retreive the argument passed by windows? Or am I still not understanding it?

  8. #8
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Calling conventions work in symmetry: The compiler of the caller code MUST know how to call the callee code, and the callee code must know what to do with it.

    Imagine it like a restaurant, where some staff is responsible for putting plates out, and some other staff serving up the food. But in a different restaurant, the same person carries plates out to the dining table as does the serving. Obviously, if you take the staff out of the one restaurant and simply put them in the other restaurant (without any instructions - and the staff are REALLY stupid - just like computers!), you either end up with food directly on the table or doubled up plates. That wouldn't work.

    Just the same for the compiler - BOTH sides have to know what is done where - which order the arguments are, and "who puts the plate on the table" (stack-clean up). If both sides don't use the same principles, then you get a mess (too many plates, or food directly on the table - in computer terms, probably a crash).

    In this case, Windows DEFINES that WindProc MUST be called with __stdcall convention - and the code in Windows that makes this call is compiled with a __stdcall calling convention.

    --
    Mats
    Last edited by matsp; 05-01-2009 at 09:42 AM.
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  9. #9
    Registered User
    Join Date
    Jan 2009
    Posts
    31
    OK, so windows places message information on the stack, and then tells WndProc() what has been placed on the stack so it can retrieve it. I think I understand.

    Thank you for that good analogy.

    But now I have to ask; Inside an API application, How is WndProc() called. There is no call to it inside of the application, so what calls it? If I understand correctly now, __stdcall only gives instructions on how to retrieve and send arguments, it does not force a call.
    Last edited by RaisinToe; 05-01-2009 at 11:50 AM. Reason: Change my wording

  10. #10
    Ex scientia vera
    Join Date
    Sep 2007
    Posts
    477
    Quote Originally Posted by RaisinToe View Post
    OK, so windows places message information on the stack, and then tells WndProc() what has been placed on the stack so it can retrieve it. I think I understand.

    Thank you for that good analogy.

    But now I have to ask; Inside an API application, How is WndProc() called. There is no call to it inside of the application, so what calls it? If I understand correctly now, __stdcall only gives instructions on how to retrieve and send arguments, it does not force a call.
    You still misunderstanding what stdcall is. It isn't solely used for wndproc.

    Stdcall is short for standard call(ing)(At least, that's my guess). It tells the compiler that the function that is to be converted to machine code(Assembly language) is to put the arguments to the function on the stack in a certain way. In the case of stdcall, arguments are pushed onto the stack in reverse order(Right to left, if you look at a C/++ function declaration). The calling convention also dictates how the memory is set up inside the function, and how it is cleaned up, and how the functions returns data. This here is from wikipedia, and it won't make sense unless you understand assembly language:

    Code:
    calc:
    push eBP            ; save old frame pointer
     mov eBP,eSP         ; get new frame pointer
     sub eSP,localsize   ; reserve place for locals
     .
     .                   ; perform calculations, leave result in AX
     .
     mov eSP,eBP         ; free space for locals
     pop eBP             ; restore old frame pointer
     ret paramsize       ; free parameter space and return
    If you can be a bit more specific on what you are asking, then maybe we can help you out.
    "What's up, Doc?"
    "'Up' is a relative concept. It has no intrinsic value."

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. strcmp returning 1...
    By Axel in forum C Programming
    Replies: 12
    Last Post: 09-08-2006, 07:48 PM
  2. getline() don't want to work anymore...
    By mikahell in forum C++ Programming
    Replies: 7
    Last Post: 07-31-2006, 10:50 AM
  3. Why don't the tutorials on this site work on my computer?
    By jsrig88 in forum C++ Programming
    Replies: 3
    Last Post: 05-15-2006, 10:39 PM
  4. fopen();
    By GanglyLamb in forum C Programming
    Replies: 8
    Last Post: 11-03-2002, 12:39 PM
  5. DLL __cdecl doesnt seem to work?
    By Xei in forum C++ Programming
    Replies: 6
    Last Post: 08-21-2002, 04:36 PM

Tags for this Thread