Microsoft Visual Studio具有一个名为“内联汇编”的功能,使您能够在__asm块内的c ++程序中编写x86代码。
现在我对这个功能有疑问。
此寄存器中的寄存器是真正的寄存器还是只是寄存器的某些虚拟化?
使用此寄存器(例如eax,ebx等)是否可以提高性能?
答案 0 :(得分:3)
它们是真实的寄存器,与编译器生成的asm使用的寄存器相同。在将编译器的输出组装到机器代码之后,来自内联asm的指令与发出的指令之间没有区别。通过编译器。
使用此寄存器(例如eax,ebx等)是否可以提高性能?
与什么相比? 编译器生成的代码已经使用了寄存器,因此,不,除非您确切地知道自己在做什么,否则通常不能使用内联汇编来击败编译器。(例如,您已经阅读并理解了{ {3}},英特尔的优化手册,等等。请参阅Agner Fog's optimization guides中的更多链接。
https://stackoverflow.com/tags/x86/info是手写asm比编译器生成的asm差的一个很好的例子。
您(或编译器)将变量保存在寄存器中的次数越多,当它们频繁更改时,效果越好。您不能避免使用寄存器,因为x86在一些特殊指令之外没有内存到内存的指令。但是您可以(并且应该)避免使用内存。
即使那样,MSVC糟糕的inline-asm语法也使得无法将数据传递到inline asm中而不通过内存反弹,因此,您需要在asm中编写一个完整的循环以减轻这种开销。
有关此内容的更多信息,请参见C++ code for testing the Collatz conjecture faster than hand-written assembly - why?,以及使用MSVC内联汇编的简单函数的最终编译器输出示例,该示例还显示了编译器生成的指令。
(您可以使用What is the difference between 'asm', '__asm' and '__asm__'?自己编写任何代码。有关查看编译器输出的更多信息,请参见https://godbolt.org/。)
How to remove "noise" from GCC/clang assembly output?中的大多数原因都适用于MSVC组件以及GNU C组件。