Feeds de las etiquetas frecuentes

El Alicate

¿Un merengue o un reggaeton? Cuarto y mitad
"Tú lo abres y lo cierras mami"... ¡ma que cosa! Este tío es el del pescao (es muy mala) que sonó por aquí:
Y sobre todo la de "Mueve Mami":
De todas formas ahí otras muy chulas como la de "si me preguntan donde vivo yo, yo vivo en la discoteca" (que se titula borrachera, un buen merengue).

¿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.