{"id":42,"date":"2006-08-15T07:00:31","date_gmt":"2006-08-15T12:00:31","guid":{"rendered":"http:\/\/www.nynaeve.net\/?p=42"},"modified":"2019-12-13T17:41:39","modified_gmt":"2019-12-13T22:41:39","slug":"win32-calling-conventions-usage-cases","status":"publish","type":"post","link":"http:\/\/www.nynaeve.net\/?p=42","title":{"rendered":"Win32 calling conventions: Usage cases"},"content":{"rendered":"<p><a title=\"Win32 calling conventions: Concepts\" href=\"http:\/\/www.nynaeve.nlast%20timeet\/?p=39\">Last time<\/a>,\u00c2\u00a0I talked about some of the general concepts behind the varying calling conventions in use on Win32 (x86).\u00c2\u00a0 This posting focuses on the implications and usage cases behind each of the calling conventions, in an effort to provide a better understanding as to when you&#8217;ll see them used.<\/p>\n<p>When looking at the different calling conventions, we can see that there are a number of differences between them.\u00c2\u00a0 Stack usage vs register parameters, caller vs callee cleans stack, member function calls vs &#8220;plain C&#8221; function calls, and soforth.\u00c2\u00a0 These differences lend each calling convention to specific cases where they are best suited.<\/p>\n<p>To begin with, consider the __cdecl calling convention.\u00c2\u00a0 We know that it is a stack based calling convention where the caller cleans the stack.\u00c2\u00a0 Furthermore, we know that it is the default calling convention for CL (big hint as to when you&#8217;ll see this being used!).\u00c2\u00a0 These attributes make it well suited for a couple of cases:<\/p>\n<ul>\n<li><em>Variadic functions<\/em>, or functions with an ellipsis (&#8230;) terminating the argument list.\u00c2\u00a0 These functions have a variable number of arguments, which is not known at compile time of the callee.\u00c2\u00a0 __cdecl is useful for these functions because the compiler needs to implement a stack displacement to clean arguments off of the stack, but it doesn&#8217;t know how many arguments there are.\u00c2\u00a0 By leaving the argument-disposal up to the caller, who does know the number of arguments at compile time, the compiler doesn&#8217;t need\u00c2\u00a0special help from the programmer to correctly adjust the stack\u00c2\u00a0when the\u00c2\u00a0variadic function is\u00c2\u00a0going to return\u00c2\u00a0&#8211; it &#8220;just works&#8221;.\u00c2\u00a0 __cdecl is the only calling convention on Win32 x86 that supports variadic functions when used with CL.<\/li>\n<li>Old-style C functions without prototypes.\u00c2\u00a0 For compatibility with legacy C code, the C compiler needs to support making function calls to unprototyped functions.\u00c2\u00a0 These must be treated as if they were variadic functions, because the compiler doesn&#8217;t know whether the function takes a fixed number of arguments or not (because there is no prototyped argument list).<\/li>\n<li>Any other case where the programmer does not explicitly override the calling convention.\u00c2\u00a0 The default Visual Studio build environment will use the compiler default calling convention if you do not explicitly tell it otherwise, and this goes to __cdecl.\u00c2\u00a0 Some build environments (the DDK\/build.exe platform in particular) default to different calling conventions, but Visual Studio built programs will always default to __cdecl if you are using CL.<\/li>\n<\/ul>\n<p>Next, we&#8217;ll take a look at __stdcall.\u00c2\u00a0 This calling convention is the standard for Win32 APIs; virtually all system APIs are __stdcall (typically decorated as &#8220;WINAPI&#8221;, &#8220;NTAPI&#8221;,\u00c2\u00a0or &#8220;CALLBACK&#8221; in the headers, which are macros that expand to __stdcall).\u00c2\u00a0 Here are the typcial usage cases for __stdcall (and the &#8220;why&#8221; behind them):<\/p>\n<ul>\n<li>Library functions.\u00c2\u00a0 Excepting the C runtime libraries, virtually all Microsoft-shipped Win32 libraries use __stdcall.\u00c2\u00a0 The main reason for this (if you discount the &#8220;that&#8217;s the way it has always been&#8221;) is that you save some instruction code space by using __stdcall and not __cdecl for library functions.\u00c2\u00a0 The reason for this is that for __cdecl functions, the caller typically needs to adjust the stack pointer after every &#8220;call&#8221; instruction to a __cdecl function (which takes up instruction code space &#8211; typically an &#8220;add esp, imm8&#8221; opcode).\u00c2\u00a0 For __stdcall functions, you only pay this penality once, in the &#8220;retn imm16&#8221; opcode at the end of the function (as opposed to once for every caller).\u00c2\u00a0 For frequently called functions (say, ReadFile), this begins to add up.\u00c2\u00a0 You also theoretically save a bit of processor time and cache space, as there is one less instruction to be executed per &#8220;call&#8221;.<\/li>\n<li>COM functions.\u00c2\u00a0 COM uses __stdcall with the &#8220;this&#8221; pointer being the first argument, which is\u00c2\u00a0a required part of the COM API contract for publicly accessible functions.<\/li>\n<li>Functions that need to be called from a language other than C\/C++.\u00c2\u00a0 This also ties back into the COM and library function purposes, but of all of the calling conventions discussed here, only __stdcall has practically universal support among non-Microsoft or non-C\/C++ compilers for x86 Win32 (such as Visual Basic, or Delphi).\u00c2\u00a0 As a result, it is advantageous to use __stdcall if you are expecting to be called from other languages.<\/li>\n<li>Microsoft-built programs.\u00c2\u00a0 Microsoft defaults their programs to __stdcall and not __cdecl virtually everywhere, even in images that don&#8217;t export functions, or in internally, non-exported funtions within a system library.\u00c2\u00a0 This also applies to Microsoft kernel mode code, such as the HAL and the kernel itself.<\/li>\n<li>Programs built with the DDK.\u00c2\u00a0 The DDK defaults to __stdcall and not __cdecl.<\/li>\n<li>NT kernel drivers.\u00c2\u00a0 These are always (or at least should always be!) built with the DDK, which again, defaults to __stdcall.<\/li>\n<\/ul>\n<p>There yet remains __fastcall to discuss.\u00c2\u00a0 This calling convention is not used as extensively as the other two (no Microsoft build environment that I am aware of defaults to it), so most of the cases for it being used are the result of a programmer explicitly requesting it.<\/p>\n<ul>\n<li>Functions that do not call other functions (&#8220;leaf functions&#8221;).\u00c2\u00a0 These are good candidates for __fastcall because the register arguments are passed in volatile registers, so there is a penalty associated with __fastcall functions that call subfunctions and need to use their arguments across those function calls, as this requires the __fastcall function to save arguments to somewhere nonvolatile (i.e. the stack), and that defeats the whole purpose of __fastcall entirely.<\/li>\n<li>Functions that do not use their arguments after the first subfunction call.\u00c2\u00a0 These can still benefit from __fastcall without the penalty mentioned above relating to preserving arguments across function calls.<\/li>\n<li>Short functions that call other functions and then return.\u00c2\u00a0 If you can make both functions __fastcall, then sometimes the compiler can be clever and not need to re-load the argument registers when a __fastcall function calls a __fastcall subfunction.\u00c2\u00a0 This can be useful for &#8220;wrapper&#8221; functions in some cases.<\/li>\n<li>Functions that interface with assembly code.\u00c2\u00a0 Sometimes it can be more convenient to make a C function called by assembler code __fastcall, because this can save you the work of manually tracking stack displacements.\u00c2\u00a0 It can also sometimes be more convenient to make assembler functions called by C code __fastcall as well, for similar reasons.<\/li>\n<\/ul>\n<p>In general, __fastcall is relatively rare.\u00c2\u00a0 There are a couple of kernel functions that use it (KfRaiseIrql, for instance).\u00c2\u00a0 A couple of software vendors (such as <a title=\"Blizzard Entertainment\" href=\"http:\/\/www.blizzard.com\">Blizzard Entertainment<\/a>) seem to like to ship things compiled with __fastcall as the default calling convention, but this not the common case, and usually not a good idea.<\/p>\n<p>Finally, there is __thiscall.\u00c2\u00a0 This calling convention is only used if you are using the default calling convention for member functions.\u00c2\u00a0 Note that for member functions that are not accessible cross-program (e.g. not exported somehow), the compiler will sometimes replace ecx with ebx for the &#8220;this&#8221; pointer as a custom calling convention, depending on your optimization settings.<\/p>\n<p>That&#8217;s all for this installment.\u00c2\u00a0 In the next posting, I&#8217;ll discuss what the various calling conventions look like at a low level (assembly), and what this means to you.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Last time,\u00c2\u00a0I talked about some of the general concepts behind the varying calling conventions in use on Win32 (x86).\u00c2\u00a0 This posting focuses on the implications and usage cases behind each of the calling conventions, in an effort to provide a better understanding as to when you&#8217;ll see them used. When looking at the different calling [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[2,8,5],"tags":[],"_links":{"self":[{"href":"http:\/\/www.nynaeve.net\/index.php?rest_route=\/wp\/v2\/posts\/42"}],"collection":[{"href":"http:\/\/www.nynaeve.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.nynaeve.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.nynaeve.net\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.nynaeve.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=42"}],"version-history":[{"count":1,"href":"http:\/\/www.nynaeve.net\/index.php?rest_route=\/wp\/v2\/posts\/42\/revisions"}],"predecessor-version":[{"id":652,"href":"http:\/\/www.nynaeve.net\/index.php?rest_route=\/wp\/v2\/posts\/42\/revisions\/652"}],"wp:attachment":[{"href":"http:\/\/www.nynaeve.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=42"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.nynaeve.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=42"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.nynaeve.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=42"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}