Buscar..


Microsoft Assembler - MASM

Dado que el 8086/8088 se usó en la PC de IBM, y el sistema operativo de Microsoft fue el más utilizado, el ensamblador MASM de Microsoft fue el estándar de facto durante muchos años. Siguió de cerca la sintaxis de Intel, pero permitió una sintaxis conveniente pero "suelta" que (en retrospectiva) solo causó confusión y errores en el código.

Un ejemplo perfecto es el siguiente:

MaxSize      EQU     16          ; Define a constant
Symbol       DW      0x1234      ; Define a 16-bit WORD called Symbol to hold 0x1234

             MOV     AX, 10      ; AX now holds 10
             MOV     BX, MaxSize ; BX now holds 16
             MOV     CX, Symbol  ; ????

¿La última instrucción MOV pone el contenido de Symbol en CX , o la dirección de Symbol en CX ? ¿ CX termina con 0x1234 o 0x0102 (o lo que sea)? Resulta que CX termina con 0x1234 - si quieres la dirección, necesitas usar el especificador OFFSET

             MOV     AX, [Symbol]      ; Contents of Symbol
             MOV     CX, OFFSET Symbol ; Address of Symbol

Ensamblador de Intel

Intel escribió la especificación del lenguaje ensamblador 8086, un derivado de los procesadores 8080, 8008 y 4004 anteriores. Como tal, el ensamblador que escribieron siguió su propia sintaxis con precisión. Sin embargo, este ensamblador no se usó mucho.

Intel definió sus códigos de operación para tener cero, uno o dos operandos. Las instrucciones de dos operandos se definieron para estar en el dest , orden de source , que era diferente de otros ensambladores en ese momento. Pero algunas instrucciones utilizaron registros implícitos como operandos, solo tenía que saber qué eran. Intel también usó el concepto de "prefijo" códigos de operación: un código de operación afectaría la siguiente instrucción.

; Zero operand examples
NOP             ; No parameters
CBW             ; Convert byte in AL into word in AX
MOVSB           ; Move byte pointed to by DS:SI to byte pointed to by ES:DI
                ; SI and DI are incremented or decremented according to D bit

; Prefix examples
REP   MOVSB     ; Move number of bytes in CX from DS:SI to ES:DI
                ; SI and DI are incremented or decremented according to D bit

; One operand examples
NOT      AX     ; Replace AX with its one's complement
MUL      CX     ; Multiply AX by CX and put 32-bit result in DX:AX

; Two operand examples
MOV      AL, [0x1234] ; Copy the contents of memory location DS:0x1234 into AL register

Intel también rompió una convención utilizada por otros ensambladores: para cada código de operación, se inventó una mnemónica diferente. Esto requirió nombres sutil o claramente diferentes para operaciones similares: por ejemplo, LDM para "Cargar desde la memoria" y LDI para "Cargar inmediatamente". Intel usó el único MOV mnemotécnico, y esperaba que el ensamblador resolviera qué código de operación utilizar desde el contexto. Eso causó muchos escollos y errores para los programadores en el futuro cuando el ensamblador no pudo intuir lo que el programador realmente quería ...

Ensamblador AT&T - como

Aunque el 8086 fue el más utilizado en las PC de IBM junto con Microsoft, hubo una cantidad de otras computadoras y sistemas operativos que también lo utilizaron: en particular, Unix. Ese era un producto de AT&T, y ya tenía Unix ejecutándose en otras arquitecturas. Esas arquitecturas utilizaban una sintaxis de ensamblaje más convencional, especialmente que las instrucciones de dos operandos las especificaban en la source , orden de dest .

Así que las convenciones de ensambladores de AT&T anularon las convenciones dictadas por Intel, y se introdujo un dialecto completamente nuevo para el rango x86:

  • Los nombres de los registros fueron prefijados por % :
    %al , %bx etc.
  • Los valores inmediatos fueron preferidos por $ :
    $4
  • Los operandos estaban en source , orden de dest
  • Opcodes incluyó sus tamaños de operandos:
    movw $4, %ax ; Move word 4 into AX

Turbo Assembler de Borland - TASM

Borland comenzó con un compilador de Pascal que llamaron "Turbo Pascal". Esto fue seguido por compiladores para otros idiomas: C / C ++, Prolog y Fortran. También produjeron un ensamblador llamado "Turbo Assembler", que, siguiendo la convención de nomenclatura de Microsoft, llamaron "TASM".

TASM intentó solucionar algunos de los problemas de escritura de código utilizando MASM (ver más arriba), al proporcionar una interpretación más estricta del código fuente en un modo IDEAL específico. Por defecto, asumió el modo MASM , por lo que pudo ensamblar la fuente MASM directamente, pero luego Borland descubrió que tenían que ser compatibles bug-for-bug con las idiosincrasias más "extravagantes" de MASM, así que también agregaron un modo QUIRKS .

Dado que TASM era (mucho) más barato que MASM, tenía una gran base de usuarios, pero no mucha gente usaba el modo IDEAL, a pesar de sus ventajas promocionadas.

Ensamblador GNU - gas

Cuando el proyecto GNU necesitaba un ensamblador para la familia x86, utilizaban la versión de AT&T (y su sintaxis) asociada con Unix en lugar de la versión de Intel / Microsoft.

Ensamblador Netwide - NASM

NASM es, con diferencia, el ensamblador más adaptado para la arquitectura x86: está disponible para prácticamente todos los sistemas operativos basados ​​en x86 (incluso se incluye con MacOS) y está disponible como ensamblador multiplataforma en otras plataformas.

Este ensamblador utiliza la sintaxis de Intel, pero es diferente de los demás porque se centra en gran medida en su propio lenguaje "macro", lo que permite al programador crear expresiones más complejas utilizando definiciones más simples, lo que permite crear nuevas "instrucciones".

Desafortunadamente, esta poderosa característica tiene un costo: el tipo de datos interfiere con las instrucciones generalizadas, por lo que no se aplica la tipificación de datos.

response:    db       'Y'     ; Character that user typed

             cmp      response, 'N' ; *** Error! Unknown size!
             cmp byte response, 'N' ; That's better!
             cmp      response, ax  ; No error!

Sin embargo, NASM introdujo una característica de la que otros carecían: nombres de símbolos en el ámbito. Cuando define un símbolo en otros ensambladores, ese nombre está disponible en el resto del código, pero eso "usa" ese nombre, "contaminando" el espacio de nombres global con símbolos.

Por ejemplo (usando la sintaxis NASM):

       STRUC     Point
X      resw      1
Y      resw      1
       ENDSTRUC

Después de esta definición, X e Y se definen para siempre. Para evitar "usar" los nombres X e Y , necesitaba usar nombres más definidos:

       STRUC     Point
Pt_X   resw      1
Pt_Y   resw      1
       ENDSTRUC

Pero NASM ofrece una alternativa. Al aprovechar su concepto de "variable local", puede definir campos de estructura que requieren que nombre la estructura contenedora en referencias futuras:

       STRUC      Point
.X     resw       1
.Y     resw       1
       ENDSTRUC

Cursor ISTRUC     Point
       ENDISTRUC

       mov        ax,[Cursor+Point.X]
       mov        dx,[Cursor+Point.Y]

Desafortunadamente, debido a que NASM no realiza un seguimiento de los tipos, no puede usar la sintaxis más natural:

       mov        ax,[Cursor.X]
       mov        dx,[Cursor.Y]

Sin embargo, otro ensamblador - YASM

YASM es una reescritura completa de NASM, pero es compatible con las sintaxis de Intel y AT&T.



Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow