You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用GCC/Clang内联汇编调用x87的FSIN实现double类型sin函数

使用x87 FSIN指令实现自定义sin函数(GCC/Clang)

如果需要绕过标准库sin函数,直接用x87的FSIN硬件指令实现正弦计算,可以通过GCC/Clang的内联汇编完成。以下是具体实现:

基础实现(无范围调整)

double my_sin(double x) {
    double result;
    __asm__ __volatile__ (
        "fldl %1\n"          // 将输入double加载到x87浮点栈顶
        "fsin\n"             // 执行x87正弦运算,结果保留在栈顶
        "fstpl %0\n"         // 将栈顶结果存入result变量
        : "=m" (result)      // 输出约束:result为内存变量
        : "m" (x)            // 输入约束:x为内存变量
        : "st(0)"            // 告知编译器x87栈顶寄存器被修改
    );
    return result;
}

带范围调整的优化版本

FSIN指令对输入角度的最佳范围是**[-π, π]**,超出该范围会导致精度下降。因此建议先对输入做模2π的调整,保证计算精度:

#include <math.h>

double my_sin(double x) {
    // 将输入角度调整到[-π, π]区间
    x = fmod(x, 2 * M_PI);
    if (x > M_PI) {
        x -= 2 * M_PI;
    } else if (x < -M_PI) {
        x += 2 * M_PI;
    }

    double result;
    __asm__ __volatile__ (
        "fldl %1\n"
        "fsin\n"
        "fstpl %0\n"
        : "=m" (result)
        : "m" (x)
        : "st(0)"
    );
    return result;
}

关键细节说明

  • __volatile__:防止编译器因优化省略这段汇编代码,确保指令一定会被执行。
  • 内存约束"m":直接操作内存中的变量,避免寄存器分配可能带来的冲突,适配x87指令的浮点栈操作逻辑。
  • 寄存器破坏声明:"st(0)"告诉编译器x87的栈顶寄存器被修改,避免编译器在汇编块前后对该寄存器的非法复用。
  • 精度差异:硬件FSIN的精度在最佳范围内接近标准库,但全范围精度不如标准库的软件实现(标准库通常用泰勒级数、CORDIC等算法优化),需根据需求权衡使用。

内容的提问来源于stack exchange,提问作者Edison von Myosotis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 07:43:32