为什么有这么多不同的调用约定?
从历史上看,为什么似乎每个人和他们的弟弟都定义了自己的调用约定?你有 C、C++、Windows、Pascal、Fortran、Fastcall 以及可能还有无数其他我没有想到的语言。难道不应该有一种约定对于绝大多数用例来说是最有效的吗?是否有任何充分的理由选择其中一种而不是另一种?
Historically, why does it seem like just about everyone and their kid brother defined their own calling conventions? You've got C, C++, Windows, Pascal, Fortran, Fastcall and probably a zillion others I didn't think to mention. Shouldn't one convention be the most efficient for the vast majority of use cases? Is there ever any good reason to prefer one over the other?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
您提到的调用约定是几十年来针对不同语言和不同硬件设计的。他们都有不同的目标。 cdecl 支持 printf 的变量参数。 stdcall 导致代码生成更小,但没有变量参数。在旧机器上,Fastcall 可以极大地提高仅使用一两个参数的简单函数的性能(但现在很少能提高速度。)
请注意,当引入 x64 时,至少在 Windows 上,它被设计为具有单一调用约定。
Raymond Chen 撰写了有关调用约定历史的精彩系列文章,您可以从这里开始。
The calling conventions you mention were designed over the course of decades for different languages and different hardware. They all had different goals. cdecl supported variable arguments for printf. stdcall resulted in smaller code gen, but no variable arguments. Fastcall could greatly speed up the performance of simple functions with only one or two arguments on older machines (but is rarely a speed up today.)
Note than when x64 was introduced, on Windows at least, it was designed to have a single calling convention.
Raymond Chen wrote a great series on the history of calling conventions, you can start here.
因为从历史上看,每个人和他们的弟弟都定义了自己的调用约定。它们都是为了不同的目的而创建的,因此受到不同的性能需求的驱动。例如,C++ 倾向于优化传递
this
参数。Because historically everyone and their kid brother did define their own calling conventions. They were all created for different purposes and thus driven by different performance needs. For instance, C++ favours optimisations for passing the
this
parameter.更多信息:http://en.wikipedia.org/wiki/X86_calling_conventions
More Information: http://en.wikipedia.org/wiki/X86_calling_conventions
部分原因是微处理器(或处理器)的底层架构。大多数语言都从特定的 CPU 开始,并与该架构有点纠缠在一起。例如,旧的 Univac 1100 系列计算机甚至没有调用堆栈!
另一部分原因是,在尝试了多种做事方法之前,不可能预见到最佳解决方案。
Part of the reason is the underlying architecture of the microprocessor (or processor). Most languages start on a specific CPU, and get entangled a bit with that architecture. For example, the old Univac 1100 series computer didn't even have a call stack!
Another part of the reason is that is is not possible to foresee the best solution until you've tried several ways of doing things.
它们是为不同的目的而创建的,并且具有不同的优化系统。
例如,为了减少“堆栈溢出”(没有双关语),一些人想到了各种调用函数的想法,以防止堆栈溢出。
另一个例子是 Lambda 演算。不要太含糊,但在 Lambda 中,函数只能传递一个参数并返回一个值,因此也需要自己的调用约定。
They're created for different purposes, and with different optimization systems.
For instance, to reduce "Stack Overflow," (no pun intended) some people thought of various ideas to call function to make stack overflows impossible.
Another instance is the Lambda Calculus. Not to be too vague, but in Lambda, functions may only pass one argument and return one value, and thus also need their own calling conventions.