内联汇编的“真实”用途是什么?

时间:2015-01-25 16:27:06

标签: c assembly inline-assembly

我们可以在装配中做些什么,我们不能在原始C中做什么?或者在装配中更容易做的事情?任何现代代码是使用内联汇编实际编写的,还是仅仅作为遗留或教育功能实现?

2 个答案:

答案 0 :(得分:5)

内联汇编(以及相关说明,调用纯粹在汇编中编写的外部函数)可能非常有用或绝对必要,例如编写设备驱动程序,直接访问硬件或未在语言中定义的处理器功能,硬件 - 支持并行处理(与多线程相对),如CUDA,与FPGA的接口,性能等。

这也很重要,因为有些事情只能通过标准(C ++和C)提供的抽象级别“下方”来实现。

标准认识到某些事情本质上是实施定义的,并且在整个标准中允许这样做。其中一项津贴(可能是最低级别)是对asm的承认。那么,“有点”的认可:

在C(N1256)中,可在“共同扩展”下的标准中找到:

  

J.5.10 asm关键字
  1 asm关键字可用于将汇编语言直接插入转换器输出(6.8)。最常见的实现是通过以下形式的声明:

     
    

asm(character-string-literal);

  

在C ++(N3337)中,它有类似的警告:

  

§7.4/ 1
  asm声明的格式为

     
    

ASM-定义:

         
      

asm(string-literal);

    
  
     

asm声明是有条件支持的;它的含义是实现定义的。 [注意:通常用于将信息通过实现传递给汇编程序。 - 注意]

应该注意的是,近年来的一个重要发展是,通过使用内联汇编来提高性能往往会适得其反,除非您完全知道 正在做什么。编译器/优化器寄存器使用决策,管道感知和分支预测行为等几乎总是足以满足大多数用途。

另一方面,近年来处理器为更高级别的操作(例如英特尔的AES扩展)增加了CPU级别的支持,可以为专业应用程序提高几个数量级的性能。

所以:

传统功能?一点也不。这对某些要求绝对必要。

教育特色?在一个理想的世界中,只有伴随着一系列讲座,解释为什么你可能永远不需要它,如果你确实需要它,如何尽可能地将它的可见表面区域限制在你的应用程序的其余部分。 / p>

答案 1 :(得分:5)

在以下情况下,您还需要使用内联asm进行编码:

  • 您需要使用标准C中不可用的某些处理器功能;通常,使用进位机器指令的添加在bignum

  • GMPlib实现中非常有用
  • 在当前具有当前optimizing compilers的处理器上,出于性能原因通常不应使用asm,因为编译器会优化得更好(一个旧示例正在实现memcpy x86上的rep stosw

  • 在使用或实施其他ABI时,您需要一些asm。例如,某些Ocaml或Common Lisp实现的运行时系统具有不同的调用约定,转换到它们可能需要asm;但是当前libffi(使用asm)可能会避免您使用asm进行编码

  • 您的全新硬件可能最近instruction set未完全由您的编译器实现(例如AVX512 ...等扩展程序),您可能需要asm < / p>

  • 您希望实现一些在C中无法实现的功能,例如: backtrace

一般来说,在使用asm之前你应该考虑两次以上,如果你使用它,你应该在很少的地方使用它。通常,请避免使用asm ....

GCC编译器引入了extended asm功能,该功能几乎已成为许多其他编译器支持的事实上的标准(例如Clang/LLVM ...) - 但详细信息在于。另请参阅GCC Inline Assembly HowTo

Linux kernel(以及许多libc实施,例如glibcmusl libc等......)正在使用asm(至少要制作) syscalls)但很少有主要的免费软件(直接)使用asm说明。

另请阅读Linux Assembly HowTo