Не работает синус, ассемблер, код на си
Написала программу, не вычисляется синус. Нигде не смогла найти нормальное описание правил синтаксиса
#include <stdio.h>
#include<math.h>
#include <locale>
#include<malloc.h>
#include<stdlib.h>
int main() {
float r, u, x, y;
float a = -1;
printf("Print X, Y:\n");
if (!(scanf("%f %f", &x, &y))) //ввод Х и У + проверка на правильный ввод данных: если не читаются числа, выдает ошибку
{
printf("Error.Try again"); //вывод ошибки
} else {
//определяем и инициализируем указатели
float *X = &x; // в asm(1) будет %1
float *Y = &y; // в asm(1) будет %2
float *R = &r; // в asm(1) будет %0
float *U = &u; // в asm(2) будет %0
float *A = &a; // в asm(2) будет %0
asm // решаем алгоритм r=sqrt(x*x+y*y);
(
".intel_syntax noprefix \n\t" //синтаксис Intel, допускается опускание % перед именами регистров
"movss xmm1, [%2] \n\t" //Заносим данные в регистр (х)
"movss xmm2, [%2] \n\t" //Заносим данные в регистр (х)
"mulss xmm1, xmm2 \n\t" //Умножаем х*х
"movss xmm3, [%3] \n\t" //Заносим данные в регистр (y)
"movss xmm2, [%3] \n\t" //Заносим данные в регистр (y)
"mulss xmm2, xmm3 \n\t" //Умножаем y*y
"addss xmm1, xmm2 \n\t" //Суммируем х*х и y*y
"sqrtss xmm1, xmm1 \n\t" // ax,ax //Квадратный корень из (х*х+y*y)
"movss [%0], xmm1 \n\t" //Вывод данных из регистра
:"=r"(R) //возвращаемые данные(выходные операнды),нумеруются с нуля
:"r"(R), "r"(X), "r"(Y) //Входные данные(продолжение нумерации)
:"%xmm1", "%xmm2", "%xmm3" //Разрушение регистров
);
//r=sqrt(x*x+y*y);
if (r == 0) //условие, если r=0 - радиус, одна из компонентов полярной системы координат
{
U = 0;
printf("R=%f\n", r);
printf("U=%f\n", u);
};
//U=asin(y/r);
asm // решаем алгоритм asin(y/r);;
(
".intel_syntax noprefix \n\t" //синтаксис Intel, допускается опускание % перед именами регистров
"movss xmm1, [%3] \n\t" //Заносим данные в регистр (y)
"movss xmm2, [%2] \n\t" //Заносим данные в регистр (R) = r из условия выше
"divss xmm1, xmm2 \n\t" // Делим у на r
"fsin \n\t" // cx, ax //Sin (y/r)
"movss [%0],xmm1 \n\t" //cx //Вывод данных из регистра
:"=r"(U) //возвращаемые данные(выходные операнды),нумеруются с нуля
:"r"(U), "r"(R), "r"(Y) //Входные данные(продолжение нумерации)
:"%xmm1", "%xmm2", "%xmm3" //Разрушение регистров
);
if ((x < 0) && (y >= 0)) {
asm // решаем алгоритм U=M_PI-U (доп. условия с учетом четвертей тригонометрии)
(
".intel_syntax noprefix \n\t" //синтаксис Intel, допускается опускание % перед именами регистров
"movss xmm1, [%2] \n\t" //Заносим данные в регистр (M_PI) - число pi
"movss xmm2, [%1] \n\t" //Заносим данные в регистр (u)
"subss xmm1, xmm2 \n\t" //Вычитаем U из M_PI
"movss [%0], xmm1 \n\t" //Вывод данных из регистра
:"=r"(U) //возвращаемые данные(выходные операнды),нумеруются с нуля
:"r"(U), "r"(M_PI) //Входные данные(продолжение нумерации)
:"%xmm1", "%xmm2" //Разрушение регистров
);
} else if ((x < 0) && (y < 0)) {
asm // решаем алгоритм U=(-1)*M_PI-U (доп. условия с учетом четвертей тригонометрии)
(
".intel_syntax noprefix \n\t" //синтаксис Intel, допускается опускание % перед именами регистров
"movss xmm1, [%2] \n\t" //Заносим данные в регистр (M_PI) - число pi
"movss xmm2, [%3] \n\t" //Заносим данные в регистр (a=-1)
"mulss xmm1, xmm2 \n\t" //Умножаем a на M_PI
"movss xmm2, [%1] \n\t" //Заносим данные в регистр (u)
"subss xmm1, xmm2 \n\t" //Вычитаем из -M_PI U
"movss [%0], xmm1 \n\t" //Вывод данных из регистра
:"=r"(U) //возвращаемые данные(выходные операнды),нумеруются с нуля
:"r"(U), "r"(M_PI), "r"(A) //Входные данные(продолжение нумерации)
:"%xmm1", "%xmm2" //Разрушение регистров
);
};
printf("R=%f\n", r); //вывод значений
printf("U=%f\n", u); //вывод значений
}
}
Ответы (2 шт):
Автор решения: Илья К
→ Ссылка
Перед командой fsin, нужно перебросить значение из регистра xmm2 в стек FPU.
Автор решения: PRODIGY
→ Ссылка
Нигде не смогла найти нормальное описание правил синтаксиса
Непонятно, зачем здесь использовать инструкции SSE, если они не предназначены для тригонометрии? Загружайте свои значения сразу в сопр.FPU и производите вычисления в нём. Вот пример на ассемблере fasm:
;// Решаем алгоритм: R = sqrt(x*x+y*y)
fld [Y]
fmul st0,st0 ;// y*y
fld [X]
fmul st0,st0 ;// x*x
fadd st0,st1 ;// x+y
fsqrt ;// sqrt(x*x+y*y)
fstp [R] ;// R = результат
;// Решаем алгоритм: U = sin(Y/R)
fld [Y]
fdiv [R] ;// y/R
fsin ;// sin(Y/R)
fstp [U] ;// U = результат
finit ;// Очистить стек FPU