Author Topic: Raymond Chen, 2004: The History of Calling Conventions  (Read 98 times)

jj2007

  • Member
  • *****
  • Posts: 11051
  • Assembler is fun ;-)
    • MasmBasic
Raymond Chen, 2004: The History of Calling Conventions
« on: January 10, 2021, 03:20:52 AM »
https://devblogs.microsoft.com/oldnewthing/20040102-00/?p=41213

Quote
Fastcall (__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.

daydreamer

  • Member
  • *****
  • Posts: 1458
  • building nextdoor
Re: Raymond Chen, 2004: The History of Calling Conventions
« Reply #1 on: January 11, 2021, 08:27:34 PM »
https://devblogs.microsoft.com/oldnewthing/20040108-00/?p=41163?
what do you think about this?OUCH  :eusa_boohoo:

Quote
Fastcall (__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
SIMD fan and macro fan
Happy new year 2021 that can only turn out to become better than worse 2020 :)

jj2007

  • Member
  • *****
  • Posts: 11051
  • Assembler is fun ;-)
    • MasmBasic
Re: Raymond Chen, 2004: The History of Calling Conventions
« Reply #2 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.