Diferencia entre programas compilados para diferentes sistemas operativos
8
En el punto de vista del código compilado, ¿cuál es la diferencia entre un programa compilado para un sistema operativo frente a otro (Linux frente a Windows, por ejemplo)? ¿El programa no se ejecuta directamente en la CPU? ¿O es porque el programa necesita hacer referencia a bibliotecas específicas del sistema operativo?
Los programas compilados ordinarios "se ejecutan directamente" en la CPU, pero un programa no se ejecuta en el vacío:
Muchos programas se basan en bibliotecas ( DLLso .sobibliotecas) externas cargadas dinámicamente . La forma de vincularlos depende del compilador / vinculador, y cada sistema operativo tiene diferentes estándares. Sin embargo, también hay programas "vinculados estáticamente" que proporcionan todo su propio código.
Un sistema operativo moderno no le da el control completo de la computadora a un programa en ejecución. Los programas se basan en "llamadas del sistema" para E / S, acceso al hardware y cosas como señales y entrar en un estado de suspensión. Los servicios disponibles y la interfaz están definidos por el sistema operativo. El sistema operativo también controla qué partes del sistema (memoria, registros, interrupciones) puede usar el programa.
Un programa GUI también debe funcionar a través del entorno gráfico de usuario para dibujarse en la pantalla. Pero probablemente ya hayas pensado en esto.
Por estas razones, las aplicaciones independientes del sistema operativo deben confiar en una "máquina virtual" de algún tipo, como la que proporciona el tiempo de ejecución de Java. De manera crucial, una VM proporciona una interfaz estándar para los recursos del sistema operativo (E / S, señales, etc.). Por supuesto, java o python también interpretan "bytecode" en lugar de tratar con las peculiaridades del conjunto de instrucciones de Intel; Pero esa es una historia diferente.
Además, los diferentes sistemas operativos tienen diferentes estándares para el diseño de la pila, las prácticas de alineación de la memoria, etc., por lo que incluso el código puramente numérico / computacional puede necesitar diferir de un sistema operativo a otro.
Daniel R Hicks
¿Evitarían estas diferencias la ejecución de código compilado estáticamente? No sabía eso ..
alexis
Probablemente sea solo un problema teórico, ya que alguna otra incompatibilidad te llevaría primero. Pero los sistemas operativos a menudo tienen expectativas de cómo se alinean los marcos de la pila, dónde se almacenan los registros, etc. Estos pueden variar de un sistema operativo a otro para la misma arquitectura de hardware. En teoría, es posible que EJECUTE código "extraño" que sea puramente computacional, pero nunca podrá iniciarlo y nunca podrá finalizarlo de manera limpia.
Daniel R Hicks
5
Los diferentes sistemas operativos también tienen una funcionalidad diferente. Windows tiene puertos de finalización de E / S, Linux no. FreeBSD tiene kqueue, Linux no. Linux tiene futexes, Windows no. También tienen diferentes formas de hacer lo mismo: ¿qué parámetros pasas para abrir un archivo? ¿En qué orden entran? ¿Cómo invocas específicamente la función "abrir un archivo" del sistema operativo?
ok, eso tiene sentido, pero en general, el programa se carga en la memoria y se ejecuta en la CPU, o el sistema operativo "tiene control" sobre el programa
agz
1
@agovizer: Ambos. No son mutuamente excluyentes. Por lo general, el sistema operativo configurará un entorno controlado y organizará que el hardware interrumpa el programa en un período de tiempo particular y luego entregue el núcleo al programa. Pero tan pronto como el programa alcanza cualquier número de condiciones (como un fallo de página, operación de E / S o similares), el sistema operativo se hace cargo nuevamente.
¿El programa no se ejecuta directamente en la CPU?
NO ! Ese es el trabajo del sistema operativo, evitar que las aplicaciones se ejecuten "directamente" en la CPU. Normalmente, en el nivel más bajo (es decir, en el que se basa la API del sistema operativo), una aplicación interactúa con el núcleo del sistema operativo .
¿Es porque el programa compilado en sí mismo necesita hacer referencia a bibliotecas específicas del sistema operativo?
Sí . Muchas bibliotecas del sistema operativo están escritas para facilitar la interfaz con el sistema operativo en sí, pero hay tantas que están escritas para ser multiplataforma. Estos ocultan la interfaz del sistema operativo de bajo nivel del desarrollador, y asume que la versión compilada para ese sistema operativo estará disponible en tiempo de ejecución (ver más abajo).
Aunque las bibliotecas se pueden escribir de manera multiplataforma, cuando se compilan no se pueden ejecutar multiplataforma. Todavía deben volver a compilarse para el sistema operativo de destino específico, nuevamente para utilizar los componentes subyacentes particulares del sistema operativo (kernel).
¿Cuál es la diferencia entre un programa compilado para un sistema operativo frente a otro?
Finalmente, los archivos ejecutables a menudo contienen encabezados de carga binarios muy específicos y demás (por ejemplo, el formato de archivo ejecutable PE [.exe, .dll, etc ...] para Windows o ELF para Linux [ninguno, .o, .so , etc ...]). Estos también pueden incluir código para cargar los binarios compilados específicos del sistema operativo para una biblioteca de software en particular.
Por último, desde la perspectiva de un programador: convocatoria de convenciones . El código compilado pasa variables a funciones de una manera dada (es decir, a través de registros o en la pila) en un orden muy particular. Incluso entonces, también debe acordarse quién es responsable de "limpiar" las llamadas de función (¿la persona que llama o la persona que llama?). Aunque hay varias convenciones de llamadas x86 estándar y ampliamente utilizadas , algunas pueden no ser compatibles con ciertos sistemas operativos (esto es parte de la ABI).
Los diferentes sistemas operativos también tienen una funcionalidad diferente. Windows tiene puertos de finalización de E / S, Linux no. FreeBSD tiene kqueue, Linux no. Linux tiene futexes, Windows no. También tienen diferentes formas de hacer lo mismo: ¿qué parámetros pasas para abrir un archivo? ¿En qué orden entran? ¿Cómo invocas específicamente la función "abrir un archivo" del sistema operativo?
fuente
En general, los programas no son compatibles debido a las diferencias en su interfaz binaria de aplicación (ABI) .
NO ! Ese es el trabajo del sistema operativo, evitar que las aplicaciones se ejecuten "directamente" en la CPU. Normalmente, en el nivel más bajo (es decir, en el que se basa la API del sistema operativo), una aplicación interactúa con el núcleo del sistema operativo .
Sí . Muchas bibliotecas del sistema operativo están escritas para facilitar la interfaz con el sistema operativo en sí, pero hay tantas que están escritas para ser multiplataforma. Estos ocultan la interfaz del sistema operativo de bajo nivel del desarrollador, y asume que la versión compilada para ese sistema operativo estará disponible en tiempo de ejecución (ver más abajo).
Aunque las bibliotecas se pueden escribir de manera multiplataforma, cuando se compilan no se pueden ejecutar multiplataforma. Todavía deben volver a compilarse para el sistema operativo de destino específico, nuevamente para utilizar los componentes subyacentes particulares del sistema operativo (kernel).
Finalmente, los archivos ejecutables a menudo contienen encabezados de carga binarios muy específicos y demás (por ejemplo, el formato de archivo ejecutable PE [.exe, .dll, etc ...] para Windows o ELF para Linux [ninguno, .o, .so , etc ...]). Estos también pueden incluir código para cargar los binarios compilados específicos del sistema operativo para una biblioteca de software en particular.
Por último, desde la perspectiva de un programador: convocatoria de convenciones . El código compilado pasa variables a funciones de una manera dada (es decir, a través de registros o en la pila) en un orden muy particular. Incluso entonces, también debe acordarse quién es responsable de "limpiar" las llamadas de función (¿la persona que llama o la persona que llama?). Aunque hay varias convenciones de llamadas x86 estándar y ampliamente utilizadas , algunas pueden no ser compatibles con ciertos sistemas operativos (esto es parte de la ABI).
fuente