2011-01-05 12 views
13

Soy relativamente nuevo en todo esto de bajo nivel, lenguaje ensamblador ... y quiero aprender más detalles. ¿Por qué hay una diferencia entre los lenguajes de ensamblador de Linux y Windows?¿Por qué hay una diferencia entre los lenguajes ensambladores como Windows, Linux?

Como entiendo cuando compilo un código C El sistema operativo realmente no produce la máquina pura o el código de ensamblaje, produce código binario dependiente del sistema operativo. Pero ¿por qué?

Por ejemplo, cuando uso un sistema x86, la CPU solo entiende ASM x86 ¿Estoy en lo cierto? ¿Por qué no escribimos el código de ensamblaje x86 puro y por qué hay diferentes variaciones de ensamblaje basadas en el sistema operativo? Si escribiéramos ASM puro o OS produciría ASM puro, no habría problemas de compatibilidad binarios entre los sistemas operativos o no?

Realmente me pregunto todas las razones detrás de ellos. Cualquier respuesta detallada, artículo, libro sería genial. Gracias.

+2

la única diferencia es que: los métodos que usa son dependientes del sistema operativo. por ejemplo: el método C printf() haría algo diferente en el sistema operativo porque cada sistema operativo lo maneja de otra manera. –

Respuesta

13

No hay diferencia. El código de ensamblaje es el mismo si el procesador es el mismo. El código x86 compilado en Windows es binario compatible con el código x86 en Linux. El compilador no produce código binario dependiente del sistema operativo, pero puede empaquetar el código en un formato diferente (por ejemplo, PE frente a ELF).

La diferencia radica en qué bibliotecas se utilizan. Para usar cosas del sistema operativo (E/S, por ejemplo), debe vincularse con las bibliotecas del sistema operativo. Como era de esperar, las bibliotecas del sistema de Windows no están disponibles en una máquina Linux (a menos que tenga Wine por supuesto) y viceversa.

+0

Entonces, ¿por qué hay diferentes idiomas de ensamblado Windows Asm, Linux Asm, Dos Asm? – mcaaltuntas

+0

@mcaaltuntas: Essentialy, no hay. La distinción radica en la forma en que se utilizan los recursos (llamadas del sistema operativo, básicamente), no en el conjunto de instrucciones. – Piskvor

+5

@mcaaltuntas: no hay. hay ensamblaje x86, ensamblaje x86_64, ensamblaje mips, ensamblaje m68k ... ensamblaje no ensamblado o ensamblado de windows –

3

A menos que esté utilizando un entorno de desarrollo de sistema integrado, está compilando con compiladores que están destinados a un tiempo de ejecución particular. Ese tiempo de ejecución define las convenciones para el uso del hardware: aprobación de argumentos, manejo de excepciones, etc. Estas convenciones interactúan con el sistema operativo, o al menos con las bibliotecas de tiempo de ejecución disponibles con las que el programa necesita vincularse.

1

El sistema operativo determina dos cosas: (1) el calling convention, que define cómo van los parámetros en la pila y por lo tanto afecta el código ensamblador, y (2) las bibliotecas en tiempo de ejecución que implementan funciones comunes como asignación de memoria, entrada/salida, matemáticas de nivel superior, etc.

Así que mientras x+y compila el mismo código de ensamblaje en Windows o Linux en un procesador x86, y = sin(x) será diferente debido a una convención de llamadas diferente y a una biblioteca matemática diferente.

Más allá de eso, el lenguaje ensamblador depende del procesador. x86, x86_64, ARM, PowerPC, cada uno tiene su propio lenguaje ensamblador.

3

Históricamente, el ensamblaje de Linux tiende a hacerse usando AT & T sintaxis, ya que esto es lo que admite el GNU Assembler. Del mismo modo, los ensambladores de Windows tienden a usar la sintaxis de Intel, como con MASM y NASM.

Todos los ensambladores x86 producen la misma salida, es decir, código máquina x86. Y puede usar NASM o GNU Assembler en Linux para programar bajo la sintaxis Intel, y GNU Assembler en Windows para programar bajo AT & T sintaxis.

+2

Las herramientas GNU (incluido gdb) son compatibles con las sintaxis at & t e intel en las versiones actuales. Por lo general, configuro intel-sintaxis; hace las cosas mucho más fáciles, especialmente cuando se trabaja con herramientas como Ida Pro al mismo tiempo –

4

Bueno, no ejecuta el montaje recto. El código debe estar en algún tipo de formato ejecutable: windows usa PE, la mayoría de los Unices usan ELF ahora (aunque ha habido otros, como a.out).

Las instrucciones de ensamblaje de la base son las mismas, y las funciones que crea con ellas son las mismas.

El problema viene con el acceso a otros recursos. El procesador es realmente bueno para el cálculo, pero no puede acceder al disco duro, imprimir un personaje en la pantalla o conectarse a un teléfono con Bluetooth. Estos elementos siempre dependen de algún modo del sistema operativo. Se implementan en términos de llamadas de sistema, donde el procesador señala al sistema operativo para realizar una determinada tarea. La tarea número 17 en Linux no es necesariamente la tarea 17 en Windows; es posible que ni siquiera tengan equivalentes.

Dado que la mayoría de las bibliotecas tienen algunas llamadas de sistema en sus niveles más bajos, esta es la razón por la cual el código no puede ser recompilado en todos los casos.

+0

+1 Creo que esa es una de las principales razones: diferentes formatos de archivo ejecutables. – karlphillip

1

No hay diferencia en los lenguajes ensamblados (aunque puede haber diferencias entre los ensambladores, y por lo tanto las anotaciones utilizadas), siempre que nos apeguemos a x86. Tanto Linux como Microsoft Windows se ejecutan en otras arquitecturas, más aún en el caso de Linux.

Sin embargo, un sistema operativo hoy en día no solo carga un programa en la memoria y lo suelta. Proporciona una gran cantidad de servicios. Como también protege los programas entre sí, impone restricciones. Para hacer algo más que cálculos básicos, generalmente es necesario pasar por el sistema operativo. (Esto era menos cierto en sistemas operativos anteriores, como MS-DOS y CP/M, que podían cargar programas que se ejecutan de forma independiente, pero hoy en día casi todos los sistemas no integrados tienen un sistema operativo moderno.)

No son programas almacenado como manchas binarias simples. Normalmente es necesario vincularlo con otras bibliotecas, a menudo cuando el programa se carga para su ejecución (así es como funcionan las DLL, por ejemplo) y es necesario vincularlo con el sistema operativo. Puede haber otra información que el sistema operativo requiera y, por lo tanto, debe haber algún tipo de información sobre el blob binario en el archivo ejecutable. Esto varía entre los sistemas operativos.

Por lo tanto, los archivos ejecutables deben estar en un formato para ser cargados en la memoria, y esto varía desde el sistema operativo al sistema operativo. Para hacer algo útil, tienen que hacer llamadas al sistema operativo, que son diferentes entre sistemas. Es por eso que no puede tomar un ejecutable de Windows y las bibliotecas asociadas y ejecutarlo en Linux.

0

Existen algunos ensambladores para varias plataformas que, dado un archivo fuente, producirán un archivo binario de salida directamente diseñado para ser cargado en una dirección particular. Tales ensambladores han sido populares para algunos microcontroladores pequeños, o para algunos procesadores históricos como el 6502 y el Z80. Al armar el programa, sería necesario conocer la dirección donde se esperaría que residiera; usar una dirección diferente requeriría volver a ensamblar el programa. Por otro lado, el ensamblaje en un sistema de este tipo era un proceso de un solo paso. Ejecute el ensamblador en el código fuente y obtenga una salida ejecutable. En algunos casos, sería posible tener el código fuente, ensamblador y salida en la memoria a la vez (en mi Commodore 64, utilicé un ensamblador que se publicó en la revista Compute's Gazette que funcionaba así).

A pesar de volver a montar todo en cualquier momento sus cambios de dirección podrían haber sido práctico para un programa que va a "hacerse cargo de la máquina", en muchos casos es conveniente utilizar un proceso de múltiples pasos donde archivos de origen se procesan en archivos de código objeto , que contienen las instrucciones ensambladas pero también contienen varios tipos de información "simbólica" sobre ellas; estos archivos se procesan de varias formas para generar una imagen de memoria que se puede cargar directamente en la memoria, o bien un archivo de objeto reubicable combinado que el cargador de un sistema operativo sabrá cómo ajustar para cualquier dirección a la que pueda cargarse .

Para que un sistema de enlace de objetos sea útil, debe permitir el aplazamiento de ciertos tipos de cálculos de direcciones hasta que un programa se vincule o cargue. Algunos sistemas solo permiten que se realicen cómputos extremadamente simples en el tiempo de enlace/carga, mientras que otros permiten cálculos más complicados. Los esquemas más simples pueden ser más eficientes cuando son viables, pero sus limitaciones pueden forzar soluciones temporales. A modo de ejemplo, una rutina que va a utilizar BX colocar a través de una estructura de datos con menos de 256 bytes puede ser escrito como algo así como:

mov bx,StartAddr 

lp: mov al, [BX] ... hacer algunos cálculos inc bx cmp bl, < (StartAddr + Length); < operador de prefijo significa "LSB" JNZ lp

Sería posible utilizar cmp bx,(StartAddr+Length), pero si las herramientas de compilación pueden apoyarlo, comparando sólo el byte bajo sería más rápido. Por otro lado, algunos tipos de herramientas de ensamblaje/enlace de 16 bits pueden requerir que todas las correcciones de direcciones se realicen con direcciones de 16 bits almacenadas en el código.

Debido a que diferentes sistemas permiten diferentes características en sus formatos de código de objeto, requieren diferentes características en sus lenguajes de ensamblaje para controlarlos. Los conjuntos de instrucciones pueden ser especificados por el fabricante del chip, pero las características para expresar el cálculo de dirección reubicable generalmente no lo son.

0

El lenguaje de ensamblaje está relacionado con la arquitectura de la CPU no con O.S., sino con O.S. tener una serie de funciones del sistema compiladas en binario que su programa ensamblador puede invocar, mediante llamadas de interrupción. Por ejemplo, salida de entrada estándar, operación ecc ....

Cuestiones relacionadas