The MASM Forum

Miscellaneous => 16 bit DOS Programming => Topic started by: jj2007 on January 10, 2021, 03:20:52 AM

Title: Raymond Chen, 2004: The History of Calling Conventions
Post by: jj2007 on January 10, 2021, 03:20:52 AM
https://devblogs.microsoft.com/oldnewthing/20040102-00/?p=41213

QuoteFastcall (__fastcall)
    The Fastcall calling convention passes the first parameter in the DX register and the second in the CX register (I think). Whether this was actually faster depended on your call usage. It was generally faster since parameters passed in registers do not need to be spilled to the stack, then reloaded by the callee. On the other hand, if significant computation occurs between the computation of the first and second parameters, the caller has to spill it anyway. To add insult to injury, the called function often spilled the register into memory because it needed to spare the register for something else, which in the "significant computation between the first two parameters" case means that you get a double-spill. Ouch!

    Consequently, __fastcall was typically faster only for short leaf functions, and even then it might not be.
Title: Re: Raymond Chen, 2004: The History of Calling Conventions
Post by: daydreamer on January 11, 2021, 08:27:34 PM
https://devblogs.microsoft.com/oldnewthing/20040108-00/?p=41163 (https://devblogs.microsoft.com/oldnewthing/20040108-00/?p=41163)?
what do you think about this?OUCH  :eusa_boohoo:

Quote from: jj2007 on January 10, 2021, 03:20:52 AM
QuoteFastcall (__fastcall)
    The Fastcall calling convention passes the first parameter in the DX register and the second in the CX register (I think). Whether this was actually faster depended on your call usage. It was generally faster since parameters passed in registers do not need to be spilled to the stack, then reloaded by the callee. On the other hand, if significant computation occurs between the computation of the first and second parameters, the caller has to spill it anyway. To add insult to injury, the called function often spilled the register into memory because it needed to spare the register for something else, which in the "significant computation between the first two parameters" case means that you get a double-spill. Ouch!

    Consequently, __fastcall was typically faster only for short leaf functions, and even then it might not be.
optimal usage of this fastcall would be pass data or pointer in dx and cx usage=number of times to loop,but wouldnt ax be better alternative if its some integer calculation proc?
so if data in CX is needed for calculation + combined with use it as counter register its ineffective to spill into memory+load to number of looping
Title: Re: Raymond Chen, 2004: The History of Calling Conventions
Post by: jj2007 on January 11, 2021, 08:37:10 PM
It depends, as usual. In an optimal case, i.e. (e)dx is already loaded (you don't need an explicit mov edx, myvar), then fastcall can be a cycle or so faster. This may matter if the called procedure is very short. And then comes the inevitable question: why call a short proc? Inline it!

So in practice, fastcall is never a good idea in 16- or 32-bit code.