Feeds de las etiquetas frecuentes

Mostrando entradas con la etiqueta gcc. Mostrar todas las entradas
Mostrando entradas con la etiqueta gcc. 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.

Los nuevos Barcelona de AMD y algunas cosas más...

AMD va a lanzar unos nuevos micros similares a los Opteron. Unos bichos muy gordos para servidores. Con sus 4 cores y bastante memorias cache. Como veis en el gráfico, van a ser bien gordos jejejeje. Quizás os gustaría ver lo de la tecnología HyperTransport. Que es para que corran más y que vaya de 2 palabras en 2 palabras, en vez de de 1 en 1. Por otra parte he visto las nuevas ATI que van a sacar ATI-AMD. Como se puede ver más fácil con una fotillo pos ahí hay una jejejeje. Esta noticia la vi via madboxpc.com aunque no sé de donde salté allí xD. Otra cosa curiosa es lo de las teles láser. No sabía que existiera esa tecnología. Parece que será la siguiente evolución de las TVs de plasma, LCD,... En otro orden de cosas ayer me vi leyendo algo de la documentación interna de gcc ("FRIKIIIISMO!" como diría KK), se echa de menos una traducción de eso porque se hace pesadísimo. Todo para saber como funcionan los compiladores quizás un buen libro o pdf de compiladores... si eso comentad y listo. Desde aqui un saludo a KK Un saludo Palmax PD: ATI y AMD estarán registradas por sus dueños ------------------------------------------------------------------------- - Oiga, ¿cuando hacemos un gcc -g el compilador guarda la tabla de símbolos en el ejecutable? - ¿Qué? - Digo que si cuando pasamos al gcc la opción -g de depurar guarda la tabla de símbolos en el ejecutable - ¿Eso es en linux? ... Mi universidad la mejor pública en este país de piel de toro jejejeje