windows - ¿Por qué son dependientes del sistema operativo "Archivos ejecutables"?
linux compiler-construction (6)
Entiendo que cada CPU / arquitectura tiene su propio conjunto de instrucciones, por lo tanto, un programa (binario) escrito para una CPU específica no puede ejecutarse en otro. Pero lo que realmente no entiendo es por qué un archivo ejecutable (binario como .exe por ejemplo) no se puede ejecutar en Linux, pero puede ejecutarse en Windows incluso en la misma máquina.
Esta es una pregunta básica, y la respuesta que espero es que .exe y otros formatos binarios probablemente no son instrucciones Raw de la máquina, pero contienen algunos datos que dependen del sistema operativo. Si esto es cierto, ¿cómo son estos datos dependientes del sistema operativo? y como ejemplo, ¿cuál es el formato de un archivo .exe y la diferencia entre él y los ejecutables de Linux?
¿Hay alguna fuente en la que pueda obtener información breve y detallada sobre esto?
.exe y otros formatos binarios son [definitivamente] no instrucciones de la máquina en bruto, pero contienen algunos datos que dependen del sistema operativo.
cómo son estos datos dependientes del sistema operativo? y como ejemplo, ¿cuál es el formato de un archivo .exe y la diferencia entre él y los ejecutables de Linux?
Bueno, supongo que Google te falló completamente. Los formatos .EXE están muy bien definidos por la documentación de Windows.
http://support.microsoft.com/kb/65122
La aplicación Linux ld
carga un archivo ejecutable en la memoria antes de "ejecutar" ese archivo. Puede leer en formato ld
o incluso en el famoso archivo a.out
.
Además del formato ejecutable que debe ser reconocido por el cargador del sistema (es decir, la parte de un sistema operativo que trae el ejecutable a la memoria), el problema real es la interfaz con el sistema operativo. Puede pensar en un sistema operativo como un tipo de API que proporciona puntos de entrada que debe llamar para hacer cosas específicas, como por ejemplo, escribir un carácter en la consola.
Estos detalles suelen estar más o menos ocultos para el usuario final, por lo que puede lograr escribir un carácter en la pantalla con el mismo código fuente en idiomas de nivel superior. Pero a menudo, las cosas son más diferentes, como por ejemplo el entorno Windowing. No todos los lenguajes de alto nivel proporcionan una capa de ventana que resuma incluso sobre esas diferencias.
Los programas necesitan saber cómo invocar los servicios del sistema operativo. Cómo se hace esto depende del sistema operativo: algunas usan interrupciones, algunas usan la instrucción x86 lcall
, otras (especialmente Windows) tienen bibliotecas compartidas distinguidas y no documentan cómo invocar directamente los servicios. Los antiguos Mac de 680x0 y algunos otros sistemas operativos de 680x0 usaban un área de conjunto de instrucciones reservadas y atrapaban la excepción resultante de "código de operación de CPU no válido". Además, incluso cuando el mecanismo es el mismo, el formato de orden y argumento de las llamadas al sistema difiere entre los sistemas operativos (y a veces diferentes versiones del mismo sistema operativo; ver stat()
en el kernel de Linux para un ejemplo de una interfaz que ha cambiado varias veces).
Existe cierta capacidad para tratar con las convenciones de otros sistemas operativos: FreeBSD tiene el "linuxulator" que maneja la interfaz kernel específica de Linux, NetBSD tiene emuladores para los formatos de llamada de sistema de otros sistemas operativos que usan el mismo hardware (por ejemplo, Ultrix en MIPS u OSF / 1 en Alpha), Linux solía tener iBCS2 para manejar la interfaz del kernel UnixWare / SCO Unix, Wine proporciona bibliotecas compartidas de reemplazo y un cargador binario para ejecutables de Windows de tipo PE. (No recuerdo si Wine también es compatible con LX .exe
s de estilo OS / 2, probablemente maneja el formato original .exe
, y luego está .com
que es un volcado de memoria en bruto con un encabezado abrochado). siempre hay algún formato que usa convenciones diferentes, y algunas veces las convenciones son lo suficientemente similares como para requerir sugerencias al OS sobre cómo lidiar con ellas. (Véase bless
en FreeBSD, por ejemplo).
No puedo comentar mucho sobre * nix, pero sí, la parte del código del binario suele estar feliz de ejecutarse en cualquier entorno, pero es el sistema operativo el que impone ciertas exigencias al binario. En Windows debes leer en los encabezados PE .
La segunda parte depende simplemente del desarrollador, muchas veces la parte del código hará referencia a las bibliotecas que son específicas del sistema operativo, razón por la cual puede tener código C ++ portátil y no portátil antes de ser compilado en un archivo binario.
Para hacer algo significativo, las aplicaciones deberán interactuar con el sistema operativo. Dado que las llamadas al sistema y la infraestructura del espacio de usuario tienen una apariencia fundamentalmente diferente en Windows y Unix / Linux, tener los diferentes formatos para los programas ejecutables es el problema más pequeño. Es la lógica del programa que debería cambiarse.
(Podría argumentar que esto no tiene sentido si tiene un programa que solo depende de componentes estandarizados, por ejemplo, la biblioteca de tiempo de ejecución de C. Esto es teóricamente cierto, pero irrelevante para la mayoría de las aplicaciones, ya que están obligados a usar cosas dependientes del sistema operativo).
Las otras diferencias entre los archivos de Windows PE (EXE, DLL, ..) y los archivos binarios ELF de Linux están relacionados con los diferentes cargadores de imágenes y algunas características de diseño de ambos sistemas operativos. Por ejemplo, en Linux, un programa separado se utiliza para resolver las importaciones externas de la biblioteca, mientras que esta funcionalidad está incorporada en Windows. Otro ejemplo: las bibliotecas compartidas de Linux funcionan de forma diferente que las DLL en Windows. Sin mencionar que ambos formatos están optimizados para permitir que los kernels del sistema operativo respectivos carguen los programas lo más rápido posible.
Los emuladores como Wine tratan de llenar el vacío ( y en realidad prueban que el mayor problema no es el formato binario sino la interfaz del sistema operativo ).
Una respuesta muy ingenua:
- Su estructura es diferente debido a los diferentes cargadores de procesos;
- El uso de funciones dependientes del os como syscalls, que varían de sistema operativo a sistema operativo.