Programa generador de una matriz en C
El programa con el cual trabajare es un programa en lenguaje c que nos crea e imprime una matriz de NxM, el codigo es el siguiente.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include<stdio.h> | |
/*Matriz lectura y impresion n x m*/ | |
main() | |
{ | |
int i,j,n,m; | |
printf("Dame el numero de filas:"); | |
scanf("%d",&n); | |
printf("Dame el numero de columnas:"); | |
scanf("%d",&m); | |
int A[n][m]; | |
for(i=0;i<n;i++) | |
{ | |
for(j=0;j<m;j++) | |
{ | |
printf("A[%d][%d]= ",i+1,j+1); | |
scanf("%d",&A[i][j]); | |
} | |
} | |
printf("\n\n"); | |
for(i=0;i<n;i++) | |
{ | |
for(j=0;j<m;j++) | |
{ | |
printf("%d",A[i][j]); | |
} | |
printf("\n\n"); | |
} | |
getch(); | |
} | |
Creamos el codigo ensamblador apartir del archivo.c utilizando lo siguiente.

Compilamos el codigo de ensamblador, en este caso aparece un error por el use del getch, basta con retirarlo para poder compilar y posteriormente poder crear el ejecutable.

Programa Convertido a Lenguaje Ensamblador
El codigo ensamblador generado es el siguiente, como podemos ver es un codigo bastante extenso ya que de 31 lineas de codigo paso a convertise en un codigo de 170 lineas.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.file "matriz.c" | |
.section .rodata | |
.LC0: | |
.string "Dame el numero de filas:" | |
.LC1: | |
.string "%d" | |
.LC2: | |
.string "Dame el numero de columnas:" | |
.LC3: | |
.string "A[%d][%d]= " | |
.LC4: | |
.string "\n" | |
.text | |
.globl main | |
.type main, @function | |
main: | |
.LFB0: | |
.cfi_startproc | |
pushq %rbp | |
.cfi_def_cfa_offset 16 | |
.cfi_offset 6, -16 | |
movq %rsp, %rbp | |
.cfi_def_cfa_register 6 | |
pushq %r13 | |
pushq %r12 | |
pushq %rbx | |
subq $72, %rsp | |
movq %rsp, %rax | |
movq %rax, %r12 | |
.cfi_offset 3, -40 | |
.cfi_offset 12, -32 | |
.cfi_offset 13, -24 | |
movl $.LC0, %eax | |
movq %rax, %rdi | |
movl $0, %eax | |
call printf | |
movl $.LC1, %eax | |
leaq -48(%rbp), %rdx | |
movq %rdx, %rsi | |
movq %rax, %rdi | |
movl $0, %eax | |
call __isoc99_scanf | |
movl $.LC2, %eax | |
movq %rax, %rdi | |
movl $0, %eax | |
call printf | |
movl $.LC1, %eax | |
leaq -44(%rbp), %rdx | |
movq %rdx, %rsi | |
movq %rax, %rdi | |
movl $0, %eax | |
call __isoc99_scanf | |
movl -44(%rbp), %ebx | |
movl -48(%rbp), %eax | |
movslq %ebx, %rdx | |
subq $1, %rdx | |
movq %rdx, -72(%rbp) | |
movslq %ebx, %rdx | |
leaq 0(,%rdx,4), %r13 | |
movslq %eax, %rdx | |
subq $1, %rdx | |
movq %rdx, -64(%rbp) | |
movslq %ebx, %rdx | |
cltq | |
imulq %rdx, %rax | |
salq $2, %rax | |
leaq 15(%rax), %rdx | |
movl $16, %eax | |
subq $1, %rax | |
addq %rdx, %rax | |
movq $16, -88(%rbp) | |
movl $0, %edx | |
divq -88(%rbp) | |
imulq $16, %rax, %rax | |
subq %rax, %rsp | |
movq %rsp, %rax | |
addq $15, %rax | |
shrq $4, %rax | |
salq $4, %rax | |
movq %rax, -56(%rbp) | |
movl $0, -40(%rbp) | |
jmp .L2 | |
.L5: | |
movl $0, -36(%rbp) | |
jmp .L3 | |
.L4: | |
movl -36(%rbp), %eax | |
leal 1(%rax), %edx | |
movl -40(%rbp), %eax | |
leal 1(%rax), %ecx | |
movl $.LC3, %eax | |
movl %ecx, %esi | |
movq %rax, %rdi | |
movl $0, %eax | |
call printf | |
movq -56(%rbp), %rax | |
movl -40(%rbp), %edx | |
movslq %edx, %rcx | |
movslq %ebx, %rdx | |
imulq %rdx, %rcx | |
movl -36(%rbp), %edx | |
movslq %edx, %rdx | |
addq %rcx, %rdx | |
salq $2, %rdx | |
addq %rax, %rdx | |
movl $.LC1, %eax | |
movq %rdx, %rsi | |
movq %rax, %rdi | |
movl $0, %eax | |
call __isoc99_scanf | |
addl $1, -36(%rbp) | |
.L3: | |
movl -44(%rbp), %eax | |
cmpl %eax, -36(%rbp) | |
jl .L4 | |
addl $1, -40(%rbp) | |
.L2: | |
movl -48(%rbp), %eax | |
cmpl %eax, -40(%rbp) | |
jl .L5 | |
movl $.LC4, %edi | |
call puts | |
movl $0, -40(%rbp) | |
jmp .L6 | |
.L9: | |
movl $0, -36(%rbp) | |
jmp .L7 | |
.L8: | |
movq %r13, %rsi | |
shrq $2, %rsi | |
movq -56(%rbp), %rax | |
movl -36(%rbp), %edx | |
movslq %edx, %rcx | |
movl -40(%rbp), %edx | |
movslq %edx, %rdx | |
imulq %rsi, %rdx | |
addq %rcx, %rdx | |
movl (%rax,%rdx,4), %edx | |
movl $.LC1, %eax | |
movl %edx, %esi | |
movq %rax, %rdi | |
movl $0, %eax | |
call printf | |
addl $1, -36(%rbp) | |
.L7: | |
movl -44(%rbp), %eax | |
cmpl %eax, -36(%rbp) | |
jl .L8 | |
movl $.LC4, %edi | |
call puts | |
addl $1, -40(%rbp) | |
.L6: | |
movl -48(%rbp), %eax | |
cmpl %eax, -40(%rbp) | |
jl .L9 | |
movl $0, %eax | |
call getch | |
movq %r12, %rsp | |
leaq -24(%rbp), %rsp | |
popq %rbx | |
popq %r12 | |
popq %r13 | |
popq %rbp | |
.cfi_def_cfa 7, 8 | |
ret | |
.cfi_endproc | |
.LFE0: | |
.size main, .-main | |
.ident "GCC: (Ubuntu/Linaro 4.6.1-9ubuntu3) 4.6.1" | |
.section .note.GNU-stack,"",@progbits |
Explicación de algunas lineas:
SEGMENT y ENDS: Definen los segmentos a utilizar.
cfi_startproc:Se utiliza antes de cualquier función que tenga alguna entrada de datos.
Call:Llama a alguna acción próxima a realizarse
Programa de matriz en ensamblador optimizado
Despues de una larga revision de las cosas que eran realmente necesarias y las cuales no lo eran se lograron eliminar 54 lineas de codigo terminando con el siguiente codigo mas limpio y corto.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.file "matriz.c" | |
.section .rodata | |
.LC0: | |
.string "Dame el numero de filas:" | |
.LC1: | |
.string "%d" | |
.LC2: | |
.string "Dame el numero de columnas:" | |
.LC3: | |
.string "A[%d][%d]= " | |
.LC4: | |
.string "\n" | |
.text | |
.globl main | |
.type main, @function | |
main: | |
.LFB0: | |
.cfi_startproc | |
pushq %rbp | |
movq %rsp, %rbp | |
subq $72, %rsp | |
movl $.LC0, %eax | |
movq %rax, %rdi | |
movl $0, %eax | |
call printf | |
movl $.LC1, %eax | |
leaq -48(%rbp), %rdx | |
movq %rdx, %rsi | |
movq %rax, %rdi | |
movl $0, %eax | |
call __isoc99_scanf | |
movl $.LC2, %eax | |
movq %rax, %rdi | |
movl $0, %eax | |
call printf | |
movl $.LC1, %eax | |
leaq -44(%rbp), %rdx | |
movq %rdx, %rsi | |
movq %rax, %rdi | |
movl $0, %eax | |
call __isoc99_scanf | |
movslq %ebx, %rdx | |
leaq 0(,%rdx,4), %r13 | |
movq %rsp, %rax | |
addq $15, %rax | |
shrq $4, %rax | |
salq $4, %rax | |
movq %rax, -56(%rbp) | |
movl $0, -40(%rbp) | |
.L5: | |
movl $0, -36(%rbp) | |
.L4: | |
movl -36(%rbp), %eax | |
leal 1(%rax), %edx | |
movl -40(%rbp), %eax | |
leal 1(%rax), %ecx | |
movl $.LC3, %eax | |
movl %ecx, %esi | |
movq %rax, %rdi | |
movl $0, %eax | |
call printf | |
movq -56(%rbp), %rax | |
movslq %ebx, %rdx | |
imulq %rdx, %rcx | |
movl -36(%rbp), %edx | |
salq $2, %rdx | |
addq %rax, %rdx | |
movl $.LC1, %eax | |
movq %rdx, %rsi | |
movq %rax, %rdi | |
movl $0, %eax | |
call __isoc99_scanf | |
addl $1, -36(%rbp) | |
.L3: | |
movl -44(%rbp), %eax | |
cmpl %eax, -36(%rbp) | |
jl .L4 | |
addl $1, -40(%rbp) | |
.L2: | |
cmpl %eax, -40(%rbp) | |
jl .L5 | |
movl $.LC4, %edi | |
call puts | |
movl $0, -40(%rbp) | |
.L9: | |
movl $0, -36(%rbp) | |
.L8: | |
movq %r13, %rsi | |
shrq $2, %rsi | |
movq -56(%rbp), %rax | |
movl -36(%rbp), %edx | |
movslq %edx, %rcx | |
imulq %rsi, %rdx | |
movl (%rax,%rdx,4), %edx | |
movl $.LC1, %eax | |
movl %edx, %esi | |
movq %rax, %rdi | |
movl $0, %eax | |
call printf | |
addl $1, -36(%rbp) | |
.L7: | |
movl -44(%rbp), %eax | |
cmpl %eax, -36(%rbp) | |
jl .L8 | |
movl $.LC4, %edi | |
call puts | |
addl $1, -40(%rbp) | |
.L6: | |
cmpl %eax, -40(%rbp) | |
jl .L9 | |
leaq -24(%rbp), %rsp | |
popq %rbx | |
popq %r12 | |
popq %r13 | |
popq %rbp | |
.cfi_endproc | |
.LFE0: | |
.size main, .-main | |
.ident "GCC: (Ubuntu/Linaro 4.6.1-9ubuntu3) 4.6.1" | |
.section .note.GNU-stack,"",@progbits |
Por ultimo podemos ver que el programa despues de ser optimizado ejecuta de la misma forma que antes.

Referencias:
http://es.kioskea.net/faq/3284-compilar-un-programa-ensamblador-con-nasm
http://iie.fing.edu.uy/~vagonbar/gcc-make/gcc.htm