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

Dez*_*chu 5 c++ calling-convention stdcall

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

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

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

Jer*_*fin 8

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

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

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

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

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

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