Este artículo analiza paso a paso cómo reducir el tamaño de un ejecutable ELF en x86-64 compilado con GCC partiendo de un programa mínimo que simplemente devuelve 0 al sistema. El autor, mediante una serie de iteraciones con banderas del compilador y código ensamblador inline, consigue reducir el binario de 15.816 bytes a 8.616 bytes sin recurrir a herramientas de postprocesado como objcopy o editores hexadecimales.
El recorrido parte del programa más simple posible —una función main que retorna 0— y aplica progresivamente cuatro optimizaciones clave. La primera es la bandera -s, que elimina la información de depuración y baja el binario a 14.352 bytes. La segunda introduce -nostartfiles junto a un punto de entrada _start propio, lo que omite el código de inicialización que normalmente ejecuta el sistema antes de llegar a main, dejando el archivo en 13.632 bytes.
La tercera optimización es la más drástica: combinar -static, -nostdlib y -no-pie reemplaza el enlazado dinámico y toda la maquinaria de PLT/GOT, tablas de símbolos y stubs de bibliotecas compartidas por un enlazado estático sin bibliotecas estándar y con direccionamiento fijo. Además, sustituir la llamada a exit por una invocación directa de la syscall de Linux (mov $60, %al; xor %dil, %dil; syscall) mediante asm inline reduce el ejecutable a 8.704 bytes. Por último, -fno-ident suprime la sección .comment, donde GCC almacena su firma, y deja el binario final en 8.616 bytes.
El artículo sirve como introducción práctica a conceptos del formato ELF, al proceso de arranque de un programa en Linux y a la diferencia entre enlazado dinámico y estático. Está dirigido a programadores de C/C++ y de sistemas, estudiantes de arquitectura de computadores y lectores curiosos que quieran entender qué ocurre realmente entre invocar ./a.out y la primera instrucción de main. Como consideraciones, el autor señala que el camino se detiene antes de explorar técnicas más avanzadas como la eliminación de cabeceras ELF o el ensamblado manual, y que las cifras dependen de la versión de GCC (en este caso 15.2.0) y de glibc. El texto queda además inconcluso en su última sección.
