24
Ноя
2021

Не работает асемблерная вставка в 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;        
}

Источник: https://ru.stackoverflow.com/questions/1353468/%D0%9D%D0%B5-%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D0%B0%D0%B5%D1%82-%D0%B0%D1%81%D0%B5%D0%BC%D0%B1%D0%BB%D0%B5%D1%80%D0%BD%D0%B0%D1%8F-%D0%B2%D1%81%D1%82%D0%B0%D0%B2%D0%BA%D0%B0-%D0%B2-c

Тебе может это понравится...

Добавить комментарий