【问题标题】:registers of inline assembly block are real or fake?内联汇编块的寄存器是真的还是假的?
【发布时间】:2019-04-17 17:18:09
【问题描述】:

Microsoft Visual Studio 有一个名为“内联汇编”的功能,它使您能够在 __asm 块内的 c++ 程序中编写 x86 代码。

现在我有一个关于此功能的问题。

这个块中的寄存器是真正的寄存器还是只是来自寄存器的一些虚拟化?

使用此寄存器(如 eax 、 ebx 等)是否会提高性能?

【问题讨论】:

  • 寄存器是真实的。是的,如果您使用它们,性能通常会得到改善。请注意,C 编译器有一个非常好的优化器,它在选择寄存器方面通常比你做得更好,所以你应该避免使用内联汇编,除非你确切地知道你在做什么。
  • 一些 C 编译器,例如 armcc,确实在内联汇编中使用虚拟寄存器。 Microsoft 或 GCC 内联汇编都没有。

标签: c++ visual-studio assembly x86 inline-assembly


【解决方案1】:

它们是真正的寄存器,与编译器生成的 asm 使用的相同。 将编译器输出组装成机器代码后,哪些指令来自内联 asm 与哪些指令发出并没有区别由编译器。

使用此寄存器(如 eax 、 ebx 等)是否会提高性能?

与什么相比? 编译器生成的代码已经使用了寄存器,所以不,除非您确切地知道自己在做什么,否则您通常无法使用内联 asm 击败编译器。(例如,您已经阅读并理解了所有 @ 987654321@,英特尔的优化手册等。更多链接见https://stackoverflow.com/tags/x86/info)。

C++ code for testing the Collatz conjecture faster than hand-written assembly - why? 是手写 asm 比编译器生成的 asm 差的一个很好的例子。

当变量频繁更改时,您(或编译器)将变量保存在寄存器中的次数越多越好。您不能避免使用寄存器,因为 x86 除了一些特殊指令之外没有内存到内存指令。但是您可以(并且应该)避免使用内存。


即便如此,MSVC 糟糕的 inline-asm 语法也使得在不通过内存反弹的情况下将数据传递到 inline asm 是不可能的,因此您需要在 asm 中编写一个完整的循环来减轻这种开销。强>

请参阅What is the difference between 'asm', '__asm' and '__asm__'? 了解更多信息,以及使用 MSVC 内联汇编的简单函数的最终编译器输出示例,该示例也显示了编译器生成的指令。

(您可以使用https://godbolt.org/ 为任何代码自己执行此操作。有关查看编译器输出的更多信息,另请参阅How to remove "noise" from GCC/clang assembly output?。)

https://gcc.gnu.org/wiki/DontUseInlineAsm 中的大多数原因适用于 MSVC asm 以及 GNU C asm。

【讨论】:

  • 所以还有一个问题,例如我的处理器是一个核心 i5 处理器,它的架构肯定与 x86 不同。我的意思是它可能比 x86 有更多的寄存器。而内联汇编只有几个 x86 寄存器。其他寄存器呢?
  • @RamtinMousavi:您的 i5 是 x86-64 CPU。它可以在 32 位或 64 位模式下运行。 MSVC 内联汇编在为 64 位模式编译时不可用。编译器生成的代码可以很好地使用 64 位寄存器。在 32 位模式下运行时,您“仅”获得 8 个整数寄存器而不是 16 个整数寄存器和 xmm/ymm/zmm 0..7 而不是 xmm/ymm0..15 或 zmm0..31 但您仍然拥有 x87 堆栈、MPX 绑定寄存器、EFLAGS 以及段、调试和控制寄存器。
  • @RamtinMousavi 当然,您的 CPU 是具有 x86 架构的 x86 CPU。它确实有其他寄存器,但它们不是像 eax、ebx 等通用寄存器,所以你不能直接将它们用于相同的目的。
  • @fuz 谢谢。我不知道所有核心 ix cpu 也是 x86。 8086之后发布的所有intel cpus都使用相同的汇编语言吗?
  • @RamtinMousavi 虽然英特尔也生产其他架构的处理器,但您通常会遇到的所有英特尔 CPU 都是 x86 处理器。 AMD 处理器也是如此。如果架构不同,那么 x86 程序将无法在这些芯片上运行,除非先重新编译。
猜你喜欢
  • 2014-04-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-25
  • 1970-01-01
相关资源
最近更新 更多