【问题标题】:Convert this embedded assembly code as to work with gcc将此嵌入式汇编代码转换为与 gcc 一起使用
【发布时间】:2018-12-07 21:14:00
【问题描述】:

我正在尝试将这段代码转换为与 g++ 使用的 AT&T 程序集一起使用:

double sqrt13(double n)
{
__asm{
 fld n
 fsqrt
 }
}

基于此链接:https://ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html: 我试过这个:

double raiz (double n)
    __asm__ ( "fld n\n\t"
    "fsqrt\n\t" );

但我一直收到:

/tmp/cc2AQhHj.s|662|Error: junk `n' after expression|

同样的错误信息在该文件的其他行中又出现了四次

我下载了一个名为“intel2gas”的程序,他对我说代码应该是这个:

    __asm__ volatile__ (
    "fld %0\n"
    "fsqrt\n"
    :"=m"(n)
    :
    :"memory", "esi", "edi", "eax", "ebx", "ecx", "edx"
    );

将其放入函数中并尝试运行它,我收到:

 |39|error: expected ‘(’ before ‘volatile__’|
|42|error: expected ‘)’ before ‘:’ token|
|45|error: ‘volatile__’ was not declared in this scope|

加上一个 |46|警告:函数中没有返回语句返回非 void|

那么,有什么建议吗?

【问题讨论】:

  • 尝试将其更改为 volatile。根据docsasm 可以是__asm__,但我认为 volatile 应该是volatile
  • 在那之后,当我认为它应该是一个输入时,你指定'n'是一个输出。而且那个破坏者名单很奇怪。
  • GCC 的内联是一个复杂的野兽,使用 x87 浮点约束更加困难。您必须阅读内联汇编使用手册。这可能会成功double raiz (double n) { __asm__ ("fsqrt" : "+t"(n)); return n; }
  • 内联汇编是必需的吗?为什么不以真正的组装开始(并以)结束?

标签: assembly x86 g++ inline-assembly x87


【解决方案1】:

intel2gas 显然没有实现 MSVC 对在 asm 中的 EAX(或 ST0)中保留返回值然后从非void 函数的末尾脱落的支持。即使在内联包含__asm 块的函数时,MSVC 也会将此视为实际返回值。在 GNU C 内联汇编中,只有在使用输出或读/写约束时,寄存器值才是输出。

这就是为什么您会收到 warning: no return statement in function returning non-void 和损坏的代码。

正如@MichaelPetch 指出的那样,您应该使用t 约束(x87 堆栈顶部)向编译器询问 x87 FP 寄存器堆栈上的输入浮点数。

double raiz (double n) {
    __asm__ ("fsqrt"
       : "+t"(n)          // read-write operand: top of x87 stack
    );
     return n;
}

asm volatile 不需要:即使输出未使用,asm 块也没有需要运行的副作用,并且输出是输入的纯函数。 (除非您要更改 x87 舍入模式或精度)。

可以让编译器优化掉它,或者在它的多次运行之间进行 CSE。

作为一个独立的函数,它将 (on Godbolt) 编译为

# gcc8.2 -O3 -ffast-math -m32   uses x87 by default, not SSE2
_Z4raizd:
    fld     QWORD PTR [esp+4]
   # start of inline asm
    fsqrt
   # end of inline asm.
    ret

【讨论】:

    猜你喜欢
    • 2013-01-22
    • 1970-01-01
    • 1970-01-01
    • 2019-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-01
    • 1970-01-01
    相关资源
    最近更新 更多