将 xmm floating-point 寄存器截断为 64 位寄存器

Truncating an xmm floating-point register to a 64-bit register

我想将 xmm 寄存器之一中的 floating-point 数字截断为 64 位寄存器,如标题所述。下面我将 15.9 除以 4.95。我正在打印它,我看到结果是正确的 (3.212121)。但是,当使用 cvtss2si 截断它时,rdi 以某种方式变为零。我不知道为什么。当我期望结果为 3 时,为什么这不能正确截断?我在 macOS 上用 Clang 组装。

    .global _main
    .text

_main:
    movsd xmm0, qword ptr [dividend + rip]
    divsd xmm0, qword ptr [divisor + rip]
    movsd [result + rip], xmm0

    lea rdi, [frm + rip]
    movsd xmm0, qword ptr [result + rip]
    mov al, 1
    and rsp, -16
    call _printf

    cvtss2si rdi, xmm0  # expecting 3, is 0
    mov rax, 0x2000001
    syscall

    .data
dividend:
    .quad 15.9
divisor:
    .quad 4.95
result:
    .quad 0.0
frm:
    .asciz "%f\n"

ss 是标量 单精度 。您正在转换 double 的尾数的低 32 位。作为 binary32 位模式,表示一个小数字或正好为零。此外,如果您想 truncate 而不是四舍五入到最接近的值,请使用截断转换(一个额外的 t)。 cvttsd2si rdi, xmm0 https://www.felixcloutier.com/x86/cvttsd2si.

当然,xmm 寄存器在 x86-64 系统 V 中被调用破坏,因此在 printf returns.

之后立即读取 XMM0 是没有意义的