我们可以在装配中做些什么,我们不能在原始C中做什么?或者在装配中更容易做的事情?任何现代代码是使用内联汇编实际编写的,还是仅仅作为遗留或教育功能实现?
答案 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
在当前具有当前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实施,例如glibc或musl libc等......)正在使用asm
(至少要制作) syscalls)但很少有主要的免费软件(直接)使用asm
说明。