64位快速调用

问题描述:

我一直在阅读32位调用约定的差异。 fastcallstdcall即是。64位快速调用

从我读到的这两个约定有很大的混淆,并且64位被标准化以避免这种混淆。

我不得不问,为什么选择fastcall

此外,由于fastcallstdcall是win32术语,函数调用的UNIX术语是否使用寄存器来传递参数?

+0

它并不完全是快速调用,它是“我们有8个更多的寄存器,让我们用'em'调用约定。 – 2012-07-11 00:23:19

+0

@hansPassant实际上没有使用寄存器来保存参数,因为通常必须事先将寄存器备份到堆栈中。在非常特殊的情况下,快速调用只会更快。 – Hawken 2012-07-11 01:02:00

+0

你假设他们必须“备份”。一般来说这不是一个正确的假设。代码生成器可以将它们视为暂存或从内存中重新加载它们。 “让我们使用'em'计划不是”让我们全部使用'。 – 2012-07-11 01:07:23

x86 Calling Conventions - Wikipedia, the free encyclopedia提供了一个列表。

x86-32上的通用调用约定是cdecl。 GCC提供了一个函数属性__attribute__((regparm(n)))来指示n参数是通过寄存器传递的,但这不同于fastcall。无论哪种方式,参数都在callee-clobberable寄存器中传递,因此函数调用相对于cdecl(对于regparm)和stdcall(对于fastcall)没有额外的开销(并节省了为参数添加堆栈空间的努力) 。

为了帮助您解决混淆问题,Windows和Linux上的x86-64调用约定与x86-32和x86-32上的调用约定不同。 fastcall也不是,虽然都使用大量的寄存器来传递参数。

+0

我更担心BSD,因为他们一直都有基于堆栈的调用,这既简单又节省CPU时间,因为您不需要事先备份寄存器。从我所了解的你所说的话看来,在64bit中不需要注册通行证? – Hawken 2012-07-11 01:05:37

+0

@Hawken:'regparm'和'fastcall'使用被调用者被破坏的寄存器,因此即使在'cdecl'和'stdcall'下也需要调用者保存 - 哪些CPU时间会丢失?目前C编译器没有使用非默认的x86-64调用约定。您可以看到[System V Application Binary Interface \ AMD64 Architecture Processor Supplement](http://www.x86-64.org/documentation/abi.pdf)和[MSDN | x64调用约定概述](http://msdn.microsoft.com/zh-cn/library/ms235286.aspx)了解当前正在使用的内容。 – ephemient 2012-07-11 01:17:14

+0

即使是FreeBSD开发手册也指出注册传递速度较慢。我倾向于相信他们,因为FreeBSD开发人员通常可以通过端口寄存器/堆栈传递程序进行测试,因为他们经常移植Linux代码。除此之外,你会认为你需要将传入的值写入堆栈,因为你将在你的指令中使用'%e_x'寄存器。除非你的功能只是调用另一个功能。 – Hawken 2012-07-12 08:39:10