【问题标题】:How to call C inline assembly asm in cython?如何在 cython 中调用 C 内联汇编 asm?
【发布时间】:2021-06-19 21:20:26
【问题描述】:

如何在cython中调用C语言的内联汇编函数asm()?我尝试了一个简单的asm("mov $eax, 0x1") or __asm__()。在asm-call 之前,它会很好地进行cythonizes,然后给我以下错误:

NameError: name 'asm' 未定义

我将我的代码编译为python setup.py build_ext --inplace && python runids.py

【问题讨论】:

  • 除了让asm() 工作之外,您选择的示例非常疯狂。 AT&T 语法mov $eax, 0x1 有一个直接源操作数,即符号eax 的地址,例如C 全局作用域int eax;不是寄存器%eax。目标操作数是位于绝对地址1 的内存。所以...我猜这不是你想要写的。幸运的是,您没有修改任何寄存器,因此在 GNU C 内联 asm 中作为基本 Asm 语句运行将是一条“安全”指令(regs 或 "memory" 上没有 clobber 声明),因为该地址不会是任何 C 变量的地址。
  • @PeterCordes 感谢您提供的信息
  • 我应该指出的另一点是 GNU C Basic Asm 不安全或不真正可用于除 __attribute__((naked)) 函数体之外的任何东西,或者在全局范围内(作为单独.s 文件)。或者,如果使用在基本 Asm 语句上具有隐式 "memory" clobber 的 GCC 版本,则可能是 asm("mfence"); 或没有寄存器的东西。您需要寻找对扩展 Asm 的 Cython 支持,它在 C 中看起来像 asm ("inc %0" : "+r"(var));gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html
  • asm 不是函数。它只是碰巧看起来像一个。

标签: c cython inline-assembly


【解决方案1】:

不能直接从 Cython 调用汇编程序。您可以做的最好的事情是将asm 包装在一个C 函数中并从Cython 调用它——例如像这样使用verbatim C-code(这里是gcc):

%%cython

cdef extern from *:
    """
    void inline_asm_fun(void){
        __asm__("mov $1, %%eax" ::: "eax");
    }
    """
    void inline_asm_fun()
    
def use_inline_asm():
    inline_asm_fun()

正如@PeterCordes 所指出的,要在内联汇编器中做一些有用的事情,应该使用extended asm,即__asm__("mov $1, %%eax" ::: "eax"),而不是简单且不安全的__asm__("mov $1, %eax")。后者会修改 %eax 而不会通知编译器。

对于 MVSC,内联汇编器的非标准扩展名是 __asm,但它仅支持 x86 而不是 x64。

【讨论】:

  • 如果您要在不告诉编译器的情况下修改 EAX,则需要将 C 函数设为 __attribute__((naked))(并手动使用 ret)。或者更好的是,使用 clobber __asm__("mov $1, %%eax" ::: "eax"); 或使用 "=r"(var) 输出操作数。请不要编写不安全的内联汇编,即使作为其他示例;没有误导性的例子就很难学习了。
  • @PeterCordes 我只是举了 OP 的例子。我希望服用“nop”不会破坏任何东西......
  • 是的,nop 是安全的。不能保证在内联后它会在编译器生成的 asm 中结束,但它是 NOP,而不是 climfence 或其他东西,所以这也没关系。 (而且新的 GCC 在非空基本 Asm 语句上确实有一个隐含的 "memory" 破坏。)不过,我可能已经做了 __asm__("mov $1, %%eax" ::: "eax") 只是为了说明您需要扩展 Asm 来在 C 函数中对 asm 做任何有用的事情.
  • 大多数读者会假设他们可以用任何其他指令替换“nop”,但这里它 不是 占位符,它是基本 asm 语法唯一安全的东西。 gcc.gnu.org/wiki/ConvertBasicAsmToExtended
猜你喜欢
  • 2019-03-14
  • 2018-09-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-23
相关资源
最近更新 更多