为什么会有这么多不同的调用约定?

时间:2010-08-06 22:49:02

标签: assembly history low-level calling-convention

从历史上看,为什么看起来每个人和他们的小弟弟都定义了他们自己的召唤惯例?你有C,C ++,Windows,Pascal,Fortran,Fastcall以及其他可能没有提及的其他人。对于绝大多数用例,一项公约不应该是最有效的吗?是否有任何理由更喜欢一个而不是另一个?

5 个答案:

答案 0 :(得分:10)

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

注意,除了引入x64之外,至少在Windows上,它被设计为具有单个调用约定。

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

答案 1 :(得分:1)

因为历史上每个人和他们的孩子兄弟确实定义了他们自己的召唤惯例。它们都是为不同的目的而创建的,因此受到不同性能需求的驱动。例如,C ++倾向于优化传递this参数。

答案 2 :(得分:1)

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

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

答案 3 :(得分:0)

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

另一部分原因是,在您尝试了多种做法之前,无法预见最佳解决方案。

答案 4 :(得分:0)

它们是为不同目的和不同的优化系统而创建的。

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

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