Diferencia entre revisiones de «Práctica Vectores y Matrices (Organización del Computador II)»
Sin resumen de edición |
|||
(No se muestran 3 ediciones intermedias del mismo usuario) | |||
Línea 1: | Línea 1: | ||
<div style="border: 1px solid #CECEFF; padding: 5px; background-color: #EEEEFF; margin: 0px 0px 15px 0px;">[[Image:Back.png|14px|]] [[Organización del Computador II|Volver a la página de la materia]]</div> | |||
== Ejercicio: esSimetrica == | |||
La siguiente funcion dice si una matriz es simetrica respecto de su diagonal principal | |||
global essimetrica | |||
section .text | |||
essimetrica: | |||
; inicio el stack frame | |||
push ebp | |||
mov ebp,esp | |||
push esi | |||
push edi | |||
push ebx | |||
xor ecx, ecx | |||
mov esi, dword [ebp + 8] ; puntero matriz | |||
mov cx, word [ebp + 12] ; tamano | |||
xor ebx, ebx ; ebx <- indice horiz | |||
mov edx,1 ; edx <- indice vertical | |||
cicloide: | |||
mov eax, ebx | |||
shl edx,16 | |||
mul word cx | |||
shr edx,16 | |||
add eax, edx ; eax <- ebx*ancho + edx | |||
mov edi, [esi + eax*4] ; edi <- 1er operando | |||
mov eax, edx | |||
shl edx,16 | |||
mul word cx | |||
shr edx,16 | |||
add eax, ebx ; eax <- edx*ancho + ebx | |||
cmp edi, [esi + eax*4] | |||
jnz distintas | |||
inc edx ; edx <- edx + 1 (cambio de columna) | |||
cmp edx, ecx ; si ya llegue al final de la fila | |||
jae cambioFila ; cambio de fila | |||
jmp cicloide ; si no, sigo iterando en la misma. | |||
cambioFila: | |||
inc ebx ; ebx <- ebx + 1 | |||
lea edx, [ebx +1] ; seteo edx asi para empezar de la diagonal para la derecha | |||
cmp edx, ecx | |||
jge termine | |||
jmp cicloide | |||
termine: | |||
mov eax, 1 | |||
jmp fin | |||
distintas: | |||
mov eax, 0 | |||
fin: | |||
pop ebx | |||
pop edi | |||
pop esi | |||
pop ebp | |||
ret | |||
y para correrlo desde C... | |||
#include <stdio.h> | |||
extern int essimetrica(unsigned int*, unsigned short n); | |||
int main() { | |||
unsigned int m1[] = {1,2,3,4, | |||
2,1,5,6, | |||
3,5,1,7, | |||
4,6,7,1}; | |||
unsigned int m2[] = {1,2,3,4, | |||
2,1,5,6, | |||
3,5,1,7, | |||
4,6,9,1}; | |||
int b1 = essimetrica(m1,4); | |||
int b2 = essimetrica(m2,4); | |||
printf("%u, %u\n",b1,b2); | |||
return 0; | |||
} | |||
== Ejercicio 20 == | == Ejercicio 20 == | ||
Línea 261: | Línea 360: | ||
} | } | ||
[[Category:Prácticas]] | |||
[[Category:Organización del Computador II]] |
Revisión del 05:44 1 oct 2007
Ejercicio: esSimetrica
La siguiente funcion dice si una matriz es simetrica respecto de su diagonal principal
global essimetrica section .text essimetrica: ; inicio el stack frame push ebp mov ebp,esp push esi push edi push ebx xor ecx, ecx mov esi, dword [ebp + 8] ; puntero matriz mov cx, word [ebp + 12] ; tamano xor ebx, ebx ; ebx <- indice horiz mov edx,1 ; edx <- indice vertical cicloide: mov eax, ebx shl edx,16 mul word cx shr edx,16 add eax, edx ; eax <- ebx*ancho + edx mov edi, [esi + eax*4] ; edi <- 1er operando mov eax, edx shl edx,16 mul word cx shr edx,16 add eax, ebx ; eax <- edx*ancho + ebx cmp edi, [esi + eax*4] jnz distintas inc edx ; edx <- edx + 1 (cambio de columna) cmp edx, ecx ; si ya llegue al final de la fila jae cambioFila ; cambio de fila jmp cicloide ; si no, sigo iterando en la misma. cambioFila: inc ebx ; ebx <- ebx + 1 lea edx, [ebx +1] ; seteo edx asi para empezar de la diagonal para la derecha cmp edx, ecx jge termine jmp cicloide termine: mov eax, 1 jmp fin distintas: mov eax, 0 fin: pop ebx pop edi pop esi pop ebp ret
y para correrlo desde C...
#include <stdio.h> extern int essimetrica(unsigned int*, unsigned short n); int main() { unsigned int m1[] = {1,2,3,4, 2,1,5,6, 3,5,1,7, 4,6,7,1}; unsigned int m2[] = {1,2,3,4, 2,1,5,6, 3,5,1,7, 4,6,9,1}; int b1 = essimetrica(m1,4); int b2 = essimetrica(m2,4); printf("%u, %u\n",b1,b2); return 0; }
Ejercicio 20
Escribir una función que verifique si la suma el elementos de la diagonal principal es igual a la suma de elementos de la diagonal transpuensta (supongo que diagonal "transpuensta" es la antidiagonal).
Este codigo recorre una vez la matriz guardando en edx:eax la suma total de los elementos de la diagonal principal y salvandolos en la stack al terminar, luego hace lo mismo con la antidiagonal, compara y devuelve el resultado.
global diagEq %define ptrMat [ebp+8] %define tamFila [ebp+12] %define sumAlta [ebp-16] %define sumBaja [ebp-20] section .text diagEq: ;Armo stack frame push ebp mov ebp, esp push ebx push esi push edi sub esp, 8 ;Preparo registros mov ecx, tamFila ;ecx = iterador mov edi, tamFila ;edi = tamaño fila mov esi, ptrMat ;esi = puntero a matriz xor edx, edx ;edx = parte alta de la suma acumulada xor eax, eax ;eax = parte baja de la suma acumulada ;Recorro diagonal principal diag1: mov ebx, [esi] ;ebx = elemento actual cmp ebx, 0x0 ;Comparo con cero para ver que le sumo a la parte alta jl restar1 ;sumar1: add eax, ebx ;Sumo partes bajas adc edx, 0x0 ;Paso el carry jmp seguir1 restar1: add eax, ebx ;Sumo partes bajas adc edx, 0xFFFFFFFF ;Paso el carry y sumo la sign extension seguir1: lea esi, [esi + 4*edi + 4] loop diag1 ;Guardo acumulados mov sumAlta, edx mov sumBaja, eax ;Repito para anti diagonal ;Preparo registros mov ecx, tamFila ;ecx = iterador mov esi, ptrMat ;esi = puntero a matriz xor edx, edx ;edx = parte alta de la suma acumulada xor eax, eax ;eax = parte baja de la suma acumulada ;Recorro antidiagonal lea esi, [esi + 4*edi - 4] diag2: mov ebx, [esi] ;ebx = elemento actual cmp ebx, 0x0 ;Comparo con cero para ver que le sumo a la parte alta jl restar2 ;sumar2: add eax, ebx ;Sumo partes bajas adc edx, 0x0 ;Paso el carry jmp seguir2 restar2: add eax, ebx ;Sumo partes bajas adc edx, 0xFFFFFFFF ;Paso el carry y sumo la sign extension seguir2: lea esi, [esi + 4*edi - 4] loop diag2 ;Comparo xor ebx, ebx cmp edx, sumAlta jne fin cmp eax, sumBaja jne fin mov ebx, 0x1 fin: mov eax, ebx ;Retorno add esp, 8 pop edi pop esi pop ebx pop ebp ret
Este codigo, en cambio, recorre primero la mitad superior de la matriz y luego la inferior, calculando la diferencia entre las dos diagonales, y luego la compara con cero.
global diagEq %define ptrMat [ebp+8] %define tamFila [ebp+12] section .text diagEq: ;Armo stack frame push ebp mov ebp, esp push ebx push esi push edi ;Preparo registros mov ecx, tamFila ;ecx = iterador mov edi, tamFila ;edi = tamaño fila mov esi, ptrMat ;esi = puntero a matriz xor edx, edx ;edx = parte alta de la suma acumulada xor eax, eax ;eax = parte baja de la suma acumulada ;Recorro matriz diag: mov ebx, [esi] ;ebx = elemento actual cmp ebx, 0x0 ;Comparo con cero para ver que le sumo a la parte alta jl restar1 ;sumar1: add eax, ebx ;Sumo partes bajas adc edx, 0x0 ;Paso el carry jmp seguir1 restar1: add eax, ebx ;Sumo partes bajas adc edx, 0xFFFFFFFF ;Paso el carry y sumo la sign extension seguir1: dec ecx lea esi, [esi + 4*ecx] ;Apunto esi al elemento de la otra diagonal de la misma fila mov ebx, [esi] ;ebx = elemento actual cmp ebx, 0x0 ;Comparo con cero para ver que le resto a la parte alta jl restar2 ;sumar2: sub eax, ebx ;Resto partes bajas sbb edx, 0x0 ;Paso el carry jmp seguir2 restar2: sub eax, ebx ;Resto partes bajas sbb edx, 0xFFFFFFFF ;Paso el carry y resto la sign extension seguir2: dec ecx lea esi, [esi + 4*edi] ;Apunto esi al elemento de la diagonal ppal de la proxima fila neg ecx lea esi, [esi + 4*ecx] neg ecx jnz diag ;Loopeo mientras no sea cero ;Recorro la mitad inferior de la matriz mov ecx, tamFila ;Cargo en ecx de vuelta el tamaño de fila mov esi, ptrMat ;Apunto ecx al ultimo elemento mov ebx, edi imul ebx, edi lea esi, [esi + ebx - 1] diagB: mov ebx, [esi] ;ebx = elemento actual cmp ebx, 0x0 ;Comparo con cero para ver que le sumo a la parte alta jl restarB1 ;sumarB1: add eax, ebx ;Sumo partes bajas adc edx, 0x0 ;Paso el carry jmp seguirB1 restarB1: add eax, ebx ;Sumo partes bajas adc edx, 0xFFFFFFFF ;Paso el carry y sumo la sign extension seguirB1: dec ecx neg ecx lea esi, [esi + 4*ecx] ;Apunto esi al elemento de la otra diagonal de la misma fila neg ecx mov ebx, [esi] ;ebx = elemento actual cmp ebx, 0x0 ;Comparo con cero para ver que le resto a la parte alta jl restarB2 ;sumarB2: sub eax, ebx ;Resto partes bajas sbb edx, 0x0 ;Paso el carry jmp seguirB2 restarB2: sub eax, ebx ;Resto partes bajas sbb edx, 0xFFFFFFFF ;Paso el carry y resto la sign extension seguirB2: dec ecx neg edi lea esi, [esi + 4*edi] ;Apunto esi al elemento de la diagonal ppal de la proxima fila neg edi lea esi, [esi + 4*ecx] jnz diagB ;Loopeo mientras no sea cero ;Comparo xor ebx, ebx cmp edx, 0 jne fin cmp eax, 0 jne fin mov ebx, 0x1 fin: mov eax, ebx ;Retorno pop edi pop esi pop ebx pop ebp ret
Este es el codigo C para probar los dos asm anteriores
#include <stdio.h> //Retorna 1 si true, 0 si false //Recibe puntero a la matriz y ancho de fila/columna (matriz cuadrada) extern int diagEq(int* matriz, int n); int main() { int m[16] = { 0x7589AC45, 0x87221184, 0xAC449523, 0xFA57CD24, 0x48792A98, 0xFA57CD24, 0x0F85AAEE, 0x4486AC66, 0x65AA7854, 0x7589AC45, 0x0F85AAEE, 0xFFA55712, 0x4578AFDE, 0x2584742A, 0x567CFFA8, 0x4578AFDE }; int res= diagEq(m, 4); if (res==1) printf("Suma de diagonal y antidiagonal iguales.\n"); else printf("Suma de diagonal y antidiagonal distintas-\n"); return 0; }