gcc - 编写没有破坏列表的内联汇编?
问题描述
是否可以使用 GCC 或 Clang 编写内联汇编(英特尔语法),而无需了解 clobber 列表“东西”?
我会猜测“不”,因为clobber 列表“stuff”确保您不会覆盖编译器写入的寄存器(就在您的内联汇编开始之前)?
解决方案
GNU C Basic 内联 asm 语句(无操作数/clobber 列表)基本上不推荐用于除了__attribute__((naked))
函数体之外的任何内容。 为什么不能在 GNU C 基本内联 asm 语句中使用局部变量?(也不能安全地使用全局变量。)
https://gcc.gnu.org/wiki/DontUseInlineAsm说要查看ConvertBasicAsmToExtended,原因是不使用基本 asm 语句。在 Basic asm 中你不能真正安全地做任何事情;甚至asm("cli");
可以通过任何不是volatile
.
如果您打算使用内联asm(而不是在 asm 中编写独立函数,或者使用内部函数编写 C),您需要向编译器详细描述您的 asm 指令字符串,用黑色带有输入和/或输出操作数和/或clobbers的盒子。有关指南的链接,请参阅https://stackoverflow.com/tags/inline-assembly/info,包括有关使用输入/输出约束的一些 SO 答案。
在决定是否真的值得将 GNU C 内联汇编用于任何事情之前,请三思而后行。如果您可以让编译器以另一种方式发出相同的指令,那几乎总是更好。内在函数或纯 C 语言允许不断传播优化;内联 asm 没有(除非你做类似的事情 if(_builtin_constant_p(x)) { pure C version } else { inline asm version }
)。
Intel 语法:在 GCC 中,编译时-masm=intel
您的 asm 模板将成为 Intel-syntax 的一部分.s
,并且编译器将替换 Intel 语法中的操作数。(喜欢dword ptr [rsp]
而不是(%rsp)
for "m"(my_int)
)。
在铿锵声中,我不确定在正常的 asm 语句中使用 Intel 语法是否有任何方便的方法。
但是,如果您不关心高效的代码(但是为什么要使用 asm?),还有另一种选择: clang 支持-fasm-blocks
允许像 MSVC 的低效内联 asm 样式这样的语法。 是的,这使用了英特尔语法。
有没有办法在 linux 平台上编译微软风格的内联汇编代码?显示了生成的代码是多么低效:充满了编译器生成的指令,用于将输入变量存储到内存中,以便asm{}
块读取它们。因为 MSVC 样式的 asm 块不能在寄存器中进行输入或输出。(Clang 不支持 leave-a-value-in-EAX 方法来获取单个值,因此也必须存储/重新加载输出。)
你不能为此指定clobbers,所以我假设一个asm块意味着一个"memory"
clobber,以及你写的所有寄存器上的clobbers。(或者甚至只是提及。)
我不会推荐这个; 基本上不可能以这种方式有效地包装单个指令或少数指令。只有在编写整个循环时,才能分摊将输入输入asm{}
块的开销。
推荐阅读
- angular - 如何在 Angular 2+ 的 ngbDatePicker 中突出显示今天的日期?
- symfony - FOSuserBundle 覆盖控制器
- css - 使用线将单个 div 与周围的多个 div 连接起来
- c# - 根据属性列表指定 AutoMapper 映射
- c++ - 如果你有一个固定大小的数组,并且需要遍历它!n 次,那么使用二分查找如何改变时间复杂度?
- omnet++ - 为传感器选择随机初始位置,但在特定区域
- opencv - 确定数据类型并用作模板类型名
- ios - 如何在 UIScrollView 中处理 UIScrollView
- sql - 在 Oracle 中查询 XML
- ios - FileManager MoveItem 回调 - Swift