Вызовы тригонометрических функций FPU из C++

Я пытаюсь использовать FPU с masm под VS2013 (Win10 x64), чтобы получить синус и косинус. Заголовок:

#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);

Эти функции вызываются из обычного кода Visual C++. В то время как первая функция работает правильно, и я ДЕЙСТВИТЕЛЬНО получаю правильные значения через параметры по ссылке, но две другие функции дают плохие результаты. Файл .asm содержит:

    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

Я потратил некоторое время на борьбу с этой проблемой, но я не знаком с языком ассемблера, поэтому я не смог победить :/ Нужна помощь! И было бы здорово, если бы кто-нибудь объяснил это построчно.

Спасибо.


person Andrey Lyubimov    schedule 22.10.2015    source источник
comment
Вы объявляете функции extern "C" , но объявляете аргументы как ссылки, которых нет в C. Этого не может быть, не так ли?   -  person eerorika    schedule 22.10.2015
comment
@ user2079303 ну, это действительно работает   -  person Andrey Lyubimov    schedule 22.10.2015
comment
Я почти уверен, что поведение не определено стандартом. Если в документации вашего компилятора на вашей платформе сказано, что это нормально, то я думаю, что это нормально, если вы никогда не используете другой компилятор или платформу, где это не нормально. Чего, я думаю, вы не сделаете, так как используете masm.   -  person eerorika    schedule 22.10.2015
comment
@ user2079303 Хорошо, спасибо. Давайте теперь забудем о функции sincos() тогда :)   -  person Andrey Lyubimov    schedule 22.10.2015


Ответы (1)


Операнды для хранения xmm0 расположены в неправильном порядке.

Изменить оба

movsd   xmm0, QWORD PTR a$[rsp]

to

movsd   QWORD PTR a$[rsp], xmm0
person rkhb    schedule 22.10.2015