【问题标题】:Why did Microsoft choose stdcall as their API convention?为什么微软选择 stdcall 作为他们的 API 约定?
【发布时间】:2011-04-03 02:39:26
【问题描述】:

有什么好的理由吗?

它们的内部函数(未导出)是否也是标准调用约定?

【问题讨论】:

  • 为什么微软选择 stdcall 作为他们的 API 约定?

标签: windows winapi calling-convention stdcall


【解决方案1】:

这是对 32 位代码的 pascal 调用约定的改编。 Pascal 是 OS/2 和 Windows 3 等 16 位操作系统的调用约定。为什么选择 pascal 有点猜测,即使我当时还是一只小狗,但它的效率略高。当您只需要使用 640 KB 时,这很重要。

大多数 Win32 函数不是真正的 stdcall,因为它还规定了导出函数在呈现给链接器之前如何修饰。就像 void Mumble(int arg) 变成 _Mumble@4。 @ 后面的数字描述了激活帧的大小。但是大多数 Win32 函数都是在没有任何修饰的情况下导出的。可能是为了给程序员一个使 GetProcAddress() 工作的机会。我认为装饰旨在帮助链接器检测声明的 API 函数签名与实际函数签名之间的不匹配。传递的参数数量不匹配是一种自动 kaboom,因为被调用者会在传递时从堆栈中弹出或多或少的参数。也很难诊断。 stdcall 的一个弱点,cdecl 约定没有这个问题。

内部调用是 stdcall、cdecl 和 thiscall 之间的混合包。不能说我曾经检测到一种模式,尽管我不喜欢单步执行 Windows 代码。

【讨论】:

  • 缺少符号装饰是因为 winapi 二进制文件使用.def 文件进行导出(去除装饰和/或使用序号),这使得通过 GetProcAddress 导入变得简单,因为没有符号装饰
  • 有时我确实喜欢单步执行 Windows 代码,而且我可以说大部分时间 stdcall 也在内部使用。
【解决方案2】:

使用 stdcall 编译的代码比使用 cdecl 编译的代码小得多(替代方法)。在做出决定时,更小的代码是更快的代码。

【讨论】:

  • 其实我更喜欢 Hans Passant 的回答,但无论如何。
  • 因为你是微软人(长期),所以我选择了你的答案。
  • 你有任何证据证明这个说法吗?直觉上,我认为这应该是 stdcall 和 cdecl 之间的清洗,谷歌搜索并没有得出两种调用约定之间的任何大小比较。
猜你喜欢
  • 1970-01-01
  • 2014-11-12
  • 1970-01-01
  • 2015-10-25
  • 1970-01-01
  • 1970-01-01
  • 2018-06-22
  • 1970-01-01
  • 2010-10-29
相关资源
最近更新 更多