【问题标题】:Why are there so many different calling conventions?为什么有这么多不同的调用约定?
【发布时间】:2010-08-06 22:49:01
【问题描述】:

从历史上看,为什么似乎每个人和他们的小弟都定义了自己的调用约定?你有 C、C++、Windows、Pascal、Fortran、Fastcall 以及可能还有无数其他我没想到会提到的东西。对于绝大多数用例来说,一种约定不应该是最有效的吗?有什么好的理由偏爱其中一个吗?

【问题讨论】:

    标签: assembly history low-level calling-convention


    【解决方案1】:

    您提到的调用约定是数十年来针对不同语言和不同硬件设计的。他们都有不同的目标。 cdecl 支持 printf 的可变参数。 stdcall 导致更小的代码生成,但没有可变参数。 Fastcall 可以极大地加速在旧机器上仅使用一两个参数的简单函数的性能(但现在很少加速。)

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

    Raymond Chen写了一个关于调用约定历史的精彩系列,可以开始here

    【讨论】:

    • 我喜欢 Raymond Chen 的文章。它回答了很多问题。
    【解决方案2】:

    因为从历史上看,每个人和他们的小弟确实定义了自己的调用约定。它们都是为不同的目的而创建的,因此由不同的性能需求驱动。例如,C++ 倾向于对传递 this 参数进行优化。

    【讨论】:

      【解决方案3】:
      • 其中一些在性能方面更有效,而另一些在代码大小方面更有效。
      • 某些功能(可变参数计数)仅受某些约定支持。

      更多信息:http://en.wikipedia.org/wiki/X86_calling_conventions

      【讨论】:

        【解决方案4】:

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

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

        【讨论】:

          【解决方案5】:

          它们是为不同的目的而创建的,并具有不同的优化系统。

          例如,为了减少“堆栈溢出”(不是双关语),有些人想到了各种想法来调用函数以使堆栈溢出不可能。

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

          【讨论】:

            猜你喜欢
            • 2012-02-10
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-10-17
            • 1970-01-01
            • 2023-03-29
            • 2023-03-10
            • 1970-01-01
            相关资源
            最近更新 更多