繁体   English   中英

简单明了,我们为什么要使用_stdcall?

[英]Plainly and simply, why do we use _stdcall?

我在学习使用C ++进行游戏制作的状态时遇到了调用约定。

在前一个问题中有人说MSDN没有很好地解释_stdcall - 我同意。

调用_stdcall等约定的主要目的是什么? 参数放在堆栈上的顺序是否重要? 它如何减少X86中的代码大小(正如其他人所说)?

一些调用约定的原因很简单:这样调用者和被调用者就事情如何工作达成一致。 没有它,调用者在调用特定函数时不知道在哪里放置参数。

至于为什么微软决定_stdcall的具体细节,这在很大程度上是历史性的。 在MS-DOS上,所有调用都是基于寄存器的,因此所有OS调用都需要汇编语言,或大多数高级语言的奇怪扩展。

当他们第一次使用Windows时,他们使用了cdecl调用约定,主要是因为这是编译器默认执行的操作。 至少根据谣言,在他们准备发布Windows 1.0之前不久,他们改用了Pascal调用约定,因为它足够高效(除其他外)它允许Windows适合少一张软盘。 不管精确的细节,调用约定在Pascal确实使代码更小一点,因为被调用函数从堆栈的需要,而不是到处清理它们的函数被调用清理参数。 对于从至少2个不同位置调用的任何函数,这是一个胜利(如果它在其他任何地方都有关系)。

然后他们开始研究OS / 2,并发明了另一个调用约定(syscall)。

然后,当然,来了Win32。 从技术角度来看,系统调用并没有太多问题,但是(我猜)与OS / 2相关的所有内容都被认为是污点,所以系统调用必须要去。 结果只是足以证明新名称的合理性。 公平地说,这有点夸张:他们确实添加了一个真正有用的补充:他们将参数的字节数编码到每个函数名中,所以如果(例如)你为函数提供了一个不正确的原型,那么代码就不会链接而不是最终导致调用者和被调用者之间的不匹配,这可能导致更严重的问题。

在大多数情况下,它确实回到了最初的观点:调用约定的确切细节并不重要,只要你不完全搞乱它。 大多数重要的是调用者和被调用者同意相同的事情,所以如果编译器知道函数接受什么参数,它知道如何生成代码以正确地获取这些参数(同样,他们都同意如何处理堆栈清理等)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM