PROGRAMAS EN ASSEMBLER
;EQUIVALENCIAS ASCII - HEXADECIMAL
MSTACK SEGMENT
DB 64 DUP ('MYSTACK_')
MSTACK ENDS
MDATA SEGMENT
ASCII DB 42H ;VALOR ASCII A CONVER TIR EN HEX.
ANSWER DB ?
MDATA ENDS
MCODE SEGMENT 'CODE'
MPROC PROC FAR
ASSUME CS:MCODE,SS:MSTACK,DS:MDATA
PUSH DS
SUB AX,AX
PUSH AX
MOV AX,MDATA
MOV DS,AX
MOV AL,ASCII ;CRGA EL VALOR DE ASCII A AL
SUB AL,30H ;RESTA AL-30H
CMP AL,9 ;COMPARA AL CON 9
JG LETTER ;SI ES MENOR, RESTA (AL-07H)
JMP FIN ;SALTA A FIN Y CARGA EL VALOR DE AL EN ANSWER
LETTER: SUB AL,07H
FIN: MOV ANSWER,AL
RET
MPROC ENDP
MCODE ENDS
END MPROC
;USO DE CADENAS
MSTACK SEGMENT
DB 64 DUP ('MYSTACK_')
MSTACK ENDS
MDATA SEGMENT
BACK DB 1 DUP(''),'___________________________________',3 DUP('') ;2000 DUP
LOGO DB 2 DUP(''),' ',3 DUP('')
DB 2 DUP(''),' ',3 DUP('')
DB 2 DUP(''),' PROGRAMA EN ASSEMBLER ',3 DUP('')
DB 2 DUP(''),' EN LA FLIA 80X86 ',3 DUP('')
DB 2 DUP(''),' ',3 DUP('')
DB 2 DUP(''),'____________________________________',3 DUP('')
MDATA ENDS
MCODE SEGMENT 'CODE'
MPROC PROC FAR
ASSUME CS:MCODE,ES:MDATA,SS:MSTACK
PUSH DS
SUB AX,AX
PUSH AX
MOV AX,MDATA ;CARGA EN AX EL VALOR DE MDATA
MOV ES,AX ;CARGA EN ES EL VALOR DE AX
LEA BP,BACK ;CARGA LA PROMERA DIRECCION DE BACK
MOV DX,0000
MOV AH,1
MOV AL,10 ;10
MOV BL,11111111B
MOV CX,07D0H ;(2000 DECIMAL)
INT 10H ;PIDE EL ACCESO A PANTALLA
LEA BP,LOGO ;CARGA LA PRIMERA DIRECCION DE LOGO.
MOV DH,5 ;MARGEN SUPERIOR
MOV AH,19 ;19
MOV AL,1
MOV BL,01001110B
MOV CX,230H
INT 10H
RET
MPROC ENDP
MCODE ENDS
END MPROC
;PROGRAMA DE HEX A ASCII
MSTACK SEGMENT
DB 64 DUP ('MYSTACK_')
MSTACK ENDS
MDATA SEGMENT
TMPNUM DW ?
TMPCHAR DB 8 DUP (' '),'$'
MDATA ENDS
MCODE SEGMENTE 'CODE'
MPROC PROC FAR
ASSUME CS:MCODE, DS:MDATA, SS:MSTACK
PUSH DS
SUB AX,AX
PUSH AX
MOV AX,MDATA
MOV DS,AX
;PROBLEMA DE SUMA
MOV AX,01234H
ADD AX,02299H
MOV TMPNUM,AX
;VISUALIZA UN REGISTRO DE 16 BITS
MOV CX,04H ;NUMERO DE DIGITOS A COMBERTIR
AGAIN:MOV AX,TMPNUM
AND AX,0FH ;MANTIENE LOS 4 DIGITOS INFERIORES
ADD AL,30H ;COMBIERTE A CODIGO ASCII
CMP AL,07H
ASCII:MOV SI,CX ;PONE EL INDICE =AL CARACTER
MOV TMPCHAR[SI],AL
ROR TMPNUM,1
ROR TMPNUM,1
ROR TMPNUM,1
ROR TMPNUM,1
LOOP AGAIN
;UTILIZA CADENA Y POSICION ACTUAL DEL CURSOR
LEA DX,TMPCHAR
MOV AH,9
INT 21H
RET
MPROC ENDP
MCODE ENDS
END MPROC
; PROGRAMA DE MULTIPLICACION AL CUADRADO Y AL CUBO Y MUESTRA EL RESULTADO EN PANTALLA
MSTACK SEGMENT
DB 64 DUP ('MYSTACK_')
MSTACK ENDS
MDATA SEGMENT
NUM1 DW 1234H
NUM2 DW 00CDH
TMPCHAR DB 5 DUP (' '),'$'
TMPNUM DW ?
ANS1 DW ?
ANS2 DW ?
ANS3 DW ?
MDATA ENDS
MCODE SEGMENT 'CODE'
MPROC PROC FAR
ASSUME CS:MCODE, DS:MDATA, SS:MSTACK
PUSH DS
SUB AX,AX
PUSH AX
MOV AX,MDATA
MOV DS,AX
SUB DX,DX
MOV AX,NUM1
MUL NUM2
MOV WORD PTR ANS1,AX
MOV WORD PTR ANS1+2,DX
MOV BX,AX
MOV TMPNUM,DX
CALL VER
MOV TMPNUM,AX
CALL VER
SUB DX,DX
MOV AX,NUM1
MUL NUM1
MOV WORD PTR ANS2,AX
MOV WORD PTR ANS2+2,DX
MOV TMPNUM,DX
CALL VER
MOV TMPNUM,AX
CALL VER
SUB DX,DX
MOV AX,NUM2
MUL NUM2
MUL NUM2
MOV WORD PTR ANS3,AX
MOV WORD PTR ANS3+2,DX
MOV TMPNUM,DX
CALL VER
MOV TMPNUM,AX
CALL VER
RET
MPROC ENDP
VER PROC
;PROCEDIMIENTO PARA VISUALIZA UN REGISTRO DE 16 BITS
MOV CX,04H ;NUMERO DE DIGITOS A COMBERTIR
AGAIN: MOV AX,TMPNUM
AND AX,0FH ;MANTIENE LOS 4 DIGITOS INFERIORES
ADD AL,30H ;COMBIERTE A CODIGO ASCII
CMP AL,03AH ;COMPARA CON 39
JL ASCII ;SI ES MENOR A 39
ADD AL,07H ;SI NO LE ADICIONA 7H
ASCII: MOV SI,CX ;PONE EL INDICE =AL CARACTER
MOV TMPCHAR[SI],AL
ROR TMPNUM,1
ROR TMPNUM,1
ROR TMPNUM,1
ROR TMPNUM,1
LOOP AGAIN
;UTILIZA CADENA Y POSICION ACTUAL DEL CURSOR
LEA DX,TMPCHAR
MOV AH,9
INT 21H
;INC TMPCHAR
RET
VER ENDP
MCODE ENDS
END MPROC
; MULTIPLICACION POR SUMA REPETIDA MUESTRA EL RESULTADO EN PANTALLA
MSTACK SEGMENT
DB 64 DUP ('MYSTACK_')
MSTACK ENDS
MDATA SEGMENT
NUM1 DB 1H
NUM2 DB 2H
TMPCHAR DB 5 DUP (' '),'$'
TMPNUM DW ?
PRODUCT DW ?
ANS DW ?
MDATA ENDS
MCODE SEGMENT 'CODE'
MPROC PROC FAR
ASSUME CS:MCODE, DS:MDATA, SS:MSTACK
PUSH DS
SUB AX,AX
PUSH AX
MOV AX,MDATA
MOV DS,AX
SUB AX,AX
SUB CX,CX
MOV CL,NUM2
SUB CL,01H
MOV AL,NUM1
AGAIN: ADD AL,NUM1
ADC AH,00H
LOOP AGAIN
MOV PRODUCT,AX
;MOV WORD PTR ANS,AX
;MOV WORD PTR ANS+2,DX
MOV BX,AX
MOV TMPNUM,DX
CALL VER
MOV TMPNUM,AX
CALL VER
RET
MPROC ENDP
VER PROC
;PROCEDIMIENTO PARA VISUALIZA UN REGISTRO DE 16 BITS
MOV CX,04H ;NUMERO DE DIGITOS A COMBERTIR
AGAIN1: MOV AX,TMPNUM
AND AX,0FH ;MANTIENE LOS 4 DIGITOS INFERIORES
ADD AL,30H ;COMBIERTE A CODIGO ASCII
CMP AL,03AH ;COMPARA CON 39
JL ASCII ;SI ES MENOR A 39
ADD AL,07H ;SI NO LE ADICIONA 7H
ASCII: MOV SI,CX ;PONE EL INDICE =AL CARACTER
MOV TMPCHAR[SI],AL
ROR TMPNUM,1
ROR TMPNUM,1
ROR TMPNUM,1
ROR TMPNUM,1
LOOP AGAIN1
;UTILIZA CADENA Y POSICION ACTUAL DEL CURSOR
LEA DX,TMPCHAR
MOV AH,9
INT 21H
;INC TMPCHAR
RET
VER ENDP
MCODE ENDS
END MPROC
PROGRAMAS EN SIMUPROC
PROGRAMAS EN SIMUPROC
;Ecuación de 2do Grado
MSG 'Programa Ecuación de 2do Grado'
;MSG 'Introduzca el valor de "a"'
LDT 'Introduzca el valor de "a"' ;Leo el Valor de A=
MOV 4A,AX ;Grabo el numero en la dir 4A y 4B
;MSG 'Introduzca el Valor de "b"'
LDT 'Introduzca el valor de "b"' ;Leo el valor de B=
MOV 4C,AX ;Grabo el numero en la dir 4C y 4D
;MSG 'Introduzca el Valor de "c"'
LDT 'Introduzca el valor de "c"' ;Leo el valor de C=
MOV 4E,AX ;Grabo el numero en la dir 4E y 4F
JMP 90
MSG '-b'
MOV AX,5A
EAP 5A
;d=b*b-4.0*a*c
MOV 4C,AX
MUL 4C
SUB 64
MUL 4A
MUL 4E
MOV AX,50
JMP 95
MOV AX,50
MSG 'd='
EAP 50
CMP 55
JMA 60 ;d es mayor a 0
JEQ 60 ;d es igual a 0
JMP 80 ;si b es menor a 0 salta a la pos 80
;Inicializo las constantes 1 y 2 en IEEE 754
#50
0011111110000000 ;Inicializo el Numero 1 en la dir 30 y 31
0000000000000000
0100000000000000 ;numero 2 en la dir 32 y 33
0000000000000000
110
0
010
#60
; X1=(-b+SQR(b))/a/2.0
MOV AX,5A ;-b
ADD 100 ;raiz de b
DIV 4A
DIV 56
MOV 6A,AX
; X2=(-b-SQR(b))/a/2.0
MOV AX,5A ;-b
SUB 100
DIV 4A
DIV 56
MOV 6D,AX
JMP 120
#80
;X2=sqr(-d)/a/2
MOV AX,5C ;-d
;LDF 110 ;Raiz de -d
DIV 4A
DIV 56
MOV 6D,AX
;X1=-b/0/2
MOV AX,5A ;-b
DIV 4A
DIV 56
MOV 6A,AX
JMP 120
#90 ; -b
MOV AX,55
MSG 'Negando b'
SUB 4C
MOV 5A,AX
EAP 5A
JMP 0C
#95 ; -d
MOV AX,55
MSG 'Negando d'
SUB 50
MOV 5C
OUT 1,AX
JMP 16
# 120
;Mostrar datos en Pantall
MSG 'El valor de X1 es:'
MOV AX,6A
EAP 'X='
MSG 'El valor de X2 es:'
MOV AX,6D
EAP 'X2'
HLT
;PROGRAMA DE MENUS
MSG 'MENU PRINCIPAL'
MSG 'Escriba 1: para Introducir datos'
MSG 'Escriba 2: para salir'
LDT 'Introdusca 1 Ó 2'
CMP 40
JEQ 50 ;COMPARO SI ES =
CMP 41
JEQ 33
JMP 0
MSG 'MENU SECUNDARIO'
MSG 'Que Operasión quiere realizar:?'
MSG '1: SUMAR'
MSG '2: RESATAR'
MSG '3: MULTIPLICAR'
MSG '4: DIVIDIR'
MSG '5: CARGAR DATOS'
MSG '6: MENU PRINCIPAL'
LDT 'Opsión:'
CMP 40
JEQ 20
JME 9
CMP 41
JEQ 24
CMP 42
JEQ 28
CMP 43
JEQ 2C
CMP 44
JEQ 50
CMP 45
JEQ 0
JMA 9
MOV AX,3E
ADD 3F
EAP 'SUMA:'
JMP 9
MOV AX,3E
SUB 3F
EAP 'RESTA:'
JMP 9
MOV AX,3E
MUL 3F
EAP 'MULTIPLICASION:'
JMP 9
LDA 3F
CMP 47
JEQ 60
MOV AX,3E
DIV 3F
EAP 'DIVISION:'
;OUT 1,AX
JMP 9
MSG 'FIN'
HLT
#40
1
10
11
100
101
110
0
#50
LDT 'Introdusca el PRIMER número:'
MOV 3E,AX
LDT 'Introdusca el SEGUNDO número:'
MOV 3F,AX
JMP 9
#60
MSG 'Para la División el SEGUNDO número debe ser diferente de 0'
JMP 52
;PROGRAMA PARA ORDENAR 3 NUMERO E MENOR A MAYOR
;POR EL METODO DE LA BURBUJA
MSG 'ORDENAR 3 NUMEROS DE MENOR A MAYOR'
MSG 'INTRODUSCA LOS DATOS A NUMERAR'
LDT 'ENTRODUSCA EL VALOR DE A:'
MOV 20,AX
LDT 'ENTRODUSCA EL VALOR DE B:'
MOV 21,AX
LDT 'ENTRODUSCA EL VALOR DE C:'
MOV 22,AX
; A MAYOR QUE B
;MOV CX,19
MOV AX,20
CMP 21
JMA 80
JEQ 40
JMP 50
;LOOP 5
;JMP 15
HLT
#40
; B MAYOR QUE C
MOV AX,21
CMP 22
JMA 90
JEQ 15
JMP 60
#50
; A MENOR QUE B
MOV AX,21
CMP 20
JME 40
JMP 60
#60
; B MENOR QUE C
MOV AX,22
CMP 21
JME 90
JMP 15
#15
MOV AX,20
EAP 'A'
MOV AX,21
EAP 'B'
MOV AX,22
EAP 'C'
JMP 0D
#80
MOV AX,20
MOV 25,AX
MOV AX,21
MOV 20,AX
MOV AX,25
MOV 21,AX
JMP 40
#90
MOV AX,21
MOV 25,AX
MOV AX,22
MOV 21,AX
MOV AX,25
MOV 22,AX
JMP 08
;Ecuación de 2do Grado
MSG 'Programa Ecuación de 2do Grado'
;MSG 'Introduzca el valor de "a"'
LDT 'Introduzca el valor de "a"' ;Leo el Valor de A=
MOV 4A,AX ;Grabo el numero en la dir 4A y 4B
;MSG 'Introduzca el Valor de "b"'
LDT 'Introduzca el valor de "b"' ;Leo el valor de B=
MOV 4C,AX ;Grabo el numero en la dir 4C y 4D
;MSG 'Introduzca el Valor de "c"'
LDT 'Introduzca el valor de "c"' ;Leo el valor de C=
MOV 4E,AX ;Grabo el numero en la dir 4E y 4F
JMP 90
MSG '-b'
MOV AX,5A
EAP 5A
;d=b*b-4.0*a*c
MOV 4C,AX
MUL 4C
SUB 64
MUL 4A
MUL 4E
MOV AX,50
JMP 95
MOV AX,50
MSG 'd='
EAP 50
CMP 55
JMA 60 ;d es mayor a 0
JEQ 60 ;d es igual a 0
JMP 80 ;si b es menor a 0 salta a la pos 80
;Inicializo las constantes 1 y 2 en IEEE 754
#50
0011111110000000 ;Inicializo el Numero 1 en la dir 30 y 31
0000000000000000
0100000000000000 ;numero 2 en la dir 32 y 33
0000000000000000
110
0
010
#60
; X1=(-b+SQR(b))/a/2.0
MOV AX,5A ;-b
ADD 100 ;raiz de b
DIV 4A
DIV 56
MOV 6A,AX
; X2=(-b-SQR(b))/a/2.0
MOV AX,5A ;-b
SUB 100
DIV 4A
DIV 56
MOV 6D,AX
JMP 120
#80
;X2=sqr(-d)/a/2
MOV AX,5C ;-d
;LDF 110 ;Raiz de -d
DIV 4A
DIV 56
MOV 6D,AX
;X1=-b/0/2
MOV AX,5A ;-b
DIV 4A
DIV 56
MOV 6A,AX
JMP 120
#90 ; -b
MOV AX,55
MSG 'Negando b'
SUB 4C
MOV 5A,AX
EAP 5A
JMP 0C
#95 ; -d
MOV AX,55
MSG 'Negando d'
SUB 50
MOV 5C
OUT 1,AX
JMP 16
# 120
;Mostrar datos en Pantall
MSG 'El valor de X1 es:'
MOV AX,6A
EAP 'X='
MSG 'El valor de X2 es:'
MOV AX,6D
EAP 'X2'
HLT
;PROGRAMA DE MENUS
MSG 'MENU PRINCIPAL'
MSG 'Escriba 1: para Introducir datos'
MSG 'Escriba 2: para salir'
LDT 'Introdusca 1 Ó 2'
CMP 40
JEQ 50 ;COMPARO SI ES =
CMP 41
JEQ 33
JMP 0
MSG 'MENU SECUNDARIO'
MSG 'Que Operasión quiere realizar:?'
MSG '1: SUMAR'
MSG '2: RESATAR'
MSG '3: MULTIPLICAR'
MSG '4: DIVIDIR'
MSG '5: CARGAR DATOS'
MSG '6: MENU PRINCIPAL'
LDT 'Opsión:'
CMP 40
JEQ 20
JME 9
CMP 41
JEQ 24
CMP 42
JEQ 28
CMP 43
JEQ 2C
CMP 44
JEQ 50
CMP 45
JEQ 0
JMA 9
MOV AX,3E
ADD 3F
EAP 'SUMA:'
JMP 9
MOV AX,3E
SUB 3F
EAP 'RESTA:'
JMP 9
MOV AX,3E
MUL 3F
EAP 'MULTIPLICASION:'
JMP 9
LDA 3F
CMP 47
JEQ 60
MOV AX,3E
DIV 3F
EAP 'DIVISION:'
;OUT 1,AX
JMP 9
MSG 'FIN'
HLT
#40
1
10
11
100
101
110
0
#50
LDT 'Introdusca el PRIMER número:'
MOV 3E,AX
LDT 'Introdusca el SEGUNDO número:'
MOV 3F,AX
JMP 9
#60
MSG 'Para la División el SEGUNDO número debe ser diferente de 0'
JMP 52
;PROGRAMA PARA ORDENAR 3 NUMERO E MENOR A MAYOR
;POR EL METODO DE LA BURBUJA
MSG 'ORDENAR 3 NUMEROS DE MENOR A MAYOR'
MSG 'INTRODUSCA LOS DATOS A NUMERAR'
LDT 'ENTRODUSCA EL VALOR DE A:'
MOV 20,AX
LDT 'ENTRODUSCA EL VALOR DE B:'
MOV 21,AX
LDT 'ENTRODUSCA EL VALOR DE C:'
MOV 22,AX
; A MAYOR QUE B
;MOV CX,19
MOV AX,20
CMP 21
JMA 80
JEQ 40
JMP 50
;LOOP 5
;JMP 15
HLT
#40
; B MAYOR QUE C
MOV AX,21
CMP 22
JMA 90
JEQ 15
JMP 60
#50
; A MENOR QUE B
MOV AX,21
CMP 20
JME 40
JMP 60
#60
; B MENOR QUE C
MOV AX,22
CMP 21
JME 90
JMP 15
#15
MOV AX,20
EAP 'A'
MOV AX,21
EAP 'B'
MOV AX,22
EAP 'C'
JMP 0D
#80
MOV AX,20
MOV 25,AX
MOV AX,21
MOV 20,AX
MOV AX,25
MOV 21,AX
JMP 40
#90
MOV AX,21
MOV 25,AX
MOV AX,22
MOV 21,AX
MOV AX,25
MOV 22,AX
JMP 08
DIRECTIVAS (Instrucciones para el ensamblador)
DIRECTIVAS (Instrucciones para el ensamblador)
Definición de símbolos
EQU: Define nombres simbólicos que representan valores u otros valores simbólicos. Las dos formas son:
nombre EQU expresión
nuevo_nombre EQU viejo_nombre
Una vez definido un nombre mediante EQU, no se puede volver a definir.
=: Es similar a EQU pero permite que el símbolo se pueda redefinir. Sólo admite la forma: nombre =
expresión.
Definición de datos
Ubica memoria para un ítem de datos y opcionalmente asocia un nombre simbólico con esa dirección de memoria y/o genera el valor inicial para ese ítem.
[nombre] DB valor_inicial [, valor_inicial...]
donde valor_inicial puede ser una cadena o una expresión numérica cuyo resultado esté entre -255 y 255.
[nombre] DW valor_inicial [, valor_inicial...]
donde valor_inicial puede ser una expresión numérica cuyo resultado esté entre -65535 y 65535 o un operando de memoria en cuyo caso se almacenará el offset del mismo.
[nombre] DD valor_inicial [, valor_inicial...]
donde valor_inicial puede ser una constante cuyo valor esté entre -4294967295 y 4294967295, una expresión numérica cuyo valor absoluto no supere 65535, o bien un operando de memoria en cuyo caso se almacenarán el offset y el segmento del mismo (en ese orden).
Si se desea que no haya valor inicial, deberá utilizarse el símbolo ?.
Otra forma de expresar el valor inicial es:
cuenta DUP (valor_inicial [, valor_inicial...]) donde cuenta es la cantidad de veces que debe repetirse lo que está entre paréntesis.
Definición de segmentos
Organizan el programa para utilizar los segmentos de memoria del microprocesador 8088. Estos son SEGMENT, ENDS, DOSSEG, ASSUME, GROUP.
nombre_segm SEGMENT [alineación][combinación]['clase'] sentencias nombre_segm ENDS
Alineación: define el rango de direcciones de memoria para el cual puede elegirse el inicio del segmento.
Hay cinco posibles:
1. BYTE: El segmento comienza en el siguiente byte.
2. WORD: El segmento comienza en la siguiente dirección par.
3. DWORD: Comienza en la siguiente dirección múltiplo de 4.
4. PARA: Comienza en la siguiente dirección múltiplo de 16.
5. PAGE: Comienza en la siguiente dirección múltiplo de 256.
Si no se indica la alineación ésta será PARA.
Combinación: define cómo combinar segmentos que tengan el mismo nombre. Hay cinco posibles:
1. PUBLIC: Concatena todos los segmentos que tienen el mismo nombre para formar un solo segmento. Todas las direcciones de datos e instrucciones se representan la distancia entre el inicio del segmento y la dirección correspondiente. La longitud del segmento formado será la suma de las longitudes de los segmentos con el mismo nombre.
2. STACK: Es similar a PUBLIC. La diferencia consiste que, al comenzar la ejecución del programa, el registro SS apuntará a este segmento y SP se inicializará con la longitud en bytes de este segmento.
3. COMMON: Pone el inicio de todos los segmentos teniendo el mismo nombre en la misma dirección de memoria. La longitud del segmento será la del segmento más largo.
4. MEMORY: Es igual a PUBLIC.
5. AT dirección_de_segmento: Hace que todas las etiquetas y direcciones de variables tengan el segmento especificado por la expresión contenida en dirección_de_segmento. Este segmento no puede contener código o datos con valores iniciales. Todos los símbolos que forman la expresión dirección_de_segmento deben conocerse en el primer paso de ensamblado.
Si no se indica combinación, el segmento no se combinará con otros del mismo nombre (combinación "privada").
Clase: Es una forma de asociar segmentos con diferentes nombres, pero con propósitos similares. Sirve también para identificar el segmento de código. Debe estar encerrado entre comillas simples.
El linker pone los segmentos que tengan la misma clase uno a continuación de otro, si bien siguen siendo segmentos diferentes. Además supone que los segmentos de código tiene clase CODE o un nombre con el sufijo CODE.
DOSSEG: Esta directiva especifica que los segmentos deben ordenarse según la convención de DOS.
Esta es la convención usada por los compiladores de lenguajes de alto nivel.
GROUP: Sirve para definir grupos de segmentos. Un grupo es una colección de segmentos asociados con la misma dirección inicial. De esta manera, aunque los datos estén en diferentes segmentos, todos pueden accederse mediante el mismo registro de segmento. Los segmentos de un grupo no necesitan ser contiguos.
Sintaxis: nombre_grupo GROUP segmento [, segmento...]
ASSUME: Sirve para indicar al ensamblador qué registro de segmento corresponde con un segmento determinado. Cuando el ensamblador necesita referenciar una dirección debe saber en qué registro de segmento lo apunta.
Sintaxis: ASSUME reg_segm:nombre [, reg_segm:nombre...] donde el nombre puede ser de segmento o de grupo, una expresión utilizando el operador SEG o la palabra NOTHING, que cancela la selección de registro de segmento hecha con un ASSUME anterior.
Control del ensamblador
ORG expresión: El offset del código o datos a continuación será la indicada por la expresión. Todos los símbolos que forman la expresión deben conocerse en el primer paso de ensamblado.
EVEN: Hace que la próxima instrucción o dato se ensamble en la siguiente posición par.
END [etiqueta]: Debe ser la última sentencia del código fuente. La etiqueta indica dónde debe comenzar la ejecución del programa. Si el programa se compone de varios módulos, sólo el módulo que contiene la dirección de arranque del programa debe contener la directiva END etiqueta. Los demás módulos deberán terminar con la directiva END (sin etiqueta).
Definición de procedimientos
Los procedimientos son secciones de código que se pueden llamar para su ejecución desde distintas partes del programa.
etiqueta PROC {NEARFAR}
sentencias
etiqueta ENDP
Ensamblado condicional
Verifican una condición determinada y si se cumple, ensambla una porción de código. Opcionalmente puede ensamblarse otra porción de código si la condición no se cumple. Son los siguientes: IF, IF1, IF2, IFB, IFDEF, IFDIF, IFE, IFIDN, IFNB, IFNDEF, ENDIF, ELSE.
{IFIFE} condición
sentencias ;Se ejecutan si es cierta (IF) o falsa (IFE).
[ELSE sentencias] ;Se ejecutan si es falsa (IF) o cierta (IFE).
ENDIF
La directiva ELSE y sus sentencias son opcionales. ENDIF termina el bloque y es obligatorio. Se pueden anidar directivas condicionales.
IF1 permite el ensamblado de las sentencias sólo en el primer paso, mientras que IF2 lo permite en el segundo paso.
IFDEF nombre permite el ensamblado de las sentencias si el nombre está definido, mientras que IFNDEF nombre lo permite si no está definido.
IFB permite el ensamblado si el argumento en una macro es blanco (no se pasó el argumento).
IFNB permite el ensamblado si el argumento en una macro no es blanco (se pasó el argumento).
IFIDN, permite el ensamblado si los dos parámetros pasados a la macro son idénticos.
IFDIF, permite el ensamblado si los dos parámetros pasados a la macro son diferentes.
Macros: Las macros asignan un nombre simbólico a un bloque de sentencias fuente. Luego se puede usar dicho nombre para representar esas sentencias. Opcionalmente se pueden definir parámetros para representar argumentos para la macro.
Definición de macros
nombre_macro MACRO [parámetro [,parámetro...]]
[LOCAL nombre_local[,nombre_local...] sentencias
ENDM
Los parámetros son opcionales. Si existen, entonces también aparecerán en algunas de las sentencias en la definición de la macro. Al invocar la macro mediante: nombre_macro [argumento [,argumento..]] se ensamblarán las sentencias indicadas en la macro teniendo en cuenta que cada lugar donde aparezca un parámetro se reemplazará por el argumento correspondiente.
El nombre_local de la directiva LOCAL es un nombre simbólico temporario que será reemplazado por un único nombre simbólico (de la forma ??número) cuando la macro se invoque.
Todas las etiquetas dentro de la macro deberán estar indicadas en la directiva LOCAL para que el ensamblador no genere un error indicando que un símbolo está definido varias veces.
La directiva EXITM (usada dentro de la definición de la macro) sirve para que no se ensamblen más sentencias de la macro (se usa dentro de bloques condicionales).
PURGE nombre_macro [,nombre_macro...]: Borra las macros indicadas de la memoria para poder utilizar este espacio para otros símbolos.
Definición de bloques de repetición
Son tres: REPT, IRP e IRPC. Como en el caso de la directiva MACRO, se puede incluir la sentencias LOCAL y EXITM y deben terminarse con la directiva ENDM.
REPT expresión sentencias ENDM
La expresión debe poder ser evaluada en el primer paso del ensamblado y el resultado deberá estar entre 0 y 65535.
Esta expresión indica la cantidad de veces que debe repetirse el bloque.
IRP parámetro, sentencias
ENDM
El parámetro se reemplaza por el primer argumento y se ensamblan las sentencias dentro del bloque.
Luego el parámetro se reemplaza por el segundo argumento y se ensamblan las sentencias y así sucesivamente hasta agotar los argumentos.
IRPC parámetro, cadena sentencias
ENDM
Es similar a IRP con la diferencia que el parámetro se reemplaza por cada carácter de la cadena. Si ésta contiene comas, espacios u otros caracteres especiales deberá encerrarse con paréntesis angulares (<>).
Procesador: Indican el tipo de procesador y coprocesador en el que se va a ejecutar el programa. Los de procesador son: .8086, .186, .286, .386, .486 y .586 para instrucciones en modo real, .286P, .386P, .486P y .586P para instrucciones privilegiadas, .8087, .287 y .387 para coprocesadores. Deben ubicarse al principio del código fuente. Habilitan las instrucciones correspondientes al procesador y coprocesador indicado. Sin estas directivas, sólo se pueden ensamblar instrucciones del 8086 y 8087.
Referencias externas al módulo
Sirve para poder particionar un programa en varios archivos fuentes o módulos. Son imprescindibles si se hace un programa en alto nivel con procedimientos en assembler. Hay tres: PUBLIC, EXTRN e INCLUDE.
PUBLIC nombre[, nombre...]: Estos nombres simbólicos se escriben en el archivo objeto. Durante una sesión con el linker, los símbolos en diferentes módulos pero con los mismos nombres tendrán la misma dirección.
EXTRN nombre:tipo [,nombre:tipo...]: Define una variable externa con el nombre y tipo (NEAR, FAR, BYTE, WORD, DWORD o ABS (número constante especificado con la directiva EQU o =)) especificado. El tipo debe ser el mismo que el del ítem indicado con la directiva PUBLIC en otro módulo.
INCLUDE nombre_de_archivo: Ensambla las sentencias indicadas en dicho archivo.
Segmentos simplificados
Permite definir los segmentos sin necesidad de utilizar las directivas de segmentos que aparecen más arriba.
.MODEL modelo: Debe estar ubicada antes de otra directiva de segmento. El modelo puede ser uno de los siguientes:
1. TINY: Los datos y el código juntos ocupan menos de 64 KB por lo que entran en el mismo segmento. Se utiliza para programas .COM. Algunos ensambladores no soportan este modelo.
2. SMALL: Los datos caben en un segmento de 64 KB y el código cabe en otro segmento de 64 KB.
Por lo tanto todo el código y los datos se pueden acceder como NEAR.
3. MEDIUM: Los datos entran en un sólo segmento de 64 KB, pero el código puede ser mayor de 64KB. Por lo tanto, código es FAR, mientras que los datos se acceden como NEAR.
4. COMPACT: Todo el código entra en un segmento de 64 KB, pero los datos no (pero no pueden haber matrices de más de 64 KB). Por lo tanto, código es NEAR, mientras que los datos se acceden como FAR.
5. LARGE: Tanto el código como los datos pueden ocupar más de 64 KB (pero no pueden haber matrices de más de 64 KB), por lo que ambos se acceden como FAR.
6. HUGE: Tanto el código como los datos pueden ocupar más de 64 KB (y las matrices también), por lo que ambos se acceden como FAR y los punteros a los elementos de las matrices también son FAR.
.STACK [size]: Define el segmento de pila de la longitud especificada.
.CODE [name]: Define el segmento de código.
.DATA: Define un segmento de datos NEAR con valores iniciales.
.DATA?: Define un segmento de datos NEAR sin valores iniciales.
.FARDATA [name]: Define un segmento de datos FAR con valores iniciales.
.FARDATA? [name]: Define un segmento de datos FAR sin valores iniciales.
.CONST: Sefine un segmento de datos constantes.
Los siguientes símbolos están definidos cuando se usan las directivas anteriores:
@curseg: Tiene el nombre del segmento que se está ensamblando.
@filename: Representa el nombre del archivo fuente (sin la extensión)
@codesize: Vale 0 para los modelos SMALL y COMPACT (código NEAR), y vale 1 para los modelos MEDIUM, LARGE y HUGE (código FAR).
@datasize: Vale 0 para los modelos SMALL y MEDIUM (datos NEAR), vale 1 para los modelos COMPACT y LARGE (datos FAR) y vale 2 para el modelo HUGE (punteros a matrices FAR).
@code: Nombre del segmento definido con la directiva .CODE.
@data: Nombre del segmento definido con la directivas .DATA, .DATA?, .CONST y .STACK (los cuatro están en el mismo segmento).
@fardata: Nombre del segmento definido con la directiva .FARDATA.
@fardata?: Nombre del segmento definido con la directiva .FARDATA?.
Definición de símbolos
EQU: Define nombres simbólicos que representan valores u otros valores simbólicos. Las dos formas son:
nombre EQU expresión
nuevo_nombre EQU viejo_nombre
Una vez definido un nombre mediante EQU, no se puede volver a definir.
=: Es similar a EQU pero permite que el símbolo se pueda redefinir. Sólo admite la forma: nombre =
expresión.
Definición de datos
Ubica memoria para un ítem de datos y opcionalmente asocia un nombre simbólico con esa dirección de memoria y/o genera el valor inicial para ese ítem.
[nombre] DB valor_inicial [, valor_inicial...]
donde valor_inicial puede ser una cadena o una expresión numérica cuyo resultado esté entre -255 y 255.
[nombre] DW valor_inicial [, valor_inicial...]
donde valor_inicial puede ser una expresión numérica cuyo resultado esté entre -65535 y 65535 o un operando de memoria en cuyo caso se almacenará el offset del mismo.
[nombre] DD valor_inicial [, valor_inicial...]
donde valor_inicial puede ser una constante cuyo valor esté entre -4294967295 y 4294967295, una expresión numérica cuyo valor absoluto no supere 65535, o bien un operando de memoria en cuyo caso se almacenarán el offset y el segmento del mismo (en ese orden).
Si se desea que no haya valor inicial, deberá utilizarse el símbolo ?.
Otra forma de expresar el valor inicial es:
cuenta DUP (valor_inicial [, valor_inicial...]) donde cuenta es la cantidad de veces que debe repetirse lo que está entre paréntesis.
Definición de segmentos
Organizan el programa para utilizar los segmentos de memoria del microprocesador 8088. Estos son SEGMENT, ENDS, DOSSEG, ASSUME, GROUP.
nombre_segm SEGMENT [alineación][combinación]['clase'] sentencias nombre_segm ENDS
Alineación: define el rango de direcciones de memoria para el cual puede elegirse el inicio del segmento.
Hay cinco posibles:
1. BYTE: El segmento comienza en el siguiente byte.
2. WORD: El segmento comienza en la siguiente dirección par.
3. DWORD: Comienza en la siguiente dirección múltiplo de 4.
4. PARA: Comienza en la siguiente dirección múltiplo de 16.
5. PAGE: Comienza en la siguiente dirección múltiplo de 256.
Si no se indica la alineación ésta será PARA.
Combinación: define cómo combinar segmentos que tengan el mismo nombre. Hay cinco posibles:
1. PUBLIC: Concatena todos los segmentos que tienen el mismo nombre para formar un solo segmento. Todas las direcciones de datos e instrucciones se representan la distancia entre el inicio del segmento y la dirección correspondiente. La longitud del segmento formado será la suma de las longitudes de los segmentos con el mismo nombre.
2. STACK: Es similar a PUBLIC. La diferencia consiste que, al comenzar la ejecución del programa, el registro SS apuntará a este segmento y SP se inicializará con la longitud en bytes de este segmento.
3. COMMON: Pone el inicio de todos los segmentos teniendo el mismo nombre en la misma dirección de memoria. La longitud del segmento será la del segmento más largo.
4. MEMORY: Es igual a PUBLIC.
5. AT dirección_de_segmento: Hace que todas las etiquetas y direcciones de variables tengan el segmento especificado por la expresión contenida en dirección_de_segmento. Este segmento no puede contener código o datos con valores iniciales. Todos los símbolos que forman la expresión dirección_de_segmento deben conocerse en el primer paso de ensamblado.
Si no se indica combinación, el segmento no se combinará con otros del mismo nombre (combinación "privada").
Clase: Es una forma de asociar segmentos con diferentes nombres, pero con propósitos similares. Sirve también para identificar el segmento de código. Debe estar encerrado entre comillas simples.
El linker pone los segmentos que tengan la misma clase uno a continuación de otro, si bien siguen siendo segmentos diferentes. Además supone que los segmentos de código tiene clase CODE o un nombre con el sufijo CODE.
DOSSEG: Esta directiva especifica que los segmentos deben ordenarse según la convención de DOS.
Esta es la convención usada por los compiladores de lenguajes de alto nivel.
GROUP: Sirve para definir grupos de segmentos. Un grupo es una colección de segmentos asociados con la misma dirección inicial. De esta manera, aunque los datos estén en diferentes segmentos, todos pueden accederse mediante el mismo registro de segmento. Los segmentos de un grupo no necesitan ser contiguos.
Sintaxis: nombre_grupo GROUP segmento [, segmento...]
ASSUME: Sirve para indicar al ensamblador qué registro de segmento corresponde con un segmento determinado. Cuando el ensamblador necesita referenciar una dirección debe saber en qué registro de segmento lo apunta.
Sintaxis: ASSUME reg_segm:nombre [, reg_segm:nombre...] donde el nombre puede ser de segmento o de grupo, una expresión utilizando el operador SEG o la palabra NOTHING, que cancela la selección de registro de segmento hecha con un ASSUME anterior.
Control del ensamblador
ORG expresión: El offset del código o datos a continuación será la indicada por la expresión. Todos los símbolos que forman la expresión deben conocerse en el primer paso de ensamblado.
EVEN: Hace que la próxima instrucción o dato se ensamble en la siguiente posición par.
END [etiqueta]: Debe ser la última sentencia del código fuente. La etiqueta indica dónde debe comenzar la ejecución del programa. Si el programa se compone de varios módulos, sólo el módulo que contiene la dirección de arranque del programa debe contener la directiva END etiqueta. Los demás módulos deberán terminar con la directiva END (sin etiqueta).
Definición de procedimientos
Los procedimientos son secciones de código que se pueden llamar para su ejecución desde distintas partes del programa.
etiqueta PROC {NEARFAR}
sentencias
etiqueta ENDP
Ensamblado condicional
Verifican una condición determinada y si se cumple, ensambla una porción de código. Opcionalmente puede ensamblarse otra porción de código si la condición no se cumple. Son los siguientes: IF, IF1, IF2, IFB, IFDEF, IFDIF, IFE, IFIDN, IFNB, IFNDEF, ENDIF, ELSE.
{IFIFE} condición
sentencias ;Se ejecutan si es cierta (IF) o falsa (IFE).
[ELSE sentencias] ;Se ejecutan si es falsa (IF) o cierta (IFE).
ENDIF
La directiva ELSE y sus sentencias son opcionales. ENDIF termina el bloque y es obligatorio. Se pueden anidar directivas condicionales.
IF1 permite el ensamblado de las sentencias sólo en el primer paso, mientras que IF2 lo permite en el segundo paso.
IFDEF nombre permite el ensamblado de las sentencias si el nombre está definido, mientras que IFNDEF nombre lo permite si no está definido.
IFB
IFNB
IFIDN
IFDIF
Macros: Las macros asignan un nombre simbólico a un bloque de sentencias fuente. Luego se puede usar dicho nombre para representar esas sentencias. Opcionalmente se pueden definir parámetros para representar argumentos para la macro.
Definición de macros
nombre_macro MACRO [parámetro [,parámetro...]]
[LOCAL nombre_local[,nombre_local...] sentencias
ENDM
Los parámetros son opcionales. Si existen, entonces también aparecerán en algunas de las sentencias en la definición de la macro. Al invocar la macro mediante: nombre_macro [argumento [,argumento..]] se ensamblarán las sentencias indicadas en la macro teniendo en cuenta que cada lugar donde aparezca un parámetro se reemplazará por el argumento correspondiente.
El nombre_local de la directiva LOCAL es un nombre simbólico temporario que será reemplazado por un único nombre simbólico (de la forma ??número) cuando la macro se invoque.
Todas las etiquetas dentro de la macro deberán estar indicadas en la directiva LOCAL para que el ensamblador no genere un error indicando que un símbolo está definido varias veces.
La directiva EXITM (usada dentro de la definición de la macro) sirve para que no se ensamblen más sentencias de la macro (se usa dentro de bloques condicionales).
PURGE nombre_macro [,nombre_macro...]: Borra las macros indicadas de la memoria para poder utilizar este espacio para otros símbolos.
Definición de bloques de repetición
Son tres: REPT, IRP e IRPC. Como en el caso de la directiva MACRO, se puede incluir la sentencias LOCAL y EXITM y deben terminarse con la directiva ENDM.
REPT expresión sentencias ENDM
La expresión debe poder ser evaluada en el primer paso del ensamblado y el resultado deberá estar entre 0 y 65535.
Esta expresión indica la cantidad de veces que debe repetirse el bloque.
IRP parámetro,
ENDM
El parámetro se reemplaza por el primer argumento y se ensamblan las sentencias dentro del bloque.
Luego el parámetro se reemplaza por el segundo argumento y se ensamblan las sentencias y así sucesivamente hasta agotar los argumentos.
IRPC parámetro, cadena sentencias
ENDM
Es similar a IRP con la diferencia que el parámetro se reemplaza por cada carácter de la cadena. Si ésta contiene comas, espacios u otros caracteres especiales deberá encerrarse con paréntesis angulares (<>).
Procesador: Indican el tipo de procesador y coprocesador en el que se va a ejecutar el programa. Los de procesador son: .8086, .186, .286, .386, .486 y .586 para instrucciones en modo real, .286P, .386P, .486P y .586P para instrucciones privilegiadas, .8087, .287 y .387 para coprocesadores. Deben ubicarse al principio del código fuente. Habilitan las instrucciones correspondientes al procesador y coprocesador indicado. Sin estas directivas, sólo se pueden ensamblar instrucciones del 8086 y 8087.
Referencias externas al módulo
Sirve para poder particionar un programa en varios archivos fuentes o módulos. Son imprescindibles si se hace un programa en alto nivel con procedimientos en assembler. Hay tres: PUBLIC, EXTRN e INCLUDE.
PUBLIC nombre[, nombre...]: Estos nombres simbólicos se escriben en el archivo objeto. Durante una sesión con el linker, los símbolos en diferentes módulos pero con los mismos nombres tendrán la misma dirección.
EXTRN nombre:tipo [,nombre:tipo...]: Define una variable externa con el nombre y tipo (NEAR, FAR, BYTE, WORD, DWORD o ABS (número constante especificado con la directiva EQU o =)) especificado. El tipo debe ser el mismo que el del ítem indicado con la directiva PUBLIC en otro módulo.
INCLUDE nombre_de_archivo: Ensambla las sentencias indicadas en dicho archivo.
Segmentos simplificados
Permite definir los segmentos sin necesidad de utilizar las directivas de segmentos que aparecen más arriba.
.MODEL modelo: Debe estar ubicada antes de otra directiva de segmento. El modelo puede ser uno de los siguientes:
1. TINY: Los datos y el código juntos ocupan menos de 64 KB por lo que entran en el mismo segmento. Se utiliza para programas .COM. Algunos ensambladores no soportan este modelo.
2. SMALL: Los datos caben en un segmento de 64 KB y el código cabe en otro segmento de 64 KB.
Por lo tanto todo el código y los datos se pueden acceder como NEAR.
3. MEDIUM: Los datos entran en un sólo segmento de 64 KB, pero el código puede ser mayor de 64KB. Por lo tanto, código es FAR, mientras que los datos se acceden como NEAR.
4. COMPACT: Todo el código entra en un segmento de 64 KB, pero los datos no (pero no pueden haber matrices de más de 64 KB). Por lo tanto, código es NEAR, mientras que los datos se acceden como FAR.
5. LARGE: Tanto el código como los datos pueden ocupar más de 64 KB (pero no pueden haber matrices de más de 64 KB), por lo que ambos se acceden como FAR.
6. HUGE: Tanto el código como los datos pueden ocupar más de 64 KB (y las matrices también), por lo que ambos se acceden como FAR y los punteros a los elementos de las matrices también son FAR.
.STACK [size]: Define el segmento de pila de la longitud especificada.
.CODE [name]: Define el segmento de código.
.DATA: Define un segmento de datos NEAR con valores iniciales.
.DATA?: Define un segmento de datos NEAR sin valores iniciales.
.FARDATA [name]: Define un segmento de datos FAR con valores iniciales.
.FARDATA? [name]: Define un segmento de datos FAR sin valores iniciales.
.CONST: Sefine un segmento de datos constantes.
Los siguientes símbolos están definidos cuando se usan las directivas anteriores:
@curseg: Tiene el nombre del segmento que se está ensamblando.
@filename: Representa el nombre del archivo fuente (sin la extensión)
@codesize: Vale 0 para los modelos SMALL y COMPACT (código NEAR), y vale 1 para los modelos MEDIUM, LARGE y HUGE (código FAR).
@datasize: Vale 0 para los modelos SMALL y MEDIUM (datos NEAR), vale 1 para los modelos COMPACT y LARGE (datos FAR) y vale 2 para el modelo HUGE (punteros a matrices FAR).
@code: Nombre del segmento definido con la directiva .CODE.
@data: Nombre del segmento definido con la directivas .DATA, .DATA?, .CONST y .STACK (los cuatro están en el mismo segmento).
@fardata: Nombre del segmento definido con la directiva .FARDATA.
@fardata?: Nombre del segmento definido con la directiva .FARDATA?.
OPERADORES
OPERADORES
Operadores aritméticos
+, -, *, /, MOD (resto de la división).
Operadores lógicos AND, OR, XOR, NOT, SHR, SHL.
Para los dos últimos operadores, el operando derecho indica la cantidad de bits a desplazar hacia la derecha (para SHR) o izquierda (para SHL) el operando izquierdo.
Operadores relacionales
Valen cero si son falsos y 65535 si son verdaderos.
EQ: Igual a.
NE: Distinto de.
LT: Menor que.
GT: Mayor que.
LE: Menor o igual a.
GE: Mayor o igual a.
Operadores analíticos
Descomponen operandos que representan direcciones de memoria en sus componentes.
SEG memory-operand: Retorna el valor del segmento.
OFFSET memory-operand: Retorna el valor del offset.
TYPE memory-operand: Retorna un valor que representa el tipo de operando: BYTE = 1, WORD = 2, DWORD = 4 (para direcciones de datos) y NEAR = -1 y FAR = -2 (para direcciones de instrucciones).
LENGHT memory-operand: Se aplica solamente a direcciones de datos. Retorna un valor numérico para el número de unidades (bytes, words o dwords) asociados con el operando. Si el operando es una cadena retorna el valor 1.
Ejemplo: Dada la directiva PALABRAS DW 50 DUP (0), el valor de LENGHT PALABRAS es 50, mientras que dada la directiva CADENA DB "cadena" el valor de LENGHT CADENA es 1.
SIZE memory-operand: LENGHT memory-operand * TYPE memory-operand.
Operadores sintéticos
Componen operandos de direcciones de memoria a partir de sus componentes.
type PTR memory-operand: Compone un operando de memoria que tiene el mismo segmento y offset que el especificado en el operando derecho pero con el tipo (BYTE, WORD, DWORD, NEAR o FAR) especificado en el operando izquierdo.
THIS type: Compone un operando de memoria con el tipo especificado que tiene el segmento y offset que la próxima ubicación a ensamblar.
Operadores de macros
Son operadores que se utilizan en las definiciones de macros. Hay cinco: &, <>, !, % y ;;.
&parámetro: reemplaza el parámetro con el valor actual del argumento.
: trata una serie de caracteres como una sola cadena. Se utiliza cuando el texto incluye comas, espacios u otros símbolos especiales.
!carácter: trata el carácter que sigue al operador ! como un carácter en vez de un símbolo o separador.
%texto: trata el texto que sigue a continuación del operador % como una expresión. El ensamblador calcula el valor de la expresión y reemplaza el texto por dicho valor.sentencia ;;comentario: Permite definir comentarios que aparecerán en la definición de la macro pero no cada vez que éste se invoque en el listado fuente que genera el ensamblador.
Operadores aritméticos
+, -, *, /, MOD (resto de la división).
Operadores lógicos AND, OR, XOR, NOT, SHR, SHL.
Para los dos últimos operadores, el operando derecho indica la cantidad de bits a desplazar hacia la derecha (para SHR) o izquierda (para SHL) el operando izquierdo.
Operadores relacionales
Valen cero si son falsos y 65535 si son verdaderos.
EQ: Igual a.
NE: Distinto de.
LT: Menor que.
GT: Mayor que.
LE: Menor o igual a.
GE: Mayor o igual a.
Operadores analíticos
Descomponen operandos que representan direcciones de memoria en sus componentes.
SEG memory-operand: Retorna el valor del segmento.
OFFSET memory-operand: Retorna el valor del offset.
TYPE memory-operand: Retorna un valor que representa el tipo de operando: BYTE = 1, WORD = 2, DWORD = 4 (para direcciones de datos) y NEAR = -1 y FAR = -2 (para direcciones de instrucciones).
LENGHT memory-operand: Se aplica solamente a direcciones de datos. Retorna un valor numérico para el número de unidades (bytes, words o dwords) asociados con el operando. Si el operando es una cadena retorna el valor 1.
Ejemplo: Dada la directiva PALABRAS DW 50 DUP (0), el valor de LENGHT PALABRAS es 50, mientras que dada la directiva CADENA DB "cadena" el valor de LENGHT CADENA es 1.
SIZE memory-operand: LENGHT memory-operand * TYPE memory-operand.
Operadores sintéticos
Componen operandos de direcciones de memoria a partir de sus componentes.
type PTR memory-operand: Compone un operando de memoria que tiene el mismo segmento y offset que el especificado en el operando derecho pero con el tipo (BYTE, WORD, DWORD, NEAR o FAR) especificado en el operando izquierdo.
THIS type: Compone un operando de memoria con el tipo especificado que tiene el segmento y offset que la próxima ubicación a ensamblar.
Operadores de macros
Son operadores que se utilizan en las definiciones de macros. Hay cinco: &, <>, !, % y ;;.
&parámetro: reemplaza el parámetro con el valor actual del argumento.
!carácter: trata el carácter que sigue al operador ! como un carácter en vez de un símbolo o separador.
%texto: trata el texto que sigue a continuación del operador % como una expresión. El ensamblador calcula el valor de la expresión y reemplaza el texto por dicho valor.sentencia ;;comentario: Permite definir comentarios que aparecerán en la definición de la macro pero no cada vez que éste se invoque en el listado fuente que genera el ensamblador.
INSTRUCCIONES DE CONTROL DEL PROCESADOR
INSTRUCCIONES DE CONTROL DEL PROCESADOR
CLC
CF <- 0.
STC
CF <- 1.
CMC
CF <- 1 - CF.
NOP
No hace nada.
CLD
DF <- 0 (Dirección ascendente).
STD
DF <- 1 (Dirección descendente).
CLI
IF <- 0 (Deshabilita interrupciones enmascarables).
STI
IF <- 1 (Habilita interrupciones enmascarables).
HLT
Detiene la ejecución del procesador hasta que llegue una interrupción externa.
WAIT
Detiene la ejecución del procesador hasta que se active el pin TEST del mismo.
LOCKPrefijo de instrucción que activa el pin LOCK del procesador.
CLC
CF <- 0.
STC
CF <- 1.
CMC
CF <- 1 - CF.
NOP
No hace nada.
CLD
DF <- 0 (Dirección ascendente).
STD
DF <- 1 (Dirección descendente).
CLI
IF <- 0 (Deshabilita interrupciones enmascarables).
STI
IF <- 1 (Habilita interrupciones enmascarables).
HLT
Detiene la ejecución del procesador hasta que llegue una interrupción externa.
WAIT
Detiene la ejecución del procesador hasta que se active el pin TEST del mismo.
LOCKPrefijo de instrucción que activa el pin LOCK del procesador.
INSTRUCCIONES DE TRANSFERENCIA DE CONTROL
INSTRUCCIONES DE TRANSFERENCIA DE CONTROL
(No afectan los flags):
JMP label
Saltar hacia la dirección label.
CALL label
Ir al procedimiento cuyo inicio es label. Para llamadas dentro del mismo segmento equivale a PUSH IP: JMP label, mientras que para llamadas entre segmentos equivale a PUSH CS: PUSH IP:
JMP label.
RET
Retorno de procedimiento.
RET inmed
Retorno de procedimiento y SP <- SP + inmed.
Variaciones de la instrucción de retorno:
RETN [inmed]
En el mismo segmento de código. Equivale a POP IP [:SP <- SP + inmed].
RETF [inmed]
En otro segmento de código. Equivale a POP IP: POP CS [:SP <- SP + inmed]
Saltos condicionales aritméticos (usar después de CMP):
Aritmética signada (con números positivos, negativos y cero)
JL etiqueta/JNGE etiqueta
Saltar a etiqueta si es menor.
JLE etiqueta/JNG etiqueta
Saltar a etiqueta si es menor o igual.
JE etiqueta
Saltar a etiqueta si es igual.
JNE etiqueta
Saltar a etiqueta si es distinto.
JGE etiqueta/JNL etiqueta
Saltar a etiqueta si es mayor o igual.
JG etiqueta/JNLE etiqueta
Saltar a etiqueta si es mayor.
Aritmética sin signo (con números positivos y cero)
JB etiqueta/JNAE etiqueta
Saltar a etiqueta si es menor.
JBE etiqueta/JNA etiqueta
Saltar a etiqueta si es menor o igual.
JE etiqueta
Saltar a etiqueta si es igual.
JNE etiqueta
Saltar a etiqueta si es distinto.
JAE etiqueta/JNB etiqueta
Saltar a etiqueta si es mayor o igual.
JA etiqueta/JNBE etiqueta
Saltar a etiqueta si es mayor.
Saltos condicionales según el valor de los indicadores:
JC label
Saltar si hubo arrastre/préstamo (CF = 1).
JNC label
Saltar si no hubo arrastre/préstamo (CF = 0).
JZ label
Saltar si el resultado es cero (ZF = 1).
JNZ label
Saltar si el resultado no es cero (ZF = 0).
JS label
Saltar si el signo es negativo (SF = 1).
JNS label
Saltar si el signo es positivo (SF = 0).
JP/JPE label
Saltar si la paridad es par (PF = 1).
JNP/JPO label
Saltar si la paridad es impar (PF = 0).
Saltos condicionales que usan el registro CX como contador:
LOOP label
Operación: CX <- CX-1. Saltar a label si CX<>0.
LOOPZ/LOOPE label
Operación: CX <- CX-1. Saltar a label si CX <> 0 y ZF = 1.
LOOPNZ/LOOPNE label
Operación: CX <- CX-1. Saltar a label si CX <> 0 y ZF = 0.
JCXZ label
Operación: Salta a label si CX = 0.
Interrupciones:
INT número
Salva los flags en la pila, hace TF=IF=0 y ejecuta la interrupción con el número indicado.
INTO
Interrupción condicional. Si OF = 1, hace INT 4.
IRETRetorno de interrupción. Restaura los indicadores del stack
(No afectan los flags):
JMP label
Saltar hacia la dirección label.
CALL label
Ir al procedimiento cuyo inicio es label. Para llamadas dentro del mismo segmento equivale a PUSH IP: JMP label, mientras que para llamadas entre segmentos equivale a PUSH CS: PUSH IP:
JMP label.
RET
Retorno de procedimiento.
RET inmed
Retorno de procedimiento y SP <- SP + inmed.
Variaciones de la instrucción de retorno:
RETN [inmed]
En el mismo segmento de código. Equivale a POP IP [:SP <- SP + inmed].
RETF [inmed]
En otro segmento de código. Equivale a POP IP: POP CS [:SP <- SP + inmed]
Saltos condicionales aritméticos (usar después de CMP):
Aritmética signada (con números positivos, negativos y cero)
JL etiqueta/JNGE etiqueta
Saltar a etiqueta si es menor.
JLE etiqueta/JNG etiqueta
Saltar a etiqueta si es menor o igual.
JE etiqueta
Saltar a etiqueta si es igual.
JNE etiqueta
Saltar a etiqueta si es distinto.
JGE etiqueta/JNL etiqueta
Saltar a etiqueta si es mayor o igual.
JG etiqueta/JNLE etiqueta
Saltar a etiqueta si es mayor.
Aritmética sin signo (con números positivos y cero)
JB etiqueta/JNAE etiqueta
Saltar a etiqueta si es menor.
JBE etiqueta/JNA etiqueta
Saltar a etiqueta si es menor o igual.
JE etiqueta
Saltar a etiqueta si es igual.
JNE etiqueta
Saltar a etiqueta si es distinto.
JAE etiqueta/JNB etiqueta
Saltar a etiqueta si es mayor o igual.
JA etiqueta/JNBE etiqueta
Saltar a etiqueta si es mayor.
Saltos condicionales según el valor de los indicadores:
JC label
Saltar si hubo arrastre/préstamo (CF = 1).
JNC label
Saltar si no hubo arrastre/préstamo (CF = 0).
JZ label
Saltar si el resultado es cero (ZF = 1).
JNZ label
Saltar si el resultado no es cero (ZF = 0).
JS label
Saltar si el signo es negativo (SF = 1).
JNS label
Saltar si el signo es positivo (SF = 0).
JP/JPE label
Saltar si la paridad es par (PF = 1).
JNP/JPO label
Saltar si la paridad es impar (PF = 0).
Saltos condicionales que usan el registro CX como contador:
LOOP label
Operación: CX <- CX-1. Saltar a label si CX<>0.
LOOPZ/LOOPE label
Operación: CX <- CX-1. Saltar a label si CX <> 0 y ZF = 1.
LOOPNZ/LOOPNE label
Operación: CX <- CX-1. Saltar a label si CX <> 0 y ZF = 0.
JCXZ label
Operación: Salta a label si CX = 0.
Interrupciones:
INT número
Salva los flags en la pila, hace TF=IF=0 y ejecuta la interrupción con el número indicado.
INTO
Interrupción condicional. Si OF = 1, hace INT 4.
IRETRetorno de interrupción. Restaura los indicadores del stack
INSTRUCCIONES DE MANIPULACION DE CADENAS
INSTRUCCIONES DE MANIPULACION DE CADENAS
MOVSB
Copiar un byte de la cadena fuente al destino.
Operación:
1. ES:[DI] <- DS:[SI] (un byte)
2. DI <- DI±1
3. SI <- SI±1
MOVSW
Copiar dos bytes de la cadena fuente al destino.
Operación:
1. ES:[DI] <- DS:[SI] (dos bytes)
2. DI <- DI±2
3. SI <- SI±2
LODSB
Poner en el acumulador un byte de la cadena fuente.
Operación:
1. AL <- DS:[SI] (un byte)
2. SI <- SI±1
LODSW
Poner en el acumulador dos bytes de la cadena fuente.
Operación:
1. AX <- DS:[SI] (dos bytes)
2. SI <- SI±2
STOSB
Almacenar en la cadena destino un byte del acumulador.
Operación:
1. ES:[DI] <- AL (un byte)
2. DI <- DI±1
STOSW
Almacenar en la cadena destino dos bytes del acumulador.
Operación:
1. ES:[DI] <- AX (dos bytes)
2. DI <- DI±2
CMPSB
Comparar un byte de la cadena fuente con el destino.
Operación:
1. DS:[SI] - ES:[DI] (Un byte, afecta sólo los flags)
2. DI <- DI±1
3. SI <- SI±1
CMPSW
Comparar dos bytes de la cadena fuente con el destino.
Operación:
1. DS:[SI] - ES:[DI] (Dos bytes, afecta sólo los flags)
2. DI <- DI±2
3. SI <- SI±2
SCASB
Comparar un byte del acumulador con la cadena destino.
Operación:
1. AL - ES:[DI] (Un byte, afecta sólo los flags)
2. DI <- DI±1
SCASW
Comparar dos bytes del acumulador con la cadena destino.
Operación:
1. AX - ES:[DI] (Dos byte, afecta sólo los flags)
2. DI <- DI±2
En todos los casos el signo + se toma si el indicador DF vale cero. Si vale 1 hay que tomar el signo -.
Prefijo para las instrucciones MOVSB, MOVSW, LODSB, LODSW, STOSB y STOSW:
REP: Repetir la instrucción CX veces.
Prefijos para las instrucciones CMPSB, CMPSW, SCASB, SCASW:
REPZ/REPE: Repetir mientras que sean iguales hasta un máximo de CX veces.REPNZ/REPNE: Repetir mientras que sean diferentes hasta un máximo de CX veces.
MOVSB
Copiar un byte de la cadena fuente al destino.
Operación:
1. ES:[DI] <- DS:[SI] (un byte)
2. DI <- DI±1
3. SI <- SI±1
MOVSW
Copiar dos bytes de la cadena fuente al destino.
Operación:
1. ES:[DI] <- DS:[SI] (dos bytes)
2. DI <- DI±2
3. SI <- SI±2
LODSB
Poner en el acumulador un byte de la cadena fuente.
Operación:
1. AL <- DS:[SI] (un byte)
2. SI <- SI±1
LODSW
Poner en el acumulador dos bytes de la cadena fuente.
Operación:
1. AX <- DS:[SI] (dos bytes)
2. SI <- SI±2
STOSB
Almacenar en la cadena destino un byte del acumulador.
Operación:
1. ES:[DI] <- AL (un byte)
2. DI <- DI±1
STOSW
Almacenar en la cadena destino dos bytes del acumulador.
Operación:
1. ES:[DI] <- AX (dos bytes)
2. DI <- DI±2
CMPSB
Comparar un byte de la cadena fuente con el destino.
Operación:
1. DS:[SI] - ES:[DI] (Un byte, afecta sólo los flags)
2. DI <- DI±1
3. SI <- SI±1
CMPSW
Comparar dos bytes de la cadena fuente con el destino.
Operación:
1. DS:[SI] - ES:[DI] (Dos bytes, afecta sólo los flags)
2. DI <- DI±2
3. SI <- SI±2
SCASB
Comparar un byte del acumulador con la cadena destino.
Operación:
1. AL - ES:[DI] (Un byte, afecta sólo los flags)
2. DI <- DI±1
SCASW
Comparar dos bytes del acumulador con la cadena destino.
Operación:
1. AX - ES:[DI] (Dos byte, afecta sólo los flags)
2. DI <- DI±2
En todos los casos el signo + se toma si el indicador DF vale cero. Si vale 1 hay que tomar el signo -.
Prefijo para las instrucciones MOVSB, MOVSW, LODSB, LODSW, STOSB y STOSW:
REP: Repetir la instrucción CX veces.
Prefijos para las instrucciones CMPSB, CMPSW, SCASB, SCASW:
REPZ/REPE: Repetir mientras que sean iguales hasta un máximo de CX veces.REPNZ/REPNE: Repetir mientras que sean diferentes hasta un máximo de CX veces.
INSTRUCCIONES LOGICAS (Afectan AF, CF, OF, PF, SF, ZF)
INSTRUCCIONES LOGICAS (Afectan AF, CF, OF, PF, SF, ZF)
AND dest,src
Operación: dest <- dest and src.
TEST dest,src
Operación: dest and src. Sólo afecta flags.
OR dest,src
Operación: dest <- dest or src.
XOR dest,src
Operación: dest <- dest xor src.
Las cuatro instrucciones anteriores ponen CF = OF = 0, AF queda indefinido y PF, SF y ZF dependen del
resultado.
NOT dest
Operación: dest <- Complemento a 1 de dest. No afecta los flags.
SHL/SAL dest,{1CL}
Realiza un desplazamiento lógico o aritmético a la izquierda.
SHR dest,{1CL}
Realiza un desplazamiento lógico a la derecha.
SAR dest,{1CL}
Realiza un desplazamiento aritmético a la derecha.
ROL dest,{1CL}
Realiza una rotación hacia la izquierda.
ROR dest,{1CL}
Realiza una rotación hacia la derecha.
RCL dest,{1CL}
Realiza una rotación hacia la izquierda usando el CF.
RCR dest,{1CL}
Realiza una rotación hacia la derecha usando el CF.
En las siete instrucciones anteriores la cantidad de veces que se rota o desplaza puede ser un bit o lacantidad de bits indicado en CL.
AND dest,src
Operación: dest <- dest and src.
TEST dest,src
Operación: dest and src. Sólo afecta flags.
OR dest,src
Operación: dest <- dest or src.
XOR dest,src
Operación: dest <- dest xor src.
Las cuatro instrucciones anteriores ponen CF = OF = 0, AF queda indefinido y PF, SF y ZF dependen del
resultado.
NOT dest
Operación: dest <- Complemento a 1 de dest. No afecta los flags.
SHL/SAL dest,{1CL}
Realiza un desplazamiento lógico o aritmético a la izquierda.
SHR dest,{1CL}
Realiza un desplazamiento lógico a la derecha.
SAR dest,{1CL}
Realiza un desplazamiento aritmético a la derecha.
ROL dest,{1CL}
Realiza una rotación hacia la izquierda.
ROR dest,{1CL}
Realiza una rotación hacia la derecha.
RCL dest,{1CL}
Realiza una rotación hacia la izquierda usando el CF.
RCR dest,{1CL}
Realiza una rotación hacia la derecha usando el CF.
En las siete instrucciones anteriores la cantidad de veces que se rota o desplaza puede ser un bit o lacantidad de bits indicado en CL.
INSTRUCCIONES ARITMETICAS (Afectan los flags AF, CF, OF, PF, SF, ZF)
INSTRUCCIONES ARITMETICAS (Afectan los flags AF, CF, OF, PF, SF, ZF)
ADD dest,src
Operación: dest <- dest + src.
ADC dest,src
Operación: dest <- dest + src + CF.
SUB dest,src
Operación: dest <- dest - src.
SBB dest,src
Operación: dest <- dest - src - CF.
CMP dest,src
Operación: dest - src (sólo afecta flags).
INC dest
Operación: dest <- dest + 1 (no afecta CF).
DEC dest
Operación: dest <- dest - 1 (no afecta CF).
NEG dest
Operación: dest <- - dest.
donde dest = {regmem} y src = {regmeminmed} no pudiendo ambos operandos estar en memoria.
DAA
Corrige el resultado de una suma de dos valores BCD empaquetados en el registro AL (debe estar inmediatamente después de una instrucción ADD o ADC). OF es indefinido después de la operación.
DAS
Igual que DAA pero para resta (debe estar inmediatamente después de una instrucción SUB o
SBB).
AAA
Lo mismo que DAA para números BCD desempaquetados.
AAS
Lo mismo que DAS para números BCD desempaquetados.
AAD
Convierte AH:AL en BCD desempaquetado a AL en binario.
Operación: AL <- AH * 0Ah + AL, AH <- 0. Afecta PF, SF, ZF, mientras que AF, CF y OF quedan indefinidos.
AAM
Convierte AL en binario a AH:AL en BCD desempaquetado.
Operación: AH <- AL / 0Ah, AL <- AL mod 0Ah. Afecta PF, SF, ZF, mientras que AF, CF y OF quedan indefinidos.
MUL {reg8mem8}
Realiza una multiplicación con operandos no signados de 8 por 8 bits.
Operación: AX <- AL * {reg8mem8}. CF=OF=0 si AH = 0, CF=OF=1 en caso contrario. AF, PF,
SF, ZF quedan indefinidos.
MUL {reg16mem16}
Realiza una multiplicación con operandos no signados de 16 por 16 bits.
Operación: DX:AX <- AX * {reg16mem16}. CF=OF=0 si DX = 0, CF=OF=1 en caso contrario.
AF, PF, SF, ZF quedan indefinidos.
IMUL {reg8mem8}
Realiza una multiplicación con operandos con signo de 8 por 8 bits.
Operación: AX <- AL * {reg8mem8} realizando la multiplicación con signo. CF = OF = 0 si el resultado entra en un byte, en caso contrario valdrán 1. AF, PF, SF, ZF quedan indefinidos.
IMUL {reg16mem16}
Realiza una multiplicación con operandos con signo de 16 por 16 bits.
Operación: DX:AX <- AX * {reg16mem16} realizando la multiplicación con signo. CF = OF = 0 si el resultado entra en dos bytes, en caso contrario valdrán 1. AF, PF, SF, ZF quedan indefinidos.
CBW
Extiende el signo de AL en AX. No se afectan los flags.
CWD
Extiende el signo de AX en DX:AX. No se afectan flags.
ADD dest,src
Operación: dest <- dest + src.
ADC dest,src
Operación: dest <- dest + src + CF.
SUB dest,src
Operación: dest <- dest - src.
SBB dest,src
Operación: dest <- dest - src - CF.
CMP dest,src
Operación: dest - src (sólo afecta flags).
INC dest
Operación: dest <- dest + 1 (no afecta CF).
DEC dest
Operación: dest <- dest - 1 (no afecta CF).
NEG dest
Operación: dest <- - dest.
donde dest = {regmem} y src = {regmeminmed} no pudiendo ambos operandos estar en memoria.
DAA
Corrige el resultado de una suma de dos valores BCD empaquetados en el registro AL (debe estar inmediatamente después de una instrucción ADD o ADC). OF es indefinido después de la operación.
DAS
Igual que DAA pero para resta (debe estar inmediatamente después de una instrucción SUB o
SBB).
AAA
Lo mismo que DAA para números BCD desempaquetados.
AAS
Lo mismo que DAS para números BCD desempaquetados.
AAD
Convierte AH:AL en BCD desempaquetado a AL en binario.
Operación: AL <- AH * 0Ah + AL, AH <- 0. Afecta PF, SF, ZF, mientras que AF, CF y OF quedan indefinidos.
AAM
Convierte AL en binario a AH:AL en BCD desempaquetado.
Operación: AH <- AL / 0Ah, AL <- AL mod 0Ah. Afecta PF, SF, ZF, mientras que AF, CF y OF quedan indefinidos.
MUL {reg8mem8}
Realiza una multiplicación con operandos no signados de 8 por 8 bits.
Operación: AX <- AL * {reg8mem8}. CF=OF=0 si AH = 0, CF=OF=1 en caso contrario. AF, PF,
SF, ZF quedan indefinidos.
MUL {reg16mem16}
Realiza una multiplicación con operandos no signados de 16 por 16 bits.
Operación: DX:AX <- AX * {reg16mem16}. CF=OF=0 si DX = 0, CF=OF=1 en caso contrario.
AF, PF, SF, ZF quedan indefinidos.
IMUL {reg8mem8}
Realiza una multiplicación con operandos con signo de 8 por 8 bits.
Operación: AX <- AL * {reg8mem8} realizando la multiplicación con signo. CF = OF = 0 si el resultado entra en un byte, en caso contrario valdrán 1. AF, PF, SF, ZF quedan indefinidos.
IMUL {reg16mem16}
Realiza una multiplicación con operandos con signo de 16 por 16 bits.
Operación: DX:AX <- AX * {reg16mem16} realizando la multiplicación con signo. CF = OF = 0 si el resultado entra en dos bytes, en caso contrario valdrán 1. AF, PF, SF, ZF quedan indefinidos.
CBW
Extiende el signo de AL en AX. No se afectan los flags.
CWD
Extiende el signo de AX en DX:AX. No se afectan flags.
Instrucciones de 8086 y 8088
Instrucciones de 8086 y 8088
INSTRUCCIONES DE TRANSFERENCIA DE DATOS (No afectan flags)
MOV dest,src
Copia el contenido del operando fuente (src) en el destino (dest).
Operación: dest <- src
Las posibilidades son:
1. MOV reg,{regmeminmed}
2. MOV mem,{reginmed}
3. MOV {reg16mem16},{CSDSESSS}
4. MOV {DSESSS},{reg16mem16}
PUSH src
Pone el valor en el tope del stack.
Operación: SP <- SP - 2, [SP+1:SP] <- src donde src = {reg16mem16CSDSESSS}.
POP dest
Retira el valor del tope del stack poniéndolo en el lugar indicado.
Operación: dest <- [SP+1:SP], SP <- SP + 2 donde dest = {reg16mem16DSESSS}.
XCHG reg,{regmem}
Intercambia ambos valores.
IN {ALAX},{DXinmed (1 byte)}
Pone en el acumulador el valor hallado en el port indicado.
OUT {DXinmed (1 byte)},{ALAX}
Pone en el port indicado el valor del acumulador.
XLAT
Realiza una operación de traducción de un código de un byte a otro código de un byte mediante una tabla.
Operación: AL <- [BX+AL]
LEA reg,mem
Almacena la dirección efectiva del operando de memoria en un registro.
Operación: reg <- dirección mem
LDS reg,mem32
Operación: reg <- [mem], DS <- [mem+2]
LES reg,mem32
Operación: reg <- [mem], ES <- [mem+2]
LAHF
Copia en el registro AH la imagen de los ocho bits menos significativos del registro de indicadores.
Operación: AH <- SF:ZF:X:AF:X:PF:X:CF
SAHF
Almacena en los ocho bits menos significativos del registro de indicadores el valor del registro AH.
Operación: SF:ZF:X:AF:X:PF:X:CF <- AH
PUSHF
Almacena los flags en la pila.
Operación: SP <- SP - 2, [SP+1:SP] <- Flags.
POPF
Pone en los flags el valor que hay en la pila.
Operación: Flags <- [SP+1:SP], SP <- SP + 2
INSTRUCCIONES DE TRANSFERENCIA DE DATOS (No afectan flags)
MOV dest,src
Copia el contenido del operando fuente (src) en el destino (dest).
Operación: dest <- src
Las posibilidades son:
1. MOV reg,{regmeminmed}
2. MOV mem,{reginmed}
3. MOV {reg16mem16},{CSDSESSS}
4. MOV {DSESSS},{reg16mem16}
PUSH src
Pone el valor en el tope del stack.
Operación: SP <- SP - 2, [SP+1:SP] <- src donde src = {reg16mem16CSDSESSS}.
POP dest
Retira el valor del tope del stack poniéndolo en el lugar indicado.
Operación: dest <- [SP+1:SP], SP <- SP + 2 donde dest = {reg16mem16DSESSS}.
XCHG reg,{regmem}
Intercambia ambos valores.
IN {ALAX},{DXinmed (1 byte)}
Pone en el acumulador el valor hallado en el port indicado.
OUT {DXinmed (1 byte)},{ALAX}
Pone en el port indicado el valor del acumulador.
XLAT
Realiza una operación de traducción de un código de un byte a otro código de un byte mediante una tabla.
Operación: AL <- [BX+AL]
LEA reg,mem
Almacena la dirección efectiva del operando de memoria en un registro.
Operación: reg <- dirección mem
LDS reg,mem32
Operación: reg <- [mem], DS <- [mem+2]
LES reg,mem32
Operación: reg <- [mem], ES <- [mem+2]
LAHF
Copia en el registro AH la imagen de los ocho bits menos significativos del registro de indicadores.
Operación: AH <- SF:ZF:X:AF:X:PF:X:CF
SAHF
Almacena en los ocho bits menos significativos del registro de indicadores el valor del registro AH.
Operación: SF:ZF:X:AF:X:PF:X:CF <- AH
PUSHF
Almacena los flags en la pila.
Operación: SP <- SP - 2, [SP+1:SP] <- Flags.
POPF
Pone en los flags el valor que hay en la pila.
Operación: Flags <- [SP+1:SP], SP <- SP + 2
Indicadores (flags)
Indicadores (flags)
Hay nueve indicadores de un bit en este registro de 16 bits. Los cuatro bits más significativos están indefinidos, mientras que hay tres bits con valores determinados: los bits 5 y 3 siempre valen cero y el bit 1 siempre vale uno (esto también ocurría en los procesadores anteriores).
Registro de indicadores (16 bits)
Registro de indicadores (16 bits)
CF (Carry Flag, bit 0): Si vale 1, indica que hubo "arrastre" (en caso de suma) hacia, o "préstamo" (en caso de resta) desde el bit de orden más significativo del resultado. Este indicador es usado por instrucciones que suman o restan números que ocupan varios bytes. Las instrucciones de rotación pueden aislar un bit de la memoria o de un registro poniéndolo en el CF.
PF (Parity Flag, bit 2): Si vale uno, el resultado tiene paridad par, es decir, un número par de bits a 1. Este indicador se puede utilizar para detectar errores en transmisiones.
AF (Auxiliary carry Flag, bit 4): Si vale 1, indica que hubo "arrastre" o "préstamo" del nibble (cuatro bits) menos significativo al nibble más significativo. Este indicador se usa con las instrucciones de ajuste decimal.
ZF (Zero Flag, bit 6): Si este indicador vale 1, el resultado de la operación es cero.
SF (Sign Flag, bit 7): Refleja el bit más significativo del resultado. Como los números negativos se representan en la notación de complemento a dos, este bit representa el signo: 0 si es positivo, 1 si es negativo.
TF (Trap Flag, bit 8): Si vale 1, el procesador está en modo paso a paso. En este modo, la CPU automáticamente genera una interrupción interna después de cada instrucción, permitiendo inspeccionar los resultados del programa a medida que se ejecuta instrucción por instrucción.
IF (Interrupt Flag, bit 9): Si vale 1, la CPU reconoce pedidos de interrupción externas enmascarables (por el pin INTR). Si vale 0, no se reconocen tales interrupciones. Las interrupciones no enmascarables y las internas siempre se reconocen independientemente del valor de IF.
DF (Direction Flag, bit 10): Si vale 1, las instrucciones con cadenas sufrirán "auto-decremento", esto es, se procesarán las cadenas desde las direcciones más altas de memoria hacia las más bajas. Si vale 0, habrá "auto-incremento", lo que quiere decir que las cadenas se procesarán de "izquierda a derecha". OF (Overflow flag, bit 11): Si vale 1, hubo un desborde en una operación aritmética con signo, esto es, un dígito significativo se perdió debido a que tamaño del resultado es mayor que el tamaño del destino.
Unidad aritmética y lógica
Unidad aritmética y lógica
Es la encargada de realizar las operaciones aritméticas (suma, suma con "arrastre", resta, resta con "préstamo" y comparaciones) y lógicas (AND, OR, XOR y TEST). Las operaciones pueden ser de 16 bits o de 8 bits.
Es la encargada de realizar las operaciones aritméticas (suma, suma con "arrastre", resta, resta con "préstamo" y comparaciones) y lógicas (AND, OR, XOR y TEST). Las operaciones pueden ser de 16 bits o de 8 bits.
Registros de uso general del 8086/8088:
Registros de uso general del 8086/8088:
Tienen 16 bits cada uno y son ocho:
AX = Registro acumulador, dividido en AH y AL (8 bits cada uno).Usándolo se produce (en general) una instrucción que ocupa un byte menos que si se utilizaran otros registros de uso general. Su parte más baja, AL, también tiene esta propiedad. El último registro mencionado es el equivalente al acumulador de los procesadores anteriores (8080 y 8085). Además hay instrucciones como DAA; DAS; AAA; AAS; AAM; AAD; LAHF; SAHF; CBW; IN y OUT que trabajan con AX o con uno de sus dos bytes (AH o AL). También se utiliza este registro (junto con DX a veces) en multiplicaciones y divisiones.
BX = Registro base, dividido en BH y BL.Es el registro base de propósito similar (se usa para direccionamiento indirecto) y es una versión más potente del par de registros HL de los procesadores anteriores.
CX = Registro contador, dividido en CH y CL.Se utiliza como contador en bucles (instrucción LOOP), en operaciones con cadenas (usando el prefijo REP) y en desplazamientos y rotaciones (usando el registro CL en los dos últimos casos).
DX = Registro de datos, dividido en DH y DL.Se utiliza junto con el registro AX en multiplicaciones y divisiones, en la instrucción CWD y en IN y OUT para direccionamiento indirecto de puertos (el registro DX indica el número de puerto de entrada/salida).
SP = Puntero de pila (no se puede subdividir).Aunque es un registro de uso general, debe utilizarse sólo como puntero de pila, la cual sirve para almacenar las direcciones de retorno de subrutinas y los datos temporarios (mediante las instrucciones PUSH y POP). Al introducir (push) un valor en la pila a este registro se le resta dos, mientras que al extraer (pop) un valor de la pila este a registro se le suma dos.
BP = Puntero base (no se puede subdividir).Generalmente se utiliza para realizar direccionamiento indirecto dentro de la pila.
SI = Puntero índice (no se puede subdividir).Sirve como puntero fuente para las operaciones con cadenas. También sirve para realizar direccionamiento indirecto.
DI = Puntero destino (no se puede subdividir).Sirve como puntero destino para las operaciones con cadenas. También sirve para realizar direccionamiento indirecto.
Cualquiera de estos registros puede utilizarse como fuente o destino en operaciones aritméticas y lógicas, lo que no se puede hacer con ninguno de los seis registros que se verán más adelante.
Tienen 16 bits cada uno y son ocho:
AX = Registro acumulador, dividido en AH y AL (8 bits cada uno).Usándolo se produce (en general) una instrucción que ocupa un byte menos que si se utilizaran otros registros de uso general. Su parte más baja, AL, también tiene esta propiedad. El último registro mencionado es el equivalente al acumulador de los procesadores anteriores (8080 y 8085). Además hay instrucciones como DAA; DAS; AAA; AAS; AAM; AAD; LAHF; SAHF; CBW; IN y OUT que trabajan con AX o con uno de sus dos bytes (AH o AL). También se utiliza este registro (junto con DX a veces) en multiplicaciones y divisiones.
BX = Registro base, dividido en BH y BL.Es el registro base de propósito similar (se usa para direccionamiento indirecto) y es una versión más potente del par de registros HL de los procesadores anteriores.
CX = Registro contador, dividido en CH y CL.Se utiliza como contador en bucles (instrucción LOOP), en operaciones con cadenas (usando el prefijo REP) y en desplazamientos y rotaciones (usando el registro CL en los dos últimos casos).
DX = Registro de datos, dividido en DH y DL.Se utiliza junto con el registro AX en multiplicaciones y divisiones, en la instrucción CWD y en IN y OUT para direccionamiento indirecto de puertos (el registro DX indica el número de puerto de entrada/salida).
SP = Puntero de pila (no se puede subdividir).Aunque es un registro de uso general, debe utilizarse sólo como puntero de pila, la cual sirve para almacenar las direcciones de retorno de subrutinas y los datos temporarios (mediante las instrucciones PUSH y POP). Al introducir (push) un valor en la pila a este registro se le resta dos, mientras que al extraer (pop) un valor de la pila este a registro se le suma dos.
BP = Puntero base (no se puede subdividir).Generalmente se utiliza para realizar direccionamiento indirecto dentro de la pila.
SI = Puntero índice (no se puede subdividir).Sirve como puntero fuente para las operaciones con cadenas. También sirve para realizar direccionamiento indirecto.
DI = Puntero destino (no se puede subdividir).Sirve como puntero destino para las operaciones con cadenas. También sirve para realizar direccionamiento indirecto.
Cualquiera de estos registros puede utilizarse como fuente o destino en operaciones aritméticas y lógicas, lo que no se puede hacer con ninguno de los seis registros que se verán más adelante.
Arquitectura de los procesadores 8088 y 8086:
El 8086 es un microprocesador de 16 bits, tanto en lo que se refiere a su estructura como en sus conexiones externas, mientras que el 8088 es un procesador de 8 bits que internamente es casi idéntico al 8086. La única diferencia entre ambos es el tamaño del bus de datos externo. Intel trata esta igualdad interna y desigualdad externa dividiendo cada procesador 8086 y 8088 en dos sub-procesadores. O sea, cada uno consta de una unidad de ejecución (EU: Execution Unit) y una unidad interfaz del bus (BIU: Bus Interface Unit). La unidad de ejecución es la encargada de realizar todas las operaciones mientras que la unidad de interfaz del bus es la encargada de acceder a datos e instrucciones del mundo exterior. Las unidades de ejecución son idénticas en ambos microprocesadores, pero las unidades de interfaz del bus son diferentes en varias cuestiones, como se desprende del siguiente diagrama en bloques:

La ventaja de esta división fue el ahorro de esfuerzo necesario para producir el 8088. Sólo una mitad del 8086 (el BIU) tuvo que rediseñarse para producir el 8088.
Los microprocesadores 8086 y 8088
Historia del 8086/8088
En junio de 1978 Intel lanzó al mercado el primer microprocesador de 16 bits: el 8086. En junio de 1979 apareció el 8088 (internamente igual que el 8086 pero con bus de datos de 8 bits) y en 1980 los coprocesadores 8087 (matemático) y 8089 (de entrada y salida). El primer fabricante que desarrolló software y hardware para estos chips fue la propia Intel. Reconociendo la necesidad de dar soporte a estos circuitos integrados, la empresa invirtió gran cantidad de dinero en un gran y moderno edificio en Santa Clara, California, dedicado al diseño, fabricación y venta de sus sistemas de desarrollo que, como se explicó anteriormente, son computadoras autosuficientes con el hardware y software necesario para desarrollar software de microprocesadores.
En junio de 1978 Intel lanzó al mercado el primer microprocesador de 16 bits: el 8086. En junio de 1979 apareció el 8088 (internamente igual que el 8086 pero con bus de datos de 8 bits) y en 1980 los coprocesadores 8087 (matemático) y 8089 (de entrada y salida). El primer fabricante que desarrolló software y hardware para estos chips fue la propia Intel. Reconociendo la necesidad de dar soporte a estos circuitos integrados, la empresa invirtió gran cantidad de dinero en un gran y moderno edificio en Santa Clara, California, dedicado al diseño, fabricación y venta de sus sistemas de desarrollo que, como se explicó anteriormente, son computadoras autosuficientes con el hardware y software necesario para desarrollar software de microprocesadores.
SISTEMAS NUMERICOS
Sistema Decimal.
BASE 10 => Es el número de dígitos que tiene el sistema
0 1 2 3 4 5 6 7 8 9
Sistema Binario.
Dos digitos 0 1
1001 Nibbles = 4 bits
10101010 byte = 8 bits
1024 * 8 bits Kilo Byte = 1024 Byte
10242 * 8 bits Mega Byte = 1024 Kilo Byte
10243 * 8 bits Giga Byte = 1024 Mega Byte
10244 * 8 bits Tera Byte = 1024 Giga Byte
Sistema Octal.
Ocho dígitos 0 1 2 3 4 5 6 7
Sistema Hexadecimal.
Dieciseis Digitos 0 1 2 3 4 5 6 7 8 9 A B C D F
BASE 10 => Es el número de dígitos que tiene el sistema
0 1 2 3 4 5 6 7 8 9
Sistema Binario.
Dos digitos 0 1
1001 Nibbles = 4 bits
10101010 byte = 8 bits
1024 * 8 bits Kilo Byte = 1024 Byte
10242 * 8 bits Mega Byte = 1024 Kilo Byte
10243 * 8 bits Giga Byte = 1024 Mega Byte
10244 * 8 bits Tera Byte = 1024 Giga Byte
Sistema Octal.
Ocho dígitos 0 1 2 3 4 5 6 7
Sistema Hexadecimal.
Dieciseis Digitos 0 1 2 3 4 5 6 7 8 9 A B C D F
Suscribirse a:
Entradas (Atom)