2010-11-10 13 views
5

Estoy tratando de aprender toda la cadena de ingenieria para que pueda entender mejor lo que sucede cuando hago construir/enlace/compilar etc.la comprensión de la necesidad de compiladores para diferentes plataformas

Un punto que estoy teniendo problemas with es esto: si el compilador convierte el origen en ensamblado nativo, ¿por qué el mismo programa no se puede ejecutar en diferentes sistemas operativos? ¿El ensamble no se ejecuta directamente por la CPU? Por lo tanto, el mismo código de máquina debería ejecutarse en todos los SO, siempre que sea la misma arquitectura, ¿no? Por qué no?

EDIT: La mayoría de las respuestas hasta el momento están a punto de llamar API del OS. Eso obviamente es un problema. Mi pregunta es sobre el código de máquina recta . ¿Se pasa directamente a la CPU o no? Si escribí un programa en ensamblador, ¿aún tendría que compilar por separado para cada sistema operativo? (punto aparte: si utilicé C++ cin/cout estándar, ¿depende de ese sistema operativo el compilador para dirigir la E/S de ensamblaje o la respuesta depende del compilador?)

Respuesta

8

Diferentes sistemas operativos admiten diferentes formatos binarios (por ejemplo, ELF frente a COFF), diferentes vinculadores dinámicos (con archivos * .so, * .dll y * .dylib siendo vinculado en tiempo de ejecución, después de haber distribuido su binario), y proporcionar diferentes conjuntos de funciones y bibliotecas para usar la funcionalidad proporcionada por el sistema operativo.

Se pueden abordar diferentes conjuntos de funciones, por ejemplo, con la especificación única UNIX/IEEE Std. 1003.1 (POSIX), que dicta un conjunto único de funciones que se proporcionarán en todos los sistemas operativos para diversas tareas del sistema operativo (lamentablemente no todos los sistemas operativos (ejem, Windows) cumplen). Con respecto a los formatos binarios (y también a la arquitectura del conjunto de instrucciones de la CPU), una forma de lidiar con esto es distribuir algún formato binario de alto nivel (bytecode) y luego hacer una transformación justo a tiempo al conjunto de instrucciones de destino y formato binario (aunque esto se trata más de cambiar cuando lo haces ... aún debe hacerse). La máquina virtual de bajo nivel (LLVM), por ejemplo, proporciona dicha transformación.

5

Porque, por un lado, la capacidad de la interfaz con el sistema operativo no es consistente entre las plataformas. Incluso entre Linux/x86, Windows y Mac/Intel (que pueden usar la misma CPU), la forma de hacer las cosas puede ser muy diferente.

Por lo tanto, aunque un compilador puede producir archivos de objetos que funcionarían, en el momento en que vincula esos objetos a bibliotecas específicas de la plataforma, se vuelven inherentemente no portátiles.

Un ejemplo es la asignación de memoria. Cuando desee solicitar más memoria del sistema operativo bajo UNIX, puede usar la función de biblioteca brk o sbrk. Esto es no parte de la biblioteca estándar C, más específica de UNIX.

Por otro lado, Windows puede proporcionar una función Win32GetMem para hacer lo mismo.

0

Sí El código de máquina lo ejecuta directamente la CPU. Pero incluso el conjunto de instrucciones de 32 bits "x86" que es el código de máquina ha sufrido revisiones a lo largo de los años. Pero, en general, el código compilado para una arquitectura debe ejecutarse en otros sistemas. Un problema mayor sería qué compilador y sistema operativo se compiló en

0

Sí, lo hace. Así es como puede ejecutar aplicaciones de Windows en Linux en Wine, por ejemplo. Puede ejecutar el programa directamente por más de un motivo. Por ejemplo, el formato de su ejecutable es diferente en diferentes sistemas, por lo que los sistemas normalmente no tienen la menor idea de cómo cargar y ejecutar entre sí ejecutables.Además, la mayoría de los programas querrán llamar a las rutinas del sistema y llamar a algunas funciones de la biblioteca, y aquí estamos hablando de conjuntos de acuerdos completamente diferentes sobre cómo se hace en cada sistema.

1

Tienes razón en que un compilador sólo se ocupa de la generación de las instrucciones de ensamblador correctas para una CPU de destino específico. Pero el compilador no está solo: una aplicación normalmente tiene que interactuar con el sistema operativo host para ejecutarse correctamente.

Así que el problema no está en el compilador en sí, sino en el conjunto de bibliotecas estándar que cada sistema operativo proporciona para hacer cosas comunes como acceder a archivos, asignar memoria o interactuar con el sistema de ventanas gráfico. Si bien el código para, por ejemplo, Windows XP y Solaris x86 se compilaría con el mismo conjunto de instrucciones de código de máquina, el código tendría que realizar diferentes llamadas para interactuar con el sistema operativo.

compiladores de propiedad vienen equipados solamente con las cabeceras y bibliotecas para el sistema operativo que se hacen para. Otros compiladores más agnósticos como el GCC de GNU comparten mucho código para compilar con el mismo tipo de CPU en diferentes sistemas operativos.

8

Se trata de los sistemas operativos API y ABI.

Diferentes sistemas operativos proporcionan diferentes system calls, así como diferentes mecanismos para invocar esas llamadas al sistema. Por ejemplo, mientras POSIX proporciona fork y execv para crear un nuevo proceso, Windows proporciona CreateProcess.

Además, hay diferencias en el nivel de montaje. ¿Qué código de ensamblado usas para llamar a una función? Diferentes sistemas operativos esperan diferentes calling conventions. Los sistemas operativos tampoco necesariamente acuerdan el formato del binario ejecutable, ni acuerdan otros mecanismos como el enlace dinámico.

Otro punto a considerar es la concurrencia y la forma en que el sistema operativo se encarga de eso. Algunos sistemas operativos reconocen subprocesos en el nivel kernel, mientras que otros no. Algunos podrían preferir usar múltiples procesos, y algunos podrían usar un modelo completamente diferente. Las API son diferentes, y las abstracciones pueden ser diferentes. Por ejemplo, un SO puede usar bloqueos y semáforos, otro podría usar el paso de mensajes.

0

Su pregunta, "Por lo tanto, el mismo código de máquina debería ejecutarse en todos los sistemas operativos, siempre que sea la misma arquitectura, ¿no?" Es incorrecto. El código de máquina se ejecuta en hardware que no está en el sistema operativo. Un sistema operativo proporciona servicios al programa de usuario/sistema y estos servicios se implementan de manera diferente en cada sistema operativo. Digamos por el argumento, si tomara el código máquina de su programa del sistema operativo "X" en el arco "A" y lo alimentara directamente a un sistema con sistema operativo "Y" con el mismo arco "A", la CPU podrá para ejecutar las instrucciones, pero esto puede (y casi siempre) provocar el bloqueo de su programa (debido a los diferentes problemas de implementación que otros ya han mencionado).

Cuestiones relacionadas