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