Intel x86 Assembly Language & Microarchitecture
Ensambladores
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,%bxetc. - Los valores inmediatos fueron preferidos por
$:
$4 - Los operandos estaban en
source, orden dedest - 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.