gpt4 book ai didi

assembly - 组装x86中的Sqrt

转载 作者:行者123 更新时间:2023-12-02 10:49:13 24 4
gpt4 key购买 nike

我在网上找到了一些建议。

  • C Inline assembly - Operand type mismatch for 'fst'
  • Why am I getting these assembler errors?
  • Why will I have operand type mismatch error when compiling the assembly codes with gcc?

  • 我有一个类似的问题,但是所有建议都没有帮助(或者我没有根据我的程序正确弄清楚如何实现它们)。

    该代码作为 asm(...)插入到C程序中。

    使用 -masm=intel编译后,使用时:
    asm ("FLD EBX \n" "FSQRT \n" "FST EBX \n").

    我收到编译错误:

    “错误:'fld'的操作数类型不匹配”
    “...'fst'不匹配”。

    在这些命令之前,EBX持有一些整数正值。

    那么获取ebx = sqrt(ebx)的正确方法是什么?

    最佳答案

    您应该在现代代码中将SSE/SSE2用于sqrt,而不是x87。您可以使用一条指令将gp寄存器中的整数直接转换为xmm寄存器中的double。

    cvtsi2sd  xmm0, ebx
    sqrtsd xmm0, xmm0 ; sd means scalar double, as opposed to SIMD packed double
    cvttsd2si ebx, xmm0 ; convert with truncation (C-style cast)

    ; cvtsd2si ecx, xmm0 ; rounded to nearest integer (or whatever the current rounding mode is)

    这也适用于64位整数( rbx),但是请注意 double只能精确表示最大约2 ^ 53(尾数大小)的整数。如果要检查整数是否是理想的平方,可以使用float sqrt,然后对整数结果进行尝试乘法。 ( (a*a) == b)

    请参阅 以获取指南,教程和手册的链接。

    请注意,将此代码插入C程序的中间是完全错误的方法。 GNU C内联汇编是执行汇编的最困难的方法,因为您必须真正了解所有内容才能正确地执行约束。弄错它们可能导致其他周围的代码以微妙且难以调试的方式破坏,而不仅仅是您在处理内联汇编错误时所做的事情。有关更多信息,请参见x86标签Wiki。

    如果需要 int a = sqrt((int)b),则将其写入代码中,然后让编译器为您生成这三个指令。一定要阅读并理解编译器的输出,但不要仅仅使用 asm("")盲目地将其序列放入中间。

    例如。:
    #include <math.h>
    int isqrt(int a) { return sqrt(a); }

    compiles to(不带-ffast-math的gcc 5.3):
        pxor    xmm0, xmm0      # D.2569
    cvtsi2sd xmm0, edi # D.2569, a
    sqrtsd xmm1, xmm0 # tmp92, D.2569
    ucomisd xmm1, xmm1 # tmp92, tmp92
    jp .L7 #,
    cvttsd2si eax, xmm1 # D.2570, tmp92
    ret
    .L7:
    sub rsp, 8 #,
    call sqrt #
    add rsp, 8 #,
    cvttsd2si eax, xmm0 # D.2570, tmp92
    ret

    我猜 sqrt()必须在某些类型的错误上设置errno。 :/

    -fno-math-errno:
        pxor    xmm0, xmm0      # D.2569
    cvtsi2sd xmm0, edi # D.2569, a
    sqrtsd xmm0, xmm0 # tmp92, D.2569
    cvttsd2si eax, xmm0 # D.2570, tmp92
    ret
    pxor旨在打破对xmm0先前内容的错误依赖,因为 cvtsi2sd做出了奇怪的设计决定,即不修改dest vector reg的上半部分。仅在要将转换结果插入到现有 vector 中时才有用,但是已经有 cvtdq2pd进行打包转换。 (而且他们可能没有考虑64位整数,因为当Intel发布SSE2时AMD64仍处于起步阶段)。

    关于assembly - 组装x86中的Sqrt,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35747811/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com