Не работает асемблерная вставка в C
Задача состоит в том, что бы найти обратную матрицу, размерность матрицы постоянная 3х3, необходимо для вычислений использовать асемблерную вставку. Код работает до момента асемблерной вставки. Пример работы программы:
Компилятор gcc, работаю на Astra Linux. Использую makefile, вот его содержимое:
main.0: L1snova1.c
gcc -masm=intel L1snova1.c -lm
./a.out
Сам код:
#include<stdio.h>
#include<time.h>
#include<math.h>
#include<locale.h>
#include<malloc.h>
#include<stdlib.h>
#include <stdint.h> /*типы данных с гарантируемо известным занимаемым размером в памяти*/
#define scanf_s scanf // была ошибка undefined reference to scanf_s
#include <stdint.h> /*типы данных с гарантируемо известным занимаемым размером в памяти*/
int main()
{
const int n=3;
double det;
//double tm; // переменная для хранение значения массива
//double om;
// Определяем и инициализируем указатели
// double *N = &n;
double *D = &det; // указатель на определитель
//////////////////////
// выделение памяти //
//////////////////////
double **matr; // для матрицы
matr = (double**) malloc(n*sizeof(double*));
for (int i=0; i<n; ++i)
matr[i] = (double*) malloc(n*sizeof(double));
if (NULL == matr) {
printf("Память не выделилась для matr\n");
exit(1);
}
// *для матрцы миноров* //
double **min; // для матрицы
min = (double**) malloc(n*sizeof(double*));
for (int i=0; i<n; ++i)
min[i] = (double*) malloc(n*sizeof(double));
if (NULL == min) {
printf("Память не выделилась для min\n");
exit(1);
}
// *для матрицы алгебраических дополнений* //
double **algdop; // для матрицы
algdop = (double**) malloc(n*sizeof(double*));
for (int i=0; i<n; ++i)
algdop[i] = (double*) malloc(n*sizeof(double));
if (NULL == algdop) {
printf("Память не выделилась для algdop\n");
exit(1);
}
// *для транспонированной матрицы * //
double **tmatr; // для матрицы
tmatr = (double**) malloc(n*sizeof(double*));
for (int i=0; i<n; ++i)
tmatr[i] = (double*) malloc(n*sizeof(double));
if (NULL == tmatr) {
printf("Память не выделилась для tmatr\n");
exit(1);
}
// *для обратной матрицы * //
double **obr_matr; // для матрицы
obr_matr = (double**) malloc(n*sizeof(double*));
for (int i=0; i<n; ++i)
obr_matr[i] = (double*) malloc(n*sizeof(double));
if (NULL == obr_matr) {
printf("Память не выделилась для obr_matr\n");
exit(1);
}
int i,j;
//double *M =&tmatr[i][j];
double *M = &tmatr[i][j];
double *O = &obr_matr[i][j];
////////////////////////
// заполнение матрицы //
////////////////////////
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
printf("a[%d][%d] = ", i+1, j+1);
// scanf_s("%lf", &matr[i][j]);
if (!scanf("%lf", &matr[i][j])){ fflush(stdin); printf("Ошибка ввода! Нужно писать числа!!!\n"); return 0;}
}
}
/////////////////////////////
// вывод введенной матрицы //
/////////////////////////////
printf("Введенная матрица:\n");
for (int i = 0; i < n; i++) { // проходим по строкам
for (int j = 0; j < n; j++) { // проходим по столбцам
printf("%g ", matr[i][j]);
// printf("\n");
}
printf("\n");
}
/////////////////////////////
// нахождение определителя //
/////////////////////////////
det = matr[0][0]*matr[1][1]*matr[2][2] + matr[0][1]*matr[1][2]*matr[2][0]
+ matr[1][0]*matr[2][1]*matr[0][2] - matr[2][0]*matr[1][1]*matr[0][2] -
matr[2][1]*matr[1][2]*matr[0][0] - matr[1][0]*matr[0][1]*matr[2][2];
printf("Определитель матрицы = %lf\n", det);
if (det==0) {
printf("Так как определитель матрицы = 0,\nматрица вырожденная и обратной не имееет\n");
return 0;
}
//////////////////////////
// нахождение миноров //
/////////////////////////
//////////////////
// 0 1 2 //
//0 - [1][2][3] //
//1 - [4][5][6] //
//2 - [7][8][9] //
//////////////////
min[0][0]= matr[1][1] * matr[2][2] - matr[2][1] * matr[1][2];
min[0][1]= matr[1][0] * matr[2][2] - matr[1][2] * matr[2][0];
min[0][2]= matr[1][0] * matr[2][1] - matr[2][0] * matr[1][1];
min[1][0]= matr[0][1] * matr[2][2] - matr[2][1] * matr[0][2];
min[1][1]= matr[0][0] * matr[2][2] - matr[2][0] * matr[0][2];
min[1][2]= matr[0][0] * matr[2][1] - matr[2][0] * matr[0][1];
min[2][0]= matr[0][1] * matr[1][2] - matr[1][1] * matr[0][2];
min[2][1]= matr[0][0] * matr[1][2] - matr[1][0] * matr[0][2];
min[2][2]= matr[0][0] * matr[1][1] - matr[1][0] * matr[0][1];
// printf("Минор первого элемента матрицы = %lf\n", min[0][0]); // проверял правильность расчетов
// printf("Минор второго элемента матрицы = %lf\n", min[0][1]); //
// *матрица алгебраических дополнений* //
for (int i = 0; i < n; i++){
for (int j = 0; j < n; j++) {
int k; // степень
k=i+j;
algdop[i][j]= pow(-1.0, k) * min[i][j]; // матрица алгелраических дополнений
}
}
// *вывод матрицы алгебраических дополнений* //
printf("Матрица алгебраических дополнений:\n");
for (int i = 0; i < n; i++) { // проходим по строкам
for (int j = 0; j < n; j++) { // проходим по столбцам
printf("%g ", algdop[i][j]);
// printf("\n");
}
printf("\n");
}
// *Транспонируем матрицу* //
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
tmatr[j][i] = algdop[i][j];
// *вывод транспонированной матрицы* //
printf("Транспонированная матрица :\n");
for (int i = 0; i < n; i++) { // проходим по строкам
for (int j = 0; j < n; j++) { // проходим по столбцам
printf("%g ", tmatr[i][j]); //
// printf("\n");
}
printf("\n");
}
///////////////////////////////////////////
// и наконец-то обратная матрицааааааааа //
///////////////////////////////////////////
for (int i = 0; i < n; i++){ // цикл для нахождения обратной матрицы
for (int j = 0; j < n; j++) {
asm //
(
".intel_syntax noprefix\n" /*Синтаксис Intel, допускается опускать % перед именами регистров*/
"movss xmm1, [%1] \n\t" // Заносим данные в регистр (Элемент матрицы)
"movss xmm0, [%2] \n\t" // Заносим данные в регистр (определитель)
"divss xmm1, xmm0 \n\t" // Делим (Элемент/определитель)
"movss [%0], xmm1 \n\t" // Вывод данных из регистра (otv)
: "=r"(O) // Возвращаемые данные
: "r"(M), "r"(D) // Входные данные
: "%xmm0", "%xmm1" // Разрушаемые регистры
);
/////////////////
/////////////////
printf("%g ", obr_matr[i][j]);
}
printf(" \n");
}
/////////////////////////
// освобождение памяти //
/////////////////////////
for (int i=0; i<n; ++i) {
free (matr[i]);
free (matr);
}
// *для матрицы миноров* //
for (int i=0; i<n; ++i) {
free (min[i]);
free (min);
}
// *для матрицы алгебраических дополнений* //
for (int i=0; i<n; ++i) {
free (algdop[i]);
free (algdop);
}
// *для транспонированной матрицы * //
for (int i=0; i<n; ++i) {
free (tmatr[i]);
free (tmatr);
}
// *для обратной матрицы * //
for (int i=0; i<n; ++i) {
free (obr_matr[i]);
free (obr_matr);
}
return 0;
}
