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

SIMD编程:addps浮点向量加法结果异常,求排查与修复

SIMD addps指令使用异常问题排查与修复

问题背景

正在学习SIMD指令,目标是用addps实现两个4元素float向量的对应元素相加,结果存入result向量。使用movaps加载向量到XMM寄存器后,执行结果输出异常,但用movlpd逐个加载元素能正确显示向量a、b的值,且C内嵌汇编复现该操作时结果正常。

汇编代码

section .data
    a dd 1.1f, 2.2f, 3.3f, 4.4f
    b dd 0.4f, 0.5f, 0.6f, 0.7f
    result dd 0.0f, 0.0f, 0.0f, 0.0f
    format db "Content = {%.1f, %.1f, %.1f, %.1f}", 10, 0
    formatResult db "Result = {%.1f, %.1f, %.1f, %.1f}", 10, 0

section .text
    global _start

_start:
    movaps xmm0, [a]
    movaps xmm1, [b]

    addps xmm0, xmm1

    movaps [result], xmm0

    mov rdi, formatResult
    movaps xmm0, [result]
    call printf

    mov eax, 60
    syscall

section .externals
    extern printf

编译执行命令

nasm -f elf64 -o file.o file.asm
gcc -nostartfiles -o file file.o -no-pie
./file

错误输出

Content = {1.1, 2.2, 3.3, 4.4}
Content = {0.4, 0.5, 0.6, 0.7}
Result = {172.8, 0.4, 0.0, 0.0}

问题原因

错误根源在于调用printf时违反了x86-64 System V ABI规范:

  1. 浮点参数类型提升:C标准中,变参函数(如printf)接收float参数时会自动将其提升为double类型。直接传递32位float会导致printf把XMM寄存器中64位的垃圾数据当成double解析,出现异常值。
  2. 参数传递方式错误:x86-64 System V ABI规定,变参函数的浮点参数需依次放入XMM0~XMM7寄存器,每个寄存器对应一个参数。你将4个float打包到单个XMM0寄存器,printf只会读取XMM0的低64位(且错误解析为double),剩余参数未正确传递,导致读取栈上垃圾数据。

而内嵌汇编正常的原因是:C编译器自动处理了float到double的类型提升,以及参数的寄存器分配,符合ABI规范。

修复方案

修改printf调用前的参数准备逻辑,将result中的每个float转换为double,并分别放入对应XMM寄存器:

_start:
    movaps xmm0, [a]
    movaps xmm1, [b]

    addps xmm0, xmm1

    movaps [result], xmm0

    ; 准备printf参数
    mov rdi, formatResult
    ; 提取每个float并转换为double,放入对应XMM寄存器
    movss xmm0, [result]        ; 加载第一个float到XMM0低32位
    cvtss2sd xmm0, xmm0         ; 转换为double
    movss xmm1, [result+4]      ; 第二个float(每个float占4字节)
    cvtss2sd xmm1, xmm1
    movss xmm2, [result+8]
    cvtss2sd xmm2, xmm2
    movss xmm3, [result+12]
    cvtss2sd xmm3, xmm3
    call printf

    mov eax, 60
    syscall

若想验证addps的计算结果本身是否正确,可通过gdb查看XMM寄存器的值,确认向量相加逻辑无误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 08:41:11