En informática , un código ejecutable , un archivo ejecutable o un programa ejecutable , a veces denominado simplemente ejecutable o binario , hace que una computadora "realice tareas indicadas de acuerdo con instrucciones codificadas ", [2] a diferencia de un archivo de datos que debe ser interpretado ( analizado ) por un intérprete para que sea funcional. [3]
La interpretación exacta depende del uso. "Instrucciones" se entiende tradicionalmente como instrucciones de código de máquina para una CPU física . [4] En algunos contextos, un archivo que contiene instrucciones de secuencias de comandos (como bytecode ) también puede considerarse ejecutable.
Los archivos ejecutables se pueden codificar a mano en lenguaje de máquina, aunque es mucho más conveniente desarrollar software como código fuente en un lenguaje de alto nivel que los humanos puedan entender fácilmente. En algunos casos, el código fuente puede especificarse en lenguaje ensamblador , que sigue siendo legible por humanos y al mismo tiempo está estrechamente asociado con las instrucciones del código de máquina.
El lenguaje de alto nivel se compila en un archivo de código de máquina ejecutable o en un archivo de código de máquina no ejecutable ( archivo objeto de algún tipo); el proceso equivalente en código fuente en lenguaje ensamblador se llama ensamblaje . Varios archivos objeto están vinculados para crear el ejecutable. Los archivos objeto, ejecutables o no, generalmente se almacenan en un formato contenedor , como el formato ejecutable y vinculable (ELF) o el ejecutable portátil (PE), que es específico del sistema operativo . [5] Esto le da estructura al código de máquina generado, por ejemplo dividiéndolo en secciones como .text (código ejecutable), .data (variables estáticas y globales inicializadas) y .rodata (datos de solo lectura, como constantes y instrumentos de cuerda).
Los archivos ejecutables generalmente también incluyen un sistema de ejecución , que implementa características del lenguaje de ejecución (como programación de tareas , manejo de excepciones , llamada a constructores y destructores estáticos, etc.) e interacciones con el sistema operativo, en particular pasando argumentos, entorno y devolución de un estado de salida. , junto con otras funciones de inicio y apagado, como la liberación de recursos como identificadores de archivos . Para C, esto se hace vinculando el objeto crt0 , que contiene el punto de entrada real y realiza la configuración y el apagado llamando a la biblioteca de tiempo de ejecución . [6]
Por lo tanto, los archivos ejecutables normalmente contienen un código de máquina adicional significativo además del generado directamente a partir del código fuente específico. En algunos casos, es deseable omitir esto, por ejemplo para el desarrollo de sistemas integrados, o simplemente para comprender cómo funcionan la compilación, la vinculación y la carga. En C, esto se puede hacer omitiendo el tiempo de ejecución habitual y, en su lugar, especificando explícitamente un script vinculador, que genera el punto de entrada y maneja el inicio y el apagado, como llamar main
al inicio y devolver el estado de salida al kernel al final. [7]
Para que el sistema lo ejecute (como un sistema operativo , firmware [ cita requerida ] o cargador de arranque ), un archivo ejecutable debe ajustarse a la interfaz binaria de aplicación (ABI) del sistema. En interfaces simples, un archivo se ejecuta cargándolo en la memoria y saltando al inicio del espacio de direcciones y ejecutándolo desde allí. [8] En interfaces más complicadas, los archivos ejecutables tienen metadatos adicionales que especifican un punto de entrada independiente . Por ejemplo, en ELF, el punto de entrada se define en el campo del encabezado e_entry
, que especifica la dirección de memoria (virtual) en la que iniciar la ejecución. [9] En la Colección de compiladores GNU , este campo lo establece el vinculador según el _start
símbolo. [10]