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

如何在x87与SSE寄存器间直接传输数据?附加载异常排查

x87 FPU与SSE寄存器直接数据传输及相关问题解决

一、跳过内存中转的寄存器直接传输方法

要在x87 FPU寄存器(如st(0))和SSE寄存器(如xmm1)之间直接传输双精度浮点数,无需借助临时内存变量,直接使用以下指令即可:

  • x87 → SSE:用fstpd %xmm1,这条指令会把st(0)中的双精度值直接写入xmm1寄存器的低64位,完成从x87到SSE的直接传输。
  • SSE → x87:若需要反向传输,使用ldsd %xmm1, %st(0),将xmm1低64位的双精度值加载到st(0)中。

结合你的三角函数计算场景,修改后可直接把fsin的结果从st(0)写入xmm1,省去临时内存中转步骤。

二、解决fld加载失败和fsin结果异常的问题

问题根源

  1. val的定义错误:GAS汇编里,.double后面必须写浮点格式的数值(比如90.0),如果只写90,汇编器会把它当作整数处理,转成双精度后的值并非预期的90.0,导致fld加载到st(0)的是错误值(甚至是0)。
  2. fsin的弧度制要求:x87的fsin指令计算的是弧度值的正弦,不是角度值。90度对应的弧度是π/2(约1.5708),直接传入90(弧度)的话,结果并不是1。

修正后的完整代码

.section .data
    outfloatfmt: .asciz "%lf\n"
    val: .double 1.5707963267948966  # π/2的近似值,对应90度
    sinres: .double 0
.section .text
    .extern printf
    .global main
main:
    pushq %rbp
    movq %rsp, %rbp
    fld val(%rip)               # 加载正确的弧度值到st(0)
    fsin                        # 计算正弦,结果存在st(0)
    fstpd %xmm1                 # 直接把st(0)的值写入xmm1,跳过内存中转
    movsd %xmm1, sinres(%rip)   # 将xmm1的值存入目标内存

    # 打印结果
    movsd sinres(%rip), %xmm0
    leaq outfloatfmt(%rip), %rdi
    movq $1, %rax
    callq printf

    movq %rbp, %rsp
    popq %rbp
    ret

内容的提问来源于stack exchange,提问作者TheSinisterStone

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 07:40:32