Search code examples
c++assemblymasmfpu

FPU trigonometry functions calls from C++


I'm trying to use FPU with masm under VS2013 (Win10 x64) to get sine and cosine. The header is:

#pragma once

extern "C" double fpu_sincos(const double a_d_angle, double& a_sin, double& a_cos);

extern "C" double fpu_sin(const double a_d_angle);

extern "C" double fpu_cos(const double a_d_angle);

These functions get called from regular Visual C++ code. While the first function works properly and I DO get corrent values via parameters by reference, but the other two functions give bad results. The .asm file contains:

    PUBLIC  fpu_sincos
    PUBLIC  fpu_sin
    PUBLIC  fpu_cos

    _TEXT   SEGMENT
    a$ = 32
    fpu_sincos PROC
        movsd   QWORD PTR [rsp+8], xmm0
        sub rsp, 24
        fld QWORD PTR a$[rsp]
        fsincos
        fstp QWORD PTR [r8]
        fstp QWORD PTR [rdx]
        add rsp, 24
        ret 0
    fpu_sincos ENDP
    _TEXT   ENDS

    _TEXT   SEGMENT
    a$ = 8
    fpu_sin PROC
        movsd   xmm0, QWORD PTR a$[rsp]
        fld QWORD PTR a$[rsp]
        fsin
        fstp QWORD PTR a$[rsp]
        movq    xmm0, QWORD PTR a$[rsp]
        ret 0
    fpu_sin ENDP
    _TEXT   ENDS

    _TEXT   SEGMENT
    a$ = 8
    fpu_cos PROC
        movsd   xmm0, QWORD PTR a$[rsp]
        fld QWORD PTR a$[rsp]
        fcos
        fstp QWORD PTR a$[rsp]
        movq    xmm0, QWORD PTR a$[rsp]
        ret 0
    fpu_cos ENDP
    _TEXT   ENDS

    END

I've spent some time fighting with the issue, but I'm not familiar with Assembly language so I couldn't have won :/ Need some help! And it would be great if someone explained it line by line.

Thanks.


Solution

  • The operands for storing xmm0 are in the wrong order.

    Change both

    movsd   xmm0, QWORD PTR a$[rsp]
    

    to

    movsd   QWORD PTR a$[rsp], xmm0