在C++中嵌入汇编程序可以接受吗
Embedding assembler within C++ acceptable?
如果你正在编写一个对延迟非常敏感的应用程序,那么在C++函数中嵌入汇编程序的限制是什么(通常使用C++函数调用),比如:
inline __int64 GetCpuClocks()
{
// Counter
struct { int32 low, high; } counter;
// Use RDTSC instruction to get clocks count
__asm push EAX
__asm push EDX
__asm __emit 0fh __asm __emit 031h // RDTSC
__asm mov counter.low, EAX
__asm mov counter.high, EDX
__asm pop EDX
__asm pop EAX
// Return result
return *(__int64 *)(&counter);
}
(以上功能来自我看到的另一个SO帖子)
您能像对待黑盒那样对待汇编程序内联函数吗?您能很容易地从汇编程序中进行的计算中检索结果吗?是否存在您不知道寄存器等中当前存在哪些变量的危险?它是造成的问题多于解决的问题,还是对于特定的小任务来说可以接受?
(假设您的体系结构是固定的,并且是已知的)
编辑:我刚刚发现了这个,这就是我所暗示的:
http://www.codeproject.com/Articles/15971/Using-Inline-Assembly-in-C-C
EDIT2这更针对Linux和x86——这只是一个通用的C++/汇编程序问题(或者我是这么认为的)。
我想回答子问题:
它是造成的问题多于解决的问题,还是适用于特定的小任务?
确实如此!使用内联汇编程序,您可以从编译器获得优化代码的能力。它不能进行部分表达式替换或任何其他奇特的优化。生成比编译器使用-O3发出的代码更好的代码真的非常困难。另外,下一个编译器版本的代码会变得更好(假设下一个编译版本不会破坏它;)。
编译器通常比人脑掌握的范围更广(或者应该掌握的范围,以确保理智),能够在正确的位置内联正确的函数,进行部分表达式替换,从而提高代码的效率。在ASM中你永远不会做的事情,因为你的代码变得无法读取。
作为一个轶事参考,我想参考Linus Torvalds的这篇文章,它涉及SHA1的git实现,它在libcrypt中优于手工优化的SHA1。
实际上,我认为现在内联汇编程序的唯一合理用途是调用处理器指令,而这些指令在其他情况下是不可用的(你引用的指令是可用的,例如在linux上作为clock_gettime
,至少如果你只在追求高分辨率的时间计数器),或者如果你必须做一些需要欺骗编译器的事情(例如在实现外部函数接口的过程中)。
关于片段和其他人所说的内容。尤其是使用这样的函数,您将受到性能惩罚。在内联asm中,您必须非常小心地将寄存器保持在编译器假设的状态(如上所述,推送/弹出)。如果你正常地编写代码,编译器可以小心地将那些有意义的变量和那些不适合堆栈的变量保留在寄存器中。
相信你的编译器。这很聪明。大多数时候。通过不使用内联汇编程序来思考智能、快速算法和学习相关的编译器开关(例如启用SSE优化等),可以节省时间。
如果有问题的asm在顶部推送它使用的任何寄存器,然后在底部弹出它们,我认为你不用担心。
在您的示例中,这些是__asm push EAX
和__asm pop EAX
指令。
我想,真正的答案是,你需要足够了解asm的作用,才能确保你能把它当作一个黑匣子。:)
- 为什么编程语言被编译为汇编程序而不是二进制?
- 如何使用 LLVM 库编写汇编程序
- ICC 中的 -O2 搞砸了汇编程序,ICC 中的 -O1 和 GCC / Clang 中的所有优化都很好
- 为什么汇编代码因我使用的反汇编程序而异
- C2400 内联汇编程序语法错误,与 2015 年
- 使用libwebrtc-audio-Processing-Devel汇编程序
- 编译基本汇编程序时链接错误
- 输入汇编程序-顶点着色器链接错误
- 使用intel内联汇编程序对bigint-add进行进位编码
- 在C++中嵌入汇编程序可以接受吗
- 在Windows上编译器/执行汇编程序的最简单方法
- 如何将 c++ 中的 for 循环转换为汇编程序
- 如何在Visual Studio汇编程序输出中取消名称
- 为什么 Direct3D11 的输入汇编程序只绘制 1 个对象?
- c++汇编程序文件读取
- 当我们编译C++时,我们会得到什么?二进制代码?汇编程序代码
- 如何在visual c++内联汇编程序中通过引用获取值
- 汇编程序代码中的静态值
- Linux汇编程序消息错误c++
- x64 API挂钩没有反汇编程序库