Feeds de las etiquetas frecuentes

Mostrando entradas con la etiqueta compilador. Mostrar todas las entradas
Mostrando entradas con la etiqueta compilador. Mostrar todas las entradas

¿Cómo se compila un programa?

Este artículo es una visión muy ligera. Tenemos un código que queremos compilar: ~/ejemplo $ cat suma_1y1.c // Compilame (-S llegar al ensamblador y -o para final): // gcc -S suma_1y1.c -fdump-tree-all -O0 -Wall // gcc -o suma_1y1.bin suma_1y1.c -fdump-tree-all -O0 -Wall #include int main () { int i; int j; int k; i = 1; j = 1; k = i + j; printf( "%d + %d = %d\n", i, j, k ); return k; } Y luego lo mandamos compilar con unas opciones especiales para ver todos los pasos, sin ninguna optimización y avisándonos de los posibles problemas: ~/ejemplo $ gcc -S suma_1y1.c -fdump-tree-all -O0 -Wall Y ahora vamos a ver qué ha hecho el compilador. El "suma_1y1.c.001t.tu" es el conjunto de funciones existentes, pero no tiene especial interés. Veamos el "original": ~/ejemplo $ cat suma_1y1.c.003t.original ;; Function main (main) ;; enabled by -tree-original { int i; int j; int k; int i; int j; int k; i = 1; j = 1; k = i + j; printf ((const char * restrict) (char *) "%d + %d = %d\n", i, j, k); return k; } Luego hace el paso a código de tres direcciones: ~/ejemplo $ cat suma_1y1.c.004t.gimple main () { int D.2026; int i; int j; int k; i = 1; j = 1; k = i + j; printf (&"%d + %d = %d\n"[0], i, j, k); D.2026 = k; return D.2026; } Nos saltamos algunos que no son interesantes (vcg, useless, lower, eh, cfg), y llegamos a cplxlower0 en el que vemos que ha detectado un bloque de sentencias (el "segundo"): ~/ejemplo $ cat suma_1y1.c.023t.cplxlower0 ;; Function main (main) main () { int k; int j; int i; int D.2026; : i = 1; j = 1; k = i + j; printf (&"%d + %d = %d\n"[0], i, j, k); D.2026 = k; return D.2026; } Veclower y fixupcfg no tienen mucho interés pero mostraremos la salida de éste último: ~/ejemplo $ cat suma_1y1.c.026t.fixupcfg ;; Function main (main) main () { int k; int j; int i; int D.2026; # BLOCK 2 # PRED: ENTRY (fallthru) i = 1; j = 1; k = i + j; printf (&"%d + %d = %d\n"[0], i, j, k); D.2026 = k; return D.2026; # SUCC: EXIT } Tras estos pasos el gcc realiza el siguiente código final para x86: $ cat suma_1y1.s .file "suma_1y1.c" .section .rodata .LC0: .string "%d + %d = %d\n" .text .globl main .type main, @function main: leal 4(%esp), %ecx andl $-16, %esp pushl -4(%ecx) pushl %ebp movl %esp, %ebp pushl %ecx subl $36, %esp movl $1, -16(%ebp) movl $1, -12(%ebp) movl -12(%ebp), %eax addl -16(%ebp), %eax movl %eax, -8(%ebp) movl -8(%ebp), %eax movl %eax, 12(%esp) movl -12(%ebp), %eax movl %eax, 8(%esp) movl -16(%ebp), %eax movl %eax, 4(%esp) movl $.LC0, (%esp) call printf movl -8(%ebp), %eax addl $36, %esp popl %ecx popl %ebp leal -4(%ecx), %esp ret .size main, .-main .ident "GCC: (GNU) 4.2.3 (Gentoo 4.2.3 p1.0)" .section .note.GNU-stack,"",@progbits Voy a comentar un poco algo del código (comentarios con //) .file "suma_1y1.c" // fichero que originó este código máquina .section .rodata .LC0: .string "%d + %d = %d\n" // para la llamada a printf .text .globl main .type main, @function main: leal 4(%esp), %ecx andl $-16, %esp pushl -4(%ecx) pushl %ebp // guardamos el marco de pila movl %esp, %ebp // el nuevo marco pila es la dirección de la pila pushl %ecx subl $36, %esp movl $1, -16(%ebp) // i = 1 movl $1, -12(%ebp) // j = 1 movl -12(%ebp), %eax addl -16(%ebp), %eax // k = i + j movl %eax, -8(%ebp) movl -8(%ebp), %eax // el cuarto parámetro del printf: k movl %eax, 12(%esp) movl -12(%ebp), %eax // el tercer parámetro del printf: j movl %eax, 8(%esp) movl -16(%ebp), %eax // el segundo parámetro del printf: i movl %eax, 4(%esp) movl $.LC0, (%esp) // el primer parámetro del printf: "%d + %d = %d\n" call printfEnlace movl -8(%ebp), %eax addl $36, %esp // Se desmonta la pila popl %ecx popl %ebp // Se restaura el marco de pila leal -4(%ecx), %esp // Se restaura el puntero de pila ret // retorno del main .size main, .-main .ident "GCC: (GNU) 4.2.3 (Gentoo 4.2.3 p1.0)" .section .note.GNU-stack,"",@progbits Deseas saber más, pues accede a la página del GCC de wikibooks.

[Friki][Informática][HW] En busca de más instrucciones

Sí, soy yo hablando de HW jajaja. Es cierto, que no me gusta mucho. Parece que se quiere utilizar las GPUs (GPU = tarjeta gráfica) con instrucciones especiales. Esto significa que desde el microprocesador, podremos lanzar código específico para la tarjeta gráfica. ¿No suena genial? El problema es que claro el compilador va a tener mucho trabajo o el programador va a tener que saber mucho. De todas formas, pensandolo un poquito en frío la mayoría de los sistemas están compilados para arquitecturas muy antigüas. Esto nos lleva a pensar ¿Por qué no pueden hacer un estándar y así tener binarios más eficientes? Por ejemplo, muchas personas se compran el último ordenador y ... un montón de programas que sólo están compilados para arquitecturas de hace años. ¿Qué os parece? ¡Ah! Conocí a un friki que programaba la GPU a pelo para hacer cálculos matemáticos. Bueno lo vi en /. Tras toda esta información friki... ¡un video friki!