Assembly 为什么有这么多不同的通话约定?

Assembly 为什么有这么多不同的通话约定?,assembly,history,low-level,calling-convention,Assembly,History,Low Level,Calling Convention,从历史上看,为什么似乎每个人和他们的弟弟都定义了自己的通话约定?你有C,C++,Windows,Pascal,Fortran,Fastcall,还有其他我想不提的无数。对于绝大多数用例,一个约定不应该是最有效的吗?有什么好的理由选择一个而不是另一个吗?因为从历史上看,每个人和他们的弟弟都定义了自己的通话约定。它们都是为不同的目的而创建的,因此受到不同性能需求的驱动。例如,C++支持优化< > 参数> UL>。 其中一些在性能方面更有效,而另一些在代码大小方面更有效 某些功能(变量参数计数)仅受

从历史上看,为什么似乎每个人和他们的弟弟都定义了自己的通话约定?你有C,C++,Windows,Pascal,Fortran,Fastcall,还有其他我想不提的无数。对于绝大多数用例,一个约定不应该是最有效的吗?有什么好的理由选择一个而不是另一个吗?

因为从历史上看,每个人和他们的弟弟都定义了自己的通话约定。它们都是为不同的目的而创建的,因此受到不同性能需求的驱动。例如,C++支持优化< <代码> > <代码>参数>

UL>。
  • 其中一些在性能方面更有效,而另一些在代码大小方面更有效
  • 某些功能(变量参数计数)仅受某些约定的支持

  • 更多信息:

    部分原因是微处理器(或处理器)的底层架构。大多数语言都是从一个特定的CPU开始的,并且与该体系结构有点纠结。例如,旧的Univac 1100系列计算机甚至没有调用堆栈


    另一部分原因是,除非您尝试了多种方法,否则无法预见最佳解决方案。

    您提到的呼叫约定是几十年来为不同语言和不同硬件设计的。他们都有不同的目标。cdecl支持printf的变量参数。stdcall生成的代码较小,但没有变量参数。Fastcall可以极大地提高在旧机器上仅使用一个或两个参数的简单函数的性能(但现在很少有这样的速度)

    请注意,与x64引入时相比,至少在Windows上,它被设计为具有单一调用约定


    Raymond Chen写了一个关于调用约定历史的伟大系列,你可以开始了。

    它们是为不同的目的创建的,使用不同的优化系统

    例如,为了减少“堆栈溢出”(没有双关语的意思),一些人想出了各种方法来调用函数,使堆栈溢出不可能


    另一个例子是Lambda演算。不要说得太模糊,但在Lambda中,函数可能只传递一个参数并返回一个值,因此也需要它们自己的调用约定。

    我喜欢Raymond Chen的文章。它回答了很多问题。