Multiplicação de Matriz [C/C++ com Assembly ]

1. Multiplicação de Matriz [C/C++ com Assembly ]

Cesar Soares Stenico
cesarsst

(usa Ubuntu)

Enviado em 24/06/2017 - 12:15h

Estou tentando realizar um programa que realize a multiplicaçao de matrizes (mais especificamente 3 matrizes (B x A x 2C) ) e preciso realizar essa operação tanto em C, quanto em Assembly (2 funções - uma em GAS e outra em NASM). Em C sem problemas, está rodando perfeito, porém quando tento realizar a copilação (usando o gcc) está dando falha de segmentação. Vari o codigo varias vezes e realmente não acho onde pode estar o problema (ou se a logica utilizada está errada). Segue o codigo abaixo:

Detalhe: Para realizar a "coleta" das areas da matriz (como só pode ser representado em vetor em assembly), estou usando a seguinte logica:

X = L x i + j
Onde,
L = ordem da matriz quadrada;
i = linha desejada da matriz e,
j = coluna desejada da matriz.

Como estamos representando uma matriz com números inteiros, multiplicamos o resultado desse cálculo por 4, pois um número inteiro possui 4 bytes. (pode ser observado no codigo em GAS essa logica).


#include <stdio.h>


const int L = 5;

void multMatrixN(int m1[L][L], int m2[L][L], int r[L][L], int L);
void multMatrixG(int m1[L][L], int m2[L][L], int r[L][L], int L);
void multMatrixC(int m1[L][L], int m2[L][L], int r[L][L]);
void printMatrix(int m[L][L]);
void doubleMatrix(int m[L][L]);
int smallestMatrix(int m[L][L]);

void main(void){
int a[L][L], b[L][L], c[L][L], r[L][L], aux[L][L];
int i, j;

for(i=0; i<L; i++){ // INICIALIZAÇÃO DAS MATRIZES
for(j=0; j<L; j++){
a[i][j] = 2*i+1;
b[i][j] = 2*j+1;
c[i][j] = i*j+1;
r[i][j] = 0;
}
}

doubleMatrix(c);

multMatrixG(a,b,aux,L);
//multMatrixN(aux,c,r,L);


/*
printf("\n\n\t MATRIZ A\n\t");
printMatrix(a);

printf("\n\t MATRIZ B\n\t");
printMatrix(b);

printf("\n\t MATRIZ 2C\n\t");
doubleMatrix(c);
printMatrix(c);

multMatrix(a, b, aux);
multMatrix(aux, c, r);
*/
printf("\n\n\t MATRIZ RESULTADO\n\t");
printMatrix(r);

printf("\n\n\tO menor valor da diagonal principal é %d", smallestMatrix(r));
}

//Função que realiza multiplicação em NASM
/*
void multMatrixN(int m1[L][L], int m2[L][L], int r[L][L], int L){

asm("SECTION .data");
asm("i: db 0");
asm("j: db 0");
asm("k: db 0");
asm("soma: db 0");

asm("SECTION .text");
asm("global start");
asm("_start:");

asm(" mov edi, [ebp+12]"); //M2
asm(" mov esi, [ebp+8]"); //M1

asm(" forIloop:");
asm(" forJloop:");
asm(" mov soma, 0");
asm(" forKloop:");
asm(" mov eax, [ebp+20]"); // Calculo do endereco para m1
asm(" mov ebx, i");
asm(" mul bl");
asm(" add eax, k");
asm(" sal eax, 2");
asm(" mov ecx, eax"); // ecx = (L*i + k)*4

asm(" mov eax, [ebp+20]"); // Calculo do endereco para m2
asm(" mov ebx, k");
asm(" mul bl");
asm(" add eax, j");
asm(" sal eax, 2");
asm(" mov edx, eax"); // edx = (L*k + j)*4

asm(" mov eax, [esi+ecx]"); // Calculo da multiplicacao
asm(" mov ebx, [edi+edx]");
asm(" mul ebx");
asm(" add soma, eax");

asm(" inc k");

asm(" forKcond:");
asm(" cmp k,[ebp+20]");
asm(" jne forKloop");

asm(" mov eax, [ebp+20]"); // Calculo do endereco para r
asm(" mov ebx, i");
asm(" mul bl");
asm(" add eax, j");
asm(" sal eax, 2");
asm(" mov ecx, eax"); // ecx = (L*i + j)*4

asm(" mov ebx,[ebp+16]");
asm(" mov [ebx+ecx], soma");

asm(" inc j");

asm(" forJcond:");
asm(" cmp j, [ebp+20]");
asm(" jne forJloop");

asm(" inc i");
asm(" forIcond:");
asm(" cmp i, [ebp+20]");
asm(" jne forIloop");

}*/

//Função que realiza multiplicação em GAS
void multMatrixG(int m1[L][L], int m2[L][L], int r[L][L], int L){

asm(".data");
asm("i: .byte 0");
asm("j: .byte 0");
asm("k: .byte 0");
asm("soma: .int 0");

asm(".text");

asm(" movl 12(%ebp), %edi"); //M2
asm(" movl 8(%ebp), %esi"); //M1

asm(" movl 20(%ebp), %eax");
asm(" movl %eax, i");

asm(" forIloop:");
asm(" decl i");
asm(" movl 20(%ebp), %eax");
asm(" movl %eax, j");
asm(" forJloop:");
asm(" decl j");
asm(" movl $0, soma");
asm(" movl 20(%ebp), %eax");
asm(" movl %eax, k");
asm(" forKloop:");
asm(" decl k");
asm(" movl 20(%ebp), %eax"); // Calculo do endereco para m1
asm(" movl i, %ebx");
asm(" mull %ebx");
asm(" addl k, %eax");
asm(" sall $2, %eax");
asm(" movl %eax, %ecx"); // ecx = (L*i + k)*4

asm(" movl 20(%ebp), %eax"); // Calculo do endereco para m2
asm(" movl k, %ebx");
asm(" mull %ebx");
asm(" addl j, %eax");
asm(" sall $2, %eax");
asm(" movl %eax, %edx"); // edx = (L*k + j)*4

asm(" movl (%esi,%ecx),%eax"); // Calculo da multiplicacao
asm(" movl (%edi,%edx),%ebx");
asm(" mull %ebx");
asm(" addl %eax, soma");

asm(" forKcond:");
asm(" cmpl $0, k");
asm(" jne forKloop");

asm(" movl 20(%ebp), %eax"); // Calculo do endereco para r
asm(" movl i, %ebx");
asm(" mull %ebx");
asm(" addl j, %eax");
asm(" sall $2, %eax ");
asm(" movl %eax, %ecx"); // ecx = (L*i + j)*4

asm(" movl $soma, %ebx");
asm(" movl 16(%ebp), %eax");
asm(" movl %ebx, (%eax,%ecx)");

asm(" forJcond:");
asm(" cmpl $0, j");
asm(" jne forJloop");

asm(" forIcond:");
asm(" cmpl $0, i");
asm(" jne forIloop");

}

void multMatrixC(int m1[L][L], int m2[L][L], int r[L][L]){ //REALIZA MULTIPLICAÇÃO DE MATRIZ
int i, j, k, soma = 0;

for(i=0; i<L; i++){
for(j=0; j<L; j++){
r[i][j] = 0;

for(k=0; k<L; k++){
soma += m1[i][k] * m2[k][j];
}
r[i][j] = soma;
soma = 0;
}
}
}

void printMatrix(int m[L][L]){ // PRINT MATRIZ
int i, j;

for(i=0; i<L; i++){
for(j=0; j<L; j++){
printf("%5d",m[i][j]);
}
printf("\n\t");
}
}

void doubleMatrix(int m[L][L]){ // DOBRO DA MATRIZ
int i, j;

for(i=0; i<L; i++){
for(j=0; j<L; j++){
m[i][j] *= 2;
}
}
}

int smallestMatrix(int m[L][L]){ // RETORNA MENOR VALOR DA DIAGONAL PRINCIPAL
int i, menor = 99999;

for(i=0; i<L; i++){
if(m[i][i] < menor)
menor = m[i][i];
}

return menor;
}


OBS: A função que realiza a multiplicação em NASM está comentada porque ainda tenho que verificar os comandos se estão corretas, porém se alguem puder simplismente verificar a logica em GAS e me dizer se está correta agradeço!


  






Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts