- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我见过fastcall
在许多函数之前附加符号。为什么使用它?
最佳答案
函数前的符号称为“调用约定”。它指定编译器如何(在低级别)将输入参数传递给函数并在执行后检索其结果。
有许多不同的调用约定,最流行的是 stdcall
和 cdecl
.
您可能认为只有一种方法可以做到这一点,但实际上,您可以通过多种方式调用函数并将变量传入和传出。您可以将输入参数放在堆栈上(推、推、推调用;弹出、弹出、弹出以读取输入参数)。或者,您可能更愿意将它们放在寄存器中(这是 fastcall
- 它试图将一些输入参数放入寄存器以提高速度)。
但是订单呢?你是从左到右还是从右到左插入它们?结果怎么样 - 总是只有一个(假设没有引用参数),那么你是否将结果放在堆栈上,在寄存器中,在某个内存地址?
此外,让我们假设您正在使用堆栈进行通信 - 谁的工作是在调用函数后实际清除堆栈 - 调用者还是被调用者?
如何备份然后恢复(某些)CPU 寄存器的内容 - 调用者应该这样做,还是被调用者保证它会按原样返回所有内容?
最流行的调用约定(到目前为止)是 cdecl
,这是 C 和 C++ 中的标准调用约定。 WIN32 API 使用 stdcall
,这意味着任何调用 WIN32 API 的代码都需要使用 stdcall
对于那些函数调用(使其成为另一个流行的选择)。fastcall
有点奇怪 - 人们意识到只有一个输入/输出参数的许多函数,从基于内存的堆栈中插入和弹出是相当多的开销,并且使函数调用有点重,因此引入了不同的编译器(不同的) 调用约定将一个或多个参数放入寄存器,然后将其余参数放入堆栈以获得更好的性能。问题是,并非所有编译器都使用相同的规则来处理 fastcall
,因此您在使用它时必须小心,因为您永远不知道谁在做什么。最后看Is fastcall really faster?有关 fastcall
的信息性能优势。
复杂的东西。
需要记住的重要事项:如果您不确切知道自己在做什么,请不要添加或更改调用约定,因为如果调用方和被调用方都不同意调用约定,您很可能最终会堆栈损坏和段错误。这通常发生在您在 DLL/共享库中调用函数并且编写的程序依赖于 DLL/SO/dylib 是某个调用约定(例如, cdecl
),然后使用不同的调用约定(例如, fastcall
)。现在旧程序无法再与新库通信。
关于visual-c++ - Visual c 中使用的 fastcall 关键字是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10671281/
我目前正在自己学习 x64 汇编,并且在从 C++ 调用汇编过程时无法理解堆栈会发生什么。 从我目前从 MSDN 了解到的和 Intel , 前 4 个整数/浮点参数存储在 rcx/xmm0、rd
我正在尝试从 C++ 调用我的 asm 函数并发送两个参数,根据维基百科关于 fastcall 调用约定,这两个参数应该保存在 ecx 和 edx 中。 但这不起作用。我错过了什么吗? 汇编 x86
例如,假设我有一个函数可以为您交换 32 位值中的字节: uint32_t byte_swap(uint32_t in); 好吧,将 32 位值压入堆栈并再次将其弹出似乎很愚蠢,特别是如果我们要经常调
您有使用调用约定 fastcall 的实际用例吗? 谢谢。 最佳答案 __fastcall 尝试在 CPU 寄存器而不是堆栈中传递函数参数(如果可能),这样速度更快。 这是一个 MSDN 文章的链接,
好的,所以我可以调用函数作为fastcall CC,方法是用__attribute__((fastcall))声明它。如何将函数本身定义为 fastcall? 例如,我有来电代码: // caller
考虑到: Microsoft Specific The __fastcall calling convention specifies that arguments to functions are
所以我有一个程序集需要在 Windows 上使用 fastcall 调用约定调用一个函数,但 gcc 不(afaict)支持它。 GCC 确实提供了 regparm 属性,但它期望前 3 个参数在 e
我有一个以极高频率调用的 CRC 计算函数。我已经声明为 inline 我尝试将其设为 __attribute((hot))__ 但我不确定这是否能买到任何东西。我正在考虑将其设为 fastcall。
我见过fastcall在许多函数之前附加符号。为什么使用它? 最佳答案 函数前的符号称为“调用约定”。它指定编译器如何(在低级别)将输入参数传递给函数并在执行后检索其结果。 有许多不同的调用约定,最流
这2个约定在x86编译模式下一起使用? 对于 64 位编译,没有 cdecl + fastcall 对吗?只是 AMD 64 ABI 调用约定?如果是这样,如何在 64 位模式下在 stdcall 和
我进退两难,对于 VM 的循环来说,什么是性能更好的选择: 选项 1 - 强制内联指令函数,使用计算的 goto 切换到该标签上指令的调用(有效的内联代码)...或... 选项 2 - 使用函数指针查
我是一名优秀的程序员,十分优秀!