BENEMÉRITA UNIVERSIDAD AUTÓNOMA DE PUEBLA
FACULTAD DE CIENCIAS DE LA COMPUTACIÓN
APUNTES IMPRESOS
MATERIA: ENSAMBLADOR
UNIDAD 1. Sistemas de numeración
La extensión de los microcomputadores tiene que ver con el renuente interés en el
lenguaje ensamblador, cuyas principales dos razones son:
Práctica: Un programa Ensamblador requiere menos espacio de memoria y menor
tiempo de ejecución.
Académica: Un conocimiento de lenguaje ensamblador y código de máquina
resultante proporciona un entendimiento de la arquitectura dela máquina que no
es posible con un lenguaje de alto nivel.
Todos los procesadores x86 comparten el mismo conjunto de instrucciones, los
mismos modos de direccionamiento y ejecutan sus instrucciones usando la misma
secuencia de pasos. Sin embargo, al razón por la que cada vez se fabrica un
nuevo procesador está basada en explicar las diferencias en rendimiento de cuatro
características del hardware:
Pre-fetch
Queues
Cachés
Pipelines
Superscalar designs.
El procesador 886 es un “dispositivo” no caro que no implementa ninguna de las
características anteriores. El procesador 8286 implementa la cola prefetch. El
procesador 8486 tiene una cola de prefetch, un caché y un pipeline. El 8686 tiene
todas las características de arriba con operación superscalar. Estudiando cada uno
de esos procesadores se puede ver los beneficios de cada característica.
Los Bloques de Construcción fundamentales de una Computadora son el bit y el
byte, que proporcionan el medio por el cual la computadora puede representar
datos e instrucciones en la Memoria.
Un programa en código de Màquina Consiste en diferentes Segmentos para definir
los datos, para instrucciones de máquina y un segmento llamado Stack que
contiene direcciones almacenadas.
REGISTROS: Sirven para el mejo Aritmético, movimiento de datos y
direccionamiento.
BITS Y BYTES
BIT. La Unidad más pequeña de datos en una Computadora (Off= 0, On=1).
BYTE. Un grupo de 9 bits, 8 bits para los datos y uno de paridad.
BIT DE PARIDAD. Asume que los bits “ON” para un byte son siempre un número
Impar.
Para los propósitos de referencia, los bits en un byte son numerados del 0 al 7 y
de derecha a izquierda
7 6 5 4 3 2 1 0
0 1 0 0 0 0 0 1
WORD. Un campo de 16 bits ( 2 Bytes ), los bits son numerados del 0 al 15 como
en las letras “PC”.
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
0 1 0 1 0 0 0 0 0 1 0 0 0 0 1 1
CODIGO ASCII
Los 8 bits de datos habilitan 28 (256 posibles combinaciones) de todos los bits en
“OFF”= 0000 0000 hasta todos los bits en “ON” 1111 1111 Para propósitos de
estandarización, típicamente adoptan el código ASCII (American Standar Code for
Information Interchange).
Para facilitar transferencia de diferentes dispositivos de computadora
ASCII 7 Bits 128 Diferentes Caracteres
ASCII EXTENDIDO 8 Bits 256 Diferentes Caracteres
Práctica1: Descubra qué visualizaría en pantalla, si imprime los valores
contenidos en el registro DL= 20H, DL= 65H, DL= 121H?
CODIGO ALFANUMERICO DE 8 BITS
BCD-09
Este es un código amplificado decimal decodificado binario para Intercambio de
Información (EBCDIC) que utiliza 8 posiciones binarias para cada formato de
carácter mas una posición para el control o verificación de paridad mediante
empleo de 8 posiciones de bits.
Con este Código pueden codificarse 256 caracteres distintos de ahí que se tenga la
codificación de Letras Mayúsculas y Minúsculas, además de una mayor gama de
Caracteres Especiales y de Control, que son significativos para algunas unidades de
entrada / salida.
NUMEROS BINARIOS
Una Computadora solo reconoce 0’s y 1’s, éste es el sistema numérico
debase 2 , es decir Binario.
Pero 0100 0001 = 65 o “A” ¿ Este código puede representar 65 o “A”,
dependiendo de:
Si en el programa se define un campo para propósitos de Aritmética.
Si define un campo como medio a ser descrito.
ARITMÉTICA BINARIA
La Computadora realiza aritmética solo en Formato Binario.
Adición Binaria.
0 + 0 = 0
0 + 1 = 1
1 + 0 = 1
1 +1 = 10
Ejemplos de Adición Binaria:
65 01000001
+42 + 00101010
107 01101011
60 00111100
+53 + 00110101
113 01110001
Números Negativos
Los Números Binarios son positivos si el bit más izquierdo es 0. Un numero
negativo contiene un bit 1 en su posición más izquierda.
Un nùmero binario negativo se expresa en notación de complemento a 2.
Que consiste en cambiar todos los bits y sumar 1
Ejemplos de complemento a 2:
a) Obtener a partir de 53 a -53
5 3 = 0011010 1
1 1 0 0 1 0 1 0 Complemento a 1
+ 1
1 1 0 0 1 0 1 1 = - 5 3 Complemento a 2
b) Obtener a partir de 60 a -60
6 0 = 0011110 0
1 1 0 0 0 0 1 1 Complemento a 1
+ 1
1 1 0 0 0 1 0 0 = - 6 0 Complemento a 2
Sustracción binaria
La sustracción Binaria se realiza de la siguiente manera:
Para resolver 65 - 42 se procede de la siguiente manera:
Sabemos que el numero 65 en binario es 0100000 1
y que el numero 42 en binario es 00101010
Ahora procederemos a transformar el numero 42 a - 42 es decir, su complemento
a 2.
42 = 0010101 0
1101010 1
+ 1
1 1 0 1 0 1 1 0 = - 42
por lo que 65 - 4 2 = 01000001 +11010110= 0001011 1
=23
0100000 1
+ 1101011 0
1
0001011 1
Multiplicación Binaria
La multiplicación binaria es de la siguiente forma:
1 x1=1
1 x 0 = 0
0 x 1 = 0
0 x 0 = 0
Ejemplo de Multiplicación Binaria tenemos que 10 = 1010 y 2=10
1010 x 10
10100
1 0 1 0 0 = 20
En efecto 2 x 10 = 20
Otro ejemplo
tenemos que 37 = 0 0 1 0 0 1 0 1 y 7=00000111
0010010 1
x 0000011 1
0010010 1
00100101
00100101 .
01000000 11 = 259
En efecto 37 x 7 = 259
REPRESENTACIÓN HEXADECIMAL
Supóngase que estamos viendo el contenido de Byte de Memoria y queremos
saber el contenido de cuatro bytes Adyacentes de Memoria que contiene un valor
binario para representar estos datos de 32 bits, para realizar la conversión de
binario a hexadecimal se utiliza el método de dividir cada byte por mitad y
expresar cada valor de cada mitad
01001 1001 0011 0101 1011 1001 1100 1110
9 9 3 5 11 9 12 14
100h = 0001 0000 0000
20h = 0000 0010 0000
Hexadecimal - Binario
Ah = 10d
1AFh = 0001 1010 1111
Octal – Binario
1748 = 001 111 100
3758 = 011 111 101
Binario - Octal
001010111 = 001 010 111 = 1728
011000101 = 011 000 101 = 3058
OPERACIONES LOGICAS
XOR
0 XOR 0 = 0
0 XOR 1 = 1
1 XOR 1 = 0
1 XOR 0 = 1
Un uso de esta Operación Lógica es por ejemplo Limpiar el acumulador
XOR AX,AX
OR
0 OR 0 = 0
0 OR 1 = 1
1 OR 0 = 1
1 OR 1 = 1
AND
1 AND 1 = 1
0 AND 1 = 0
0 AND 0 = 0
0 AND 0 = 0
Podemos utilizar la operación AND para filtrar
Por ejemplo:
Si tenemos 0011 0011 y queremos filtrar la parte baja sería de la
siguiente manera:
0011 0011
AND 0000 1111
0000 0011
y como se observa se esta filtrando la parte baja.
La operación sería AND 33h,0Fh
para obtener 03h
Práctica 2: Esboce un algoritmo que enmascare la parte alta y la parte
baja por separado del registro AH.
UNIDAD 2. Arquitectura de computadoras
MNEMONICO
Un método de mejorar el Manejo de las Instrucciones para el
programador es el asignar un nombre a cada Instrucción por ejemplo a la
Instrucción de decrementar nombraría con “DCR” a la de mover datos
nombrarla como “MOV”. A los nombres de las instrucciones se les conoce
como “mnemónicos”.
SEGMENTOS
Un segmento es un área de 64k de memoria
Los segmentos se pueden localizar en memoria, empezando en un límite
divisible por 16.
La mayoría de programas comienza al menos 3 segmentos aunque
puede direccionar el espacio necesario para ejecución.
3 PRINCIPALES SEGMENTOS
1. Stack Segment (El primero en entrar es el último en Salir)
contiene: Dirección de Regreso para que el programa regrese al S. O.
Dirección de Retorno para llamados a Subrutinas.
(SS) Stack Segment direcciona este segmento.
2. Code Segment
contiene: Instrucciones de máquina que son ejecutadas. La primera
Instrucción ejecutable está en el Inicio de este segmento y el S.O. liga a
esta localidad para ejecutar un programa.
(CS) Direcciona este Segmento
3. Data Segment
contiene: Algunos datos definidos, constantes y áreas que el programa
necesita.
(DS) Direcciona este Segmento
4. Extra Segment
Es para usos Especiales
Los Segmentos se dividen de la siguiente manera:
S.O
Stack
Segment
Data
Segment
Code
Segment
Extra
Segment
REGISTROS
El Procesador 8086 / 8088 tiene 14 registros que se usan para controlar la
instrucción que empieza a ser ejecutada, para manejar el direccionamiento de
memoria y para facilitar capacidades aritméticas.
Los registros de CPU son localidades de memoria muy especiales construidos de
Flip-Flops. Los registros no son parte de la memoria principal, el CPU los
implementa en un chip y los registros de los procesadores de la familia 80x86
varían en tamaño. Toda operación aritmética ocurre en los registros del CPU.
Debido a que los registros están en un chip y especialmente son manejados por el
CPU, son mucho mas rápidos que la memoria. Acceder a memoria requiere uno o
más ciclos de reloj, acceder datos en un registro normalmente toma cero ciclos de
reloj.
REGISTROS DE PROPÓSITO GENERAL
AX, BX, CX ,DX
Estos registros tienen una parte Alta y una parte Baja.
Se les puede direccionar como palabra o como byte.
AH AL
AX
1. El Registro AX: Conocido como acumulador primario. Uso: Toda
Operación de E/S, algunas Operaciones de Cadena y algunas
operaciones Aritméticas.
2. El Registro BX: conocido como registro de base, uso: Es el único
que puede usarse ( de los de propósito general ) como un índice
para direccionamiento extendido.
3. El Registro CX: Conocido como el Registro Contador uso: Controla
el numero de veces que un ciclo se repite, contiene el número de
rotaciones derechas o izquierdas de un bit.
4. El Registro DX: Conocido como Registro de Datos. Uso: Algunas
Operaciones de E/S y operaciones de multiplicación y división que
envuelven grandes valores.
REGISTRO DE TIPO APUNTADOR
1. SP: Stack Pointer. Uso: Permite Implementación de un Stack en
memoria. Asociado con el registro SS para direccionar el stack.
2. BP: Base Pointer. Uso: Facilita la referencia a parámetros (datos y
direcciones vía stack)
REGISTRO DE TIPO INDICE
Se usan para Direccionamiento Extendido y Sumas o Restas.
1. SI: Source Index Uso: Algunas Operaciones de cadenas y se asocia con DS.
2. DI: Destination Index. Uso: Operaciones de Cadenas y se asocia con ES.
CUATRO REGISTROS DE SEGMENTO
Son importantes en el direccionamiento de memoria. Con cada uno se
puede direccionar 64k de memoria.
1. CS: Code Segment. Uso: Contiene la dirección Inicial del Segmento de
Código. Esta dirección más un offset en el program counter (PC) indica la
siguiente dirección para ejecución.
2. DS: Data Segment. Uso: La Dirección Inicial del Segmento de datos. Esa
dirección mas un offset en una instrucción hace referencia a una localidad
especÍfica en el data segment.
3. SS: Stack Segment. Contiene la dirección Inicial del Stack Segment.
4. ES: Extra Segment. En algunas Operaciones de Cadenas Uso: Para
direccionamiento de manejo de memoria. Es asociado con DI, si es
requerido un programa ensamblador tiene que inicializarlo.
REGISTRO APUNTADOR A INSTRUCCIONES
IP ó PC: Contiene la dirección Offset de la Instrucción que se va a ejecutar
( se puede cambiar su valor en el Debug).
REGISTRO DE BANDERAS
Conocido también como “registro de Estado” o “program status Word” -
sólo 9 de sus 16 bits son activos e indican el Estado Actual de la máquina y sus
resultados de ejecución.
BANDERAS
O(verflow) Indica overflow “Interrupción”
D(irection) Designa dirección (derecha o izquierda) para mover o comparar
datos “cadenas” e indica si una interrupción fue deshabilitada.
I(nterrupt) Indica si una Interrupción fue deshabilitada
T(rap) Permite Operación del CPU en modo de un solo paso
S(ign) Contiene el signo resultante de una Operación
Aritmética
Z(ero) Indica el resultado de una Operación Aritmética
A(uxiliar carry) Contiene un carry en Aritmética Especializada
P(arity) Indica Paridad (1=Impar) (0=Par).
C(arry) Contiene carry de alto orden (más izquierdo).
16 BITS
OVERFLOW DIRECCION INTERRUPT TRAP SIGNO ZERO CA. AUX PARIDAD CARRY
COMPUTADORA BASICA
Unidad de Entrada
Unidad de Salida
Unidad de Memoria
Unidad Aritmética / Lógica
Unidad de Control
CONTROL UNIT
ALU BUS INTERFACE
EXECUTION UNIT UNIT
Datos y Instrucciones
Operandos Resultados a ejecutar
MEMORY UNIT
INPUT UNIT OUTPUT UNIT
ARQUITECTURA DEL PROCESADOR
8088 Microprocesador 3ª Generación con Registro de 16 Bits, es como el 8086
con una diferencia: El 8088 estaba limitado a buses de 8 bits en lugar de 16 bits el
cual lleva a cabo la transferencia entre el microprocesador, memoria y dispositivos
externos.
8088 Particionados EU: Unidad de ejecución
y en dos Unidades Uso: Ejecutar Instrucciones
8086 Lógicas BIU: Bus Interface Unit
Uso: Proporcionar Instrucciones y Datos a la E.U.
La unidad central de procesamiento (CPU) es el hardware que dirige la ejecución
de instrucciones. Las instrucciones que ejecuta el CPU generalmente son muy
simples y pueden requerir los datos en donde actuar en localidades especiales de
almacenamiento dentro del mismo CPU llamados registros. Así el CPU puede
acceder datos en los registros mucho mas rápido que en memoria RAM. Sin
embargo, el número de registros en el CPU es limitado, así el programador debe
guardar cuidadosamente solo los datos a usar.
Cualquier otro programa escrito en algún lenguaje de programación tiene que ser
convertido al lenguaje de máquina nativo del CPU para correr en la computadora.
Un compilador es un programa que traduce los programas escritos en lenguaje de
programación a lenguaje de máquina de una arquitectura de computadora
particular.
EU: EXECUTION UNIT BIU: Bus Interface Unit
AH AL PROGRAM CONTROL
BH BL
CH CL CS
DH DL
SP DS
BP SS
SI ES
DI
BUS
COTROL
UNIT
ALU
1
CU
2 Cola de
FLAG REGS 3 Instrucciones
4
.
.
INSTRUCTION POINTER
El BIU tiene como misión controlar 3 importantes funciones:
1. Controlar Buses de Transferencia de datos a la E.U., a la Memoria y a
dispositivos de E/S.
2. Los cuatro registros de Segmento Controlan el Direccionamiento y
pueden manejar hasta un millón de bytes de Direccionamiento de
Memoria.
3. Acceso a Instrucciones. Tiene que acceder a instrucciones de
Memoria en una cola de Instrucciones.
4. Si la memoria caché está presente en el chip de CPU entonces el BIU
es también responsable de acceder los datos al caché.
Cola 4 Bytes (6 en 8086)
Siempre hay cola de Instrucciones lista para ejecutar
Los buses de datos en una familia de procesadores 8086, transfiere información
entre una localidad de memoria particular y/o dispositivos de E/S y el CPU. La
pregunta es ¿ Cuál es la localidad de memoria o el dispositivo de E/S? Los buses
de direcciones responden esa pregunta, ya que cuando el software quiere acceder
alguna localidad de memoria o dispositivo de E/S, éste deja la correspondiente
dirección en el bus de direcciones.
Con a líneas, el procesador puede manejar 2ª direcciones únicas, por esta
razón el número de bits en un bus de direcciones determina el número máximo de
direccionamiento de memoria y localidades de E/S.
Procesador Tamaño del
bus de
direcciones
8088 20
8086 20
80188 20
80186 20
80286 24
80386sx 24
80386dx 32
80486 32
80586/Pentium 32
(Pro)
Tabla 1. Tamaño de los buses de direcciones de la familia 80x86.
El bus de control es una colección de señales que controla la forma en que
el procesador se comunica con el resto del sistema.
Para operaciones de lectura o escritura, las líneas de control de datos controlan la
dirección de datos en el bus de datos. Cuando ambos tienen un uno lógico, el CPU
y E/S a memoria no se comunican con otro. Si la línea de lectura es cero, el CPU
está leyendo los datos desde memoria. Si la línea de escritura es cero, el sistema
transfiere los datos desde el CPU a memoria.
OTRAS FUNCIONES DEL BIU
1. Interpretar o codificar Instrucciones
2. Realizar cálculos de Direcciones de Memoria
3. Localizar algunos operandos necesarios
4. Direccionar el ALU para realizar las operaciones requeridas
A.L.U.
E.U. tiene 3 secciones: C.U.
10 Registros
La EU notifica al BIU si necesita acceder datos en memoria y a
dispositivos de E/S y solicita Instrucciones de la Cola de Instrucciones
del BIU.
El EU y el BIU trabajan en Paralelo
El ALU incluye registro de Banderas
La unidad aritmética lógica ALU, es donde la mayoría de acciones toman lugar
entro del CPU. Por ejemplo, si se suma el valor 5 al registro AX, el CPU:
Copia el valor desde AX a el ALU.
Envía el valor 5 al ALU.
Instruye al ALU para sumar esos dos valores
Mueve el resultado de regreso al registro AX.
Para realizar sus funciones las instrucciones deben llevar 4 campos de
Información a esta Unidad de Control.
CODIFICADO 1. La operación a realizarse
COMO 2. La Localización (fuente) de algunos operandos
UNA 3. La localización (destino) de algunos resultados generados.
INSTRUCCIÓN 4. La localización de la siguiente instrucción a ejecutar
OPERATION CODE OPERATION ADDRES OPERAND ADRESS
Ejemplo:
ADD AX, VAR1
0000 0011 0000 0110 0000 0000 0001 0111
CODIGO DE LA DIRECCIÓN EN EL DIRECCIÓN EN LA UNIDAD DE MEMORIA
OPERACIÓN ALU AUX
0001 0111
0000 0000
0000 0110 INSTRUCCIÓN ADD AX,VAR1
0000 0011
MODOS DE DIRECIONAMIENTO Y CALCULO DE DIRECCIONES EFECTIVAS
Las direcciones efectivas se calculan de la Información presente en la
Instrucción que empieza a ejecutarse y frecuentemente de la
Información encontrada en los registros generales localizados en la
Unidad de Ejecución.
La forma en que se realice este cálculo depende del modo de
direccionamiento especificado por la Instrucción.
El grupo de registros apuntador e índice se usan generalmente para
funciones de direccionamiento.
0 4 B Ch 0 0 0 3h = 0 4 BCFh
Dirección Lógica Dirección real
04BC Direccción Base de Segmento
CS= 0 4 B C
04BD
04BE
04BF
04C0
Las instrucciones x86 usan 5 diferentes tipos de operandos: registros, constantes y
tres esquemas de direccionamiento de memoria. Cada forma se llama modo de
direccionamiento. Los procesadores x86 soportan el modo de direccionamiento por
registro, el modo de direccionamiento inmediato, modo de direccionamiento
indirecto, modo de direccionamiento indexado y el modo de direccionamiento
directo.
Nota: El ejemplo anterior ilustra la forma de calcular la direcciòn rela partir de la
direcciòn lògica, hay que tomar en consideración ya en tèrminos reales, que el
04BC[0], por la naturaleza de las direcciones base de segmento llevan un 0 (cero)
sobreentendido.
DIRECCIONAMIENTO POR REGISTRO
Los Registros pueden proporcionar uno o ambos operandos fuentes y
pueden ser diseñados como el destino resultado de las Instrucciones
Son más cortos y más rápidos
Instrucción: ADD CX,DX
Operación:
DIRECCIONAMIENTO INMEDIATO
El operando se almacena con la Instrucción en Memoria
El operando Inmediato se introduce a la E.U. a traves de la cola de
Instrucciones, esto reduce el tiempo requerido para capturar el operando.
Ejemplo:
Instrucción ADD AL,6
Operación
AL
0000 0110
0000 0100
DIRECCIONAMIENTO DIRECTO
La dirección se toma del Operando ( se toma directamente del campo en la
Instrucción)
Instrucción: ADD AX,ALPHA
Código: 0000 0011 0000 0110 0000 0000 0000 1111
Operación:
AX
n+2
n+1
n
[DS] + ‘F01h
[DS] + ´F00h
DIRECCIONAMIENTO INDIRECTO
Con el direccionamiento Indirecto, la Dirección Efectiva se encuentra en
el DI,SI ó BX.
La dirección se encuentra directamente accesando a un Registro.
Instrucción ADD SI,[DI]
Operación:
DI DS
0FAB
SI
001C
0000 0001
DIRECCIONAMIENTO BASE
Los Registros BX, ó BP se pueden designar como registros de base en el
càlculo de Dirección efectiva de un Operando.
En ambos casos, el contenido del Registro Dirección Desplazamiento ( 8
ó 16 Bits ) contenidos en la Instrucción para formar la Dirección Efectiva.
Ejemplo:
ADD AX,[BX +70h]
Codigo: 000 0011 0100 0111 0111 0000 BX
Operación:
DS
0111 0000 n+2
AX 0100 0111 n+1
0000 0011 n
0000 1111
DIRECCIONAMIENTO INDEXADO
Los Registros SI y DI son referidos como Registros Indice.
La Dirección Efectiva se calcula como la suma del Contenido de un
registro Indice con un desplazamiento ( 8 ó 16 Bits ) contenido en la
Instrucción.
Ejemplo: ADD DX, [SI + ARRAY]
Código: 0000 0011 1001 0100 0000 0000 0000 1111
Operación:
SI
0000 1111
0070
0000 0000
1001 0100 n+3
n+2
0000 0011
DX n n+1
n DS
DIRECCIONAMIENTO BASE-INDEXADO
En el D-B-I se suma el contenido del Registro Base y el Registro
Indexado o el desplazamiento para formar una Dirección
Efectiva.
Ejemplo:
Instrucción: ADD AL, [BX + SI + 32]
Codigo: 0000 0010 0100 0000 0011 0010
BX
SI
AL 0011 0010
0100 0000 DS
0000 0010
UNIDAD 3. Programación en Ensamblador: grupo de instrucciones
3. 1Transferencia de datos
Las instrucciones de transferencia de datos son las encargadas de mover datos de un byte
o de una palabra de un sitio a otro de la computadora como pueden ser la memoria, el
espacio de E/S y los registros del CPU. La Tabla 1 lista estas instrucciones y da una breve
nota sobre la operación de cada una de ellas.
Tabla 1. Instrucciones de transferencia de datos
Código de operación Función
MOV Transfiere una palabra o un byte
PUSH Transfiere una palabra a la pila
PUSHF Introduce el registro de bandera a la pila
LAHF Transfiere el registro de banderas a AH
SAHF Transfiere AH al registro de bandera
POP Extrae una palabra de la pila
POPF Carga el registro de banderas con una palabra de la pila
IN Lee un dato desde un dispositivo de E/S al acumulador
OUT Transfiere un dato del acumulador a un dispositivo de E/S
XCHG Intercambia una palabra o byte
XLAT Traduce (utiliza una Tabla {Lookup Table})
LEA Carga la dirección efectiva
LDS Carga DS y el operando con una dirección de 32 bits
LES Carga ES y el operando con una dirección de 32 bits
INSTRUCCIONES PUSH/POP
PUSH y POP son instrucciones importantes utilizadas para meter o sacar datos del
Segmento de Stack que tiene una estructura de pila. Solo acepta registros de 16 bits como
argumento. La ejecución de instrucciones PUSH y POP, está relacionada con los
apuntadores SP y BP:
SP: Stack Pointer. Uso: Permite Implementación de un Stack en memoria. Asociado con el
registro SS para direccionar el Stack.
BP: Base Pointer. Uso: Facilita la referencia a parámetros (datos y direcciones vía Stack)
INSTRUCCIÓN PUSH
El siguiente ejemplo, explica el funcionamiento de la instrucción PUSH. La instrucción
PUSH siempre transfiere 2 bytes de información a la pila. Después de que el dato se ha
metido a la pila, el registro SP es decrementado en 2.
Valores iniciales de los registros implicados:
SP: SS: IP: AX: BX: CX:
FFEE 1389 0100 151B 34EF 4BCA
Instrucciones a ejecutar:
SS
PUSH AX 1389
PUSH BX
PUSH CX SP (Tope de la pila)
FFE8
1389 :FFE8
1389:FFE9
4B
1389:FFEA
CA
1389:FFEB
34
1389:FFEC
EF
1389:FFED 15
1389:FFEE 1B
INSTRUCCIÓN POP
La instrucción POP realiza lo inverso a la instrucción PUSH. POP remueve y extrae datos de
la pila a un registro, indicado en el argumento de la instrucción. Después de dos bytes
fueron extraídos de la pila, el apuntador de pila (SP) es incrementado en 2.
El siguiente ejemplo, explica el funcionamiento de la instrucción POP. La instrucción POP
siempre transfiere 2 bytes de información de la pila a un registro de 16 bits. Después de
que el dato se ha extraído de la pila, el registro SP es incrementado en 2.
Valores iniciales de los registros implicados:
SP: SS: IP: AX: BX: CX:
FFE8 1389 0100 151B 34EF 4BCA
SS
1389
Instrucciones a ejecutar:
POP AX
POP BX 1389 :FFE8
1389:FFE9
SP 1389:FFEA
1389:FFEB
FFEC 1389:FFEC
1389:FFED 15
1389:FFEE 1B
PUSHF
La instrucción PUSHF copia el contenido del registro de banderas a la pila (Segmento de
Stack). Al igual que la instrucción PUSH, después del almacenar el registro de banderas, SP
se decrementa 2 unidades.
POPF
La instrucción POPF realiza la operación inversa de PUSHF, POPF remueve y extrae de la
pila un dato de 16 bits al registro de banderas.
LAHF
Carga el registro AH con banderas, LAHF copia el byte de orden inferior del registro de
banderas en AH. Después de la ejecución de esta instrucción, los bits 7,6,4,2 y 1 de AH son
iguales a las banderas S, Z, A, P y C respectivamente.
SAHF
Almacena AH en el registro de banderas, SAHF copia el contenido de AH en el byte de
orden inferior del registro de banderas. Después de la ejecución de esta instrucción las
banderas S, Z, A, P y C son iguales a los bits 7, 6, 4, 2 y 1 de AH, respectivamente.
IN y OUT
PUERTOS:
Conectan al procesador al Mundo Externo.
Reciben una señal.
Envían una señal a dispositivos ( pantalla)
Aunque extravagante el procesador puede manejar hasta 65,563 puertos.
Cada puerto tiene un número único empezando por el puerto 0.
E/S se realiza directamente a nivel de puerto
Instrucción ensamblador para leer datos de un puerto: In.
Escribir datos- salida a través de un Puerto: Out
La transferencia de datos desde un puerto de entrada se realiza en el registro AL si es un
byte y en el registro AX si es un Word.
Sintaxis
IN PUERTO, reg
Out puerto, reg
El puerto puede ser especificado de manera estática directamente dado como operando el
número de puerto en el rango de 0 a 256.
Ejemplo:
IN
AL,
port
#
Out
#por
t ,ax
Otra opción es dar el número de puerto Dinámicamente a través del uso de una variable:
Indirectamente por el contenido del Registro DX.
Mov AL,
byte
Mov DX,
#puerto
OUT
DX,AL
La Tabla 2 muestra una lista de la formas de las instrucciones IN y OUT. Note que solo el
registro AL y AX están siendo utilizados para la transferencia de datos entre los
dispositivos de E/S y el microprocesador. La instrucción IN transfiere un dato desde un
puerto E/S al registro AL o AX, y la instrucción OUT transfiere una dato del registro AX o
AL a un puerto de E/S.
Existen dos formas para el direccionamiento de puertos con la instrucción IN y OUT las
cuales son: puerto fijo y puerto variable. El direccionamiento con puerto fijo permite la
transferencia de datos entre AL o AX y un puerto de E/S con dirección de 8 bits. Se le llama
direccionamiento "puerto fijo" porque la dirección de puerto se almacena con la instrucción
(análogamente al direccionamiento inmediato).
El direccionamiento puerto variable permite la transferencia de datos entre AL o AX y un
puerto de E/S con dirección de 16 bits. A este direccionamiento se le llama puerto variable
porque la dirección del puerto se almacena en el registro DX, el cual puede ser cambiado
por el programador.
Tabla 2. Instrucciones IN y OUT.
Código de operación Función
IN AL, pp Un dato de 8 bits se transfiere del puerto pp a
AL IN AX,pp Un dato de 16 bits se transfiere del puerto pp a
AX IN AL,DX Un dato de 8 bits se transfiere del puerto DX a
AL IN AX,DX Un dato de 16 bits se transfiere del puerto DX a
AX OUT pp,AL Un dato de 8 bits se transfiere de AL al puerto
DX OUT pp,AX Un dato de 16 bits se transfiere de AX al puerto
pp OUT DX,AL Un dato de 16 bits se transfiere de AL al puerto
DX OUT DX,AX Un dato de 16 bits se transfiere de AX al puerto
DX
Nota: pp= un puerto de E/S con dirección de 8 bits y DX = contiene la
dirección de un puerto de E/S con dirección de 16 bits.
XCHG
La instrucción XCHG intercambia el contenido de cualquier registro con el contenido de
cualquier otro registro o localidad de memoria. No incluye los registros de segmento o
intercambios de memoria a memoria. La Tabla 3 muestra las formas de la instrucción
XCHG y el tamaño de la misma.
Tabla 3. Instrucción XCHG
Código de operación Tamaño de la instrucción
XCHG AX,reg 1 byte
XCHG reg,reg 2 byte
XCHG reg,mem 2 byte
XLAT
La instrucción XLAT (translate) convierte el contenido del registro AL en un número
almacenado en una tabla. Esta instrucción se utiliza para realizar una técnica directa de
conversión de un código a otro (lookup table). Una instrucción XLAT primero suma el
contenido de AL con el contenido del registro BX para formar una dirección del segmento
de datos, luego el dato almacenado en esta dirección es cargado en el registro AL. Esta
instrucción no posee operando, ya que siempre opera sobre AL.
LEA
La instrucción LEA se utiliza para cargar un registro con la dirección de un dato
especificado por un operando (Variable). En el primer ejemplo de la Tabla 4 la dirección de
DATA se almacena en el registro AX, cabe notar que la dirección y no el contenido de la
dirección DATA se almacena en el registro AX.
En una comparación de la instrucción LEA con MOV se puede observar lo siguiente: LEA
BX,[DI] carga la dirección especificada por [DI] (contenido de DI) en el registro BX.
Tabla 4. Instrucción XCHG
Código de operación Función
LEA AX,DATA AX se carga con la dirección de DATA (16 bits)
LDS DI,LIST DI y DS se cargan con la dirección de LIST (32 bits- DS:DI)
LES BX,CAT BX y ES se cargan con la dirección de CAT (32 bits -
ES:BX)
Ahora ¿por que si la directiva OFFSET realiza la misma tarea que la instrucción LEA está
disponible? La respuesta es que OFFSET se puede usar solamente para un operando
sencillo tal como LIST, DATA etc., esta directiva no puede utilizarse en operandos como
[DI], LIST[SI]. La directiva OFFSET es más eficiente que LEA para operandos sencillos,
esto es, el microprocesador 8088 toma ocho ciclos de reloj para ejecutar la instrucción en
cambio OFFSET requiere solo cuatro ciclos de reloj.
LDS y LES
Las instrucciones LDS y LES cargan un registro de 16 bits con un desplazamiento
(dirección) y el registro segmento DS o ES con una nueva dirección de segmento. Estas
instrucciones utilizan cualquier modo de direccionamiento a memoria válido para
seleccionar la localidad del nuevo desplazamiento y nuevo valor de segmento.
3.2 Instrucciones aritméticas
INSTRUCCIONES ADD y ADC
Realizan la suma y la suma con acarreo (bit CF del registro de estado) de dos operandos,
respectivamente, y guardan el resultado en el primero de ellos. Admiten todos los tipos de
direccionamiento (excepto que ambos operando estén en memoria).
ADD/ADC reg, reg
ADD/ADC mem, reg
ADD/ADC reg, mem
ADD/ADC reg, inmediato
ADD/ADC mem, inmediato
Ejemplo:
; AX = 34 + F
MOV AX, F
ADD AX, 34
Estas instrucciones afectan a los bits OF, SF, ZF, AF, PF, CF del registro de estado.
INSTRUCCIONES SUB Y SBB
Realizan la resta y la resta con acarreo, respectivamente, de dos operandos y guardan
el resultado en el primero de ellos. Admiten todos los modos de direccionamiento,
excepto dos operando en memoria.
SUB/SBB reg, reg
SUB/SBB mem, reg
SUB/SBB reg, mem
SUB/SBB reg, inmediato
SUB/SBB mem, inmediato
Ejemplo:
; AX = F-34
MOV AX, F
SUB AX, 34
Estas instrucciones afectan a los bits OF, SF, ZF, AF, PF, CF del registro de estado.
INSTRUCCIÓN NEG
Realiza la operación aritmética de negado de un operando y guarda el resultado en el
mismo operando. Combina el signo de positivo a negativo y de negativo a positivo, para
ello realiza un complemento a 2. Admite todos los tipos de direccionamiento, excepto
inmediato.
NEG reg
NEG mem
Afecta a todos los bits del registro de banderas, poniendo el bit AF a 1.
INSTRUCCIONES MUL e IMUL
Realizan la multiplicación y multiplicación con signo, respectivamente, de contenido de AX
y del operando indicado, guardando el resultado en AX, para operaciones de 8 bits y en
DX:AX para operaciones de 16 bits. Los formatos son:
MUL/IMUL reg
MUL/IMUL mem
Ejemplo:
MOV AX, FFF0h
MOV BX, 3
MUL BX ;DX:AX = FFF0h*3
AX FFD0
AX FFF0
BX 0003
BX 0003
DX 0002
INSTRUCCIONES DIV e IDIV
Realizan la división y la división con signo, respectivamente. De AX entre el operando para
operaciones de 8 bits, guardando el cociente en AL y el resto en AH; y DX:AX entre el
operando para operaciones de 16 bits guardando el cociente en AX y el resto en DX.
DIV/IDIV reg
DIV/IDIV mem
Ejemplo:
MOV AX, FFF1h
MOV BX, 7
DIV BX
FFF5 AX 2490
AX
BX 0007
BX0007
DX 0005
INSTRUCCIONES INC y DEC
Realizan las operaciones de incremento y decremento, respectivamente, de un operando,
guardando el resultado en el mismo operando. Admiten todos los modos de
direccionamiento excepto el inmediato.
INC/DEC reg
INC/DEC mem
Afectan a todos los bits de estado del registro de estado.
INTRUCCIONES LÓGICAS
Realizan las operaciones lógicas y son: OR, XOR, AND, NOT, TEST, CMP
INSTRUCCIONES AND, OR y XOR
Estas operaciones son bit a bit. La tabla de verdad cada una de estas funciones es:
Operandos AND OR XOR
0 0 0 0 0
0 1 0 1 1
1 0 0 1 1
1 1 1 1 0
Admiten todos los modos de direccionamiento excepto los dos operandos en memoria.
INSTRUCCIÓN AND
AND/OR/XOR reg, reg
AND/OR/XOR reg, mem
AND/OR/XOR mem, reg
AND/OR/XOR reg, inmediato
AND/OR/XOR mem, inmediato
Afectan a los bits SF, ZF, PF del registro de estado. Además ponen a cero los bits CF y OF.
Podemos utilizar la operación AND para filtrar o enmascarar bits. Por ejemplo, suponga
que AL=53h, si deseamos enmascarar la parte más baja de AL, se requiere conformar una
máscara cuyo valor sea 0Fh, tal que permita esta operación:
0101 0011 AL=53
AND 00001111 Máscara= 0F
00000011 RESULTADO=03
INSTRUCCIÓN OR
Podemos utilizar la operación OR, por ejemplo si deseamos prender los bits impares,
suponga que AL=00h, ¿Cuál debería ser la máscara? La respuesta es máscara= 55h:
0000 0000 AL=00
OR 01010101 Máscara= 55
01010101 RESULTADO=55
INSTRUCCIÓN XOR
Podemos utilizar la operación XOR, por ejemplo si deseamos convertir código hexadecimal
de mayúsculas a minúsculas. Si se observa la tabla de ASCII, la diferencia entre el código de
mayúsculas a minúsculas es sólo el bit 5. El código de la A= 41h=0100 0001 y a=61h=01100
0001 ¿Cuál debe ser la máscara que convierta cualquier carácter de mayúsculas a
minúsculas y viceversa? La respuesta es, máscara= 20h:
0100 0001 AL=41
XOR 0010 0000 Máscara= 20
01100001 RESULTADO=61
Note que el operador lógico XOR, también tiene la posibilidad de invertir en ambos
sentidos:
0110 0001 AL=61
XOR 0010 0000 Máscara= 20
0100 0001 RESULTADO=41
INSTRUCCIÓN NOT
Realiza la operación de negado lógico de los bits del operando, Cambia 0’s por 1’s y
viceversa, guardando el resultado en el mismo operando. Admite todos los modos
direccionamiento excepto inmediato. Las Banderas no se afectan.
NOT reg
NOT mem
No afecta a ningún bit del registro de estado.
INTRUCCIONES DE COMPARACIÓN
Estas instrucciones realizan funciones de comparación no guardando el resultado, pero si
afecta al registro de estado (no cambian a los operandos). Son muy útiles en las
instrucciones de salto. Las instrucciones de comparación son TEST y CMP.
INTRUCCIÓN TEST
Realiza la operación lógica “AND” de dos operandos, pero NO afecta a ninguno de ellos,
SÓLO afecta al registro de banderas. Admite todos los tipos de direccionamiento excepto
los dos operandos en memoria:
TEST reg, reg
TEST reg, mem
TEST mem, reg
TEST reg, inmediato
TEST mem, inmediato
Afecta a todos los bits del registro de banderas, de la misma manera que la instrucción
AND.
INTRUCCIÓN CMP
Internamente resta operando 2 del operando 1 pero no cambia los valores, los operandos
deben ser ambos byte o ambos word, sólo afecta al registro de banderas. Admite todos los
modos de direccionamiento, excepto los dos operando en memoria.
CMP reg, reg
CMP reg, mem
CMP mem, reg
CMP reg, inmediato
CMP mem, inmediato
Se usa con las instrucciones de salto.
3.3 Rotaciones y corrimientos
CORRIMIENTOS
La instrucción de corrimiento desplaza el contenido de AL, un bit a la izquierda o a la
derecha según sea el caso, llena automáticamente con 0 (cero) el bit que queda vacío. Son
parte de la capacidad lógica de la computadora, pueden realizar las siguientes acciones:
Hacer referencia a un registro o dirección de memoria.
Recorre bits a la izquierda o a la derecha.
Recorre hasta 8 bits en un byte, 16 bits en una palabra y 32 bits en una palabra doble.
Corrimiento lógico (sin signo) o aritmético (con signo).
El primer operando de la instrucción, contiene el valor al que se le aplicarán los
corrimientos y el segundo operando de la instrucción, la cantidad de corrimientos a aplicar,
puede ser un valor constante o el valor dado en el registro CL.
En los corrimientos, los bits más izquierdos o más derechos, son llenados con 0 (cero)
según sea el caso de corrimiento a la izquierda o a la derecha. Un valor de corrimiento de 1
puede codificarse como un operando inmediato, un valor mayor que 1 puede estar
contenido en el registro CL.
SHR Shift Unsigned Right
SHL Shift Unsigned Left
Ejemplo de corrimientos a la derecha:
MOV AX, 1101 0011 ; AX = 1101 0011
SHR AX,1 ; AX = 01101001
MOV CL,03
SHR AX, CL ; AX = 00110100
; AX = 00011010
; AX = 00001101
CORRIMIENTO ARITMÉTICO
La instrucción de corrimiento aritmético desplaza el contenido de AL, un bit a la izquierda
o a la derecha según sea el caso, llena automáticamente con el bit de signo el bit que
queda vacío.
SAR Shift Arithmetic Right
SAL Shift Arithmetic Left
Ejemplo de corrimientos aritmético a la derecha:
MOV AX, 1101 0011 ; AX = 1101 0011
SAR AX,1 ; AX = 11101 001
MOV CL,03
SAR AX, CL ; AX = 11101 001
; AX = 111101 00
; AX = 1111101 0
ROTACIÓN DE BITS ( DESPLAZAMIENTO CIRCULAR )
Son parte de la capacidad lógica de la computadora, pueden realizar las siguientes
acciones:
Hacer referencia a un byte o a una palabra
Hacer referencia a un registro o a memoria
Realizar rotación a la derecha o a la izquierda, el bit que es desplazado fuera, llena el espacio
vacante en la memoria o registro y también se copia en la bandera de acarreo.
Realizar rotación hasta 8 bits en un byte, 16 bits en una palabra y 32 bits en una palabra
doble.
Realizar rotación lógica ( sin signo ) o aritmética (con signo)
ROR Rota a la derecha Right
ROL Rota a la izquierda Left
Ejemplo de rotación a la derecha:
MOV AX, 1101 0011 ; AX = 1101 0011
ROR AX,1 ; AX = 11101 001
MOV CL,03
ROR AX, CL ; AX = 11101 001
; AX = 111101 00
; AX = 0111101 0
Cada bit que se desplaza fuera, se va a la bandera de Carry (CF)
3.4 Transferencia de Programa
La mayoría de los programas constan de varios ciclos en los que una serie de pasos se
repite hasta alcanzar un requisito específico y varias pruebas para determinar que acción se
realiza de entre varias posibles. Una práctica común es verificar si un programa está al final
de su ejecución. Requisitos como éstos implican la transferencia de control a la dirección
de una instrucción que no sigue de inmediato de la que se está ejecutando actualmente.
Una transferencia de control puede ser hacía adelante, para ejecutar una serie de pasos
nuevos, o hacia atrás, para volver a ejecutar los mismos pasos.
La forma más común para transferir el control en programas de lenguaje ensamblador es
usando instrucciones denominadas salto, dentro de los cuales están los “Saltos
incondicionales” y los “Saltos condicionales”.
Saltos incondicionales
Los saltos incondicionales saltan hasta la etiqueta destino de forma automática, quiere
decir que no necesita cumplir con algún tipo de condición.
SINTAXIS
JMP destino
EJEMPLO
1. JMP EtiquetaFin ; desde aquí saltará hasta las líneas 5 y 6.
2. mov ax,5 ; las líneas de la 2 a la 4 no se ejecutarán
3. mov bx,8
4. add ax,bx
5. EtiquetaFin:
6. mov dx,1 ; sí se ejecutará
Saltos condicionales
Las instrucciones de brincos condicionales ejecutan un proceso de dos pasos:
1. Primero comprueban la condición.
2. Posteriormente realizan el salto si la condición es verdadera o continúan si ésta es falsa.
Las instrucciones de brincos pueden ser divididas dentro de cuatro grupos:
1. Saltos basados en el valor de una del registro de banderas.
2. Saltos basados en el valor de los registros CX o ECX.
3. Saltos basados en comparaciones de operandos con signo. Un campo de datos trata el bit
más izquierdo como un signo, donde cero es positivo y uno es negativo
4. Saltos basados en comparaciones de operandos sin signo.
Para usar correctamente los brincos condicionales, es muy importante entender que hay
dos tipos de datos: Datos con signo y datos sin signo, entonces por ejemplo, dados los
valores de Ax y BX, ¿ Quién es mayor ? ¿ Es AX>BX ? o ¿Es BX > AX?:
AX= 11001000 y BX=00010110
CMP AX,BX ; Es AX > BX ? ó BX > AX ?
a) Si los valores de AX y BX, son destinados a realizar operaciones aritméticas, entonces
podríamos asumir los datos de AX y BX como DATOS CON SIGNO.
b) Si los valores de AX y BX representan valores ASCII, entonces podríamos asumir los valores
de Ax y Bx como DATOS SIN SIGNO.
Entonces, dependiendo de si un dato es considerado como dato con signo o sin signo, son
la instrucciones que usaremos, debido a que hay un grupo saltos condicionales para datos
con signo y un grupo de saltos condicionales para datos sin signo.
SINTAXIS
Las instrucciones de brincos tienen la siguiente sintaxis:
Jcond destino; donde cond es la condición para el salto, y destino es la etiqueta
a donde ser requiere que salte el programa.
En Las Tablas 1, 2, 3 y 4, se listan las diferentes instrucciones de salto condicional.
Tabla 1. Instrucciones para brincos, basadas en el registro bandera.
Mnemónico Descripción Banderas
(”Flags”)
JZ, JE Salta si es cero, Salta si es igual ZF = 1
JNZ, JNE Salta si no es cero, Salta si no es igual ZF= 0
JC Salta si hay acarreo CF = 1
JNC Salta si no hay acarreo CF = 0
JO Salta si hay “overflow” OF= 1
JNO Salta si no hay “overflow OF = 0
JS Saltasi hay signo (Negativo) SF = 1
JNS Salta si no hay signo (Positivo o cero) SF = 0
JP, JPE Salta si hay paridad, Salta si la paridad es PF = 1
par
JNP, JPO Salta si no hay paridad, Salta si la paridad PF = 0
es impar
Tabla 2. Instrucciones para brincos basadas en los valores del registro CX y ECX
Mnemónico Descripción
JCXZ Salta si CX es cero
JECXZ Salta si ECX es cero
Tabla 3. Instrucciones para brincos, basadas en comparaciones de operandos con signo.
Mnemónico Descripción Condición
JG, JNLE Salta si es más grande, Salta si no es ZF = 0 y SF = OF
menor o igual
JGE, JNL Salta si es más grande o igual, Salta si SF= OF
no es menor
JL,JNGE Salta si es menor, Salta si no es más SF ≠ OF
grande o igual
JLE, JNG Salta si es menor o igual, Salta si no es ZF = 1 o SF ≠ OF
más grande
Tabla 4. Instrucciones para brincos, basadas en comparaciones de operandos sin signo.
Mnemónico Descripción Condición
JA, JNBE Salta si el primer operando es más ZF = 0 y CF = 0
grande, Salta si el primer operando no
es menor o igual
JAE, JNB Salta si es el primer operando es más o CF= 0
igual, Salta si el primer operando no es
menor
JB,JNAE Salta si el primer operando es menor, CF = 1
Salta si el primer operando no es más
grande o igual
JBE, JNA Salta si el primer operando es menor o ZF = 1 o CF = 1
igual, Salta si el primer operando no es
más grande
EJEMPLOS:
INSTRUCCIÓN JE
1. CMP op1,op2 ; se realiza la comparación entre los operandos op1 y op2
2. JE Etiqueta ; si los operandos son iguales desde aquí saltará hasta la línea 6.
3. mov ax,5 ; caso contrario ejecutará de la línea 3 a la 5
4. mov bx,8
5. add ax,bx
6. Etiqueta:
7. mov dx,1
INSTRUCCIÓN JNE
1. CMP op1,op2 ; se realiza la comparación de los operandos op1 y op2
2. JNE Etiqueta ; si los operandos son diferentes desde aquí saltará hasta la línea 6
3. mov ax,5 ; caso contrario ejecutará desde la línea 3 hasta la línea 5
4. mov bx,8
5. add ax,bx
6. Etiqueta:
7. mov dx,1
INSTRUCCIÓN JZ
1. SUB op1,op2 ; se realiza la operación aritmética resta entre los operandos op1 y op2
2. JZ Etiqueta ; si el resultado es cero, entonces desde aquí saltará y ejecutará las líneas 6 y
7
3. mov ax,5 ; caso contrario ejecutará desde la línea 3 hasta la línea 5
4. mov bx,8
5. add ax,bx
6. Etiqueta:
7. mov dx,1
INSTRUCCIÓN JNZ
1. SUB op1,op2 ; se realiza la operación aritmética resta entre los operandos op1 y op2
2. JNZ Etiqueta ; si el resultado es diferente de cero, entonces saltará y ejecutará las líneas 6
y7
3. mov ax,5 ; caso contrario ejecutará desde la línea 3 hasta la línea 5
4. mov bx,8
5. add ax,bx
6. Etiqueta:
7. mov dx,1
3.4 Ciclos
La instrucción LOOP realiza un ciclo un número fijo y específico de veces, almacenado en
el registro CX. Por lo que el LOOP requiere un valor inicial en el registro CX, en cada
iteración, el LOOP de forma automática decrementa en 1 el registro CX. Si después de
decrementar CX, el valor en el registro CX no es cero, el control apuntado por el IP
(instruction pointer) pasa a la dirección del operando. Si el valor de CX es cero, el control
llevado por el apuntador a instrucciones IP, pasa a la siguiente instrucción fuera del ciclo.
La distancia de conjunto de instrucciones dentro del LOOP, debe ser un salto corto, desde
-128 hasta +127 bytes. Para una operación que exceda este límite, el ensamblador envía un
mensaje como “Salto relativo fuera de rango”.
Ejemplo de ciclos
Ejemplo del uso de LOOP para imprimir en pantalla una barra de caracteres ASCII en
cuadros de cuatro por cuatro:
ETIQUETA :INSTRUCCIONES COMENTARIOS
Mov CX, 0008 ; Repite 8 veces para completar la barra
DENUEZ:PUSH CX ; Guarda el valor de CX
MOV CX, 0004 ; Imprime 4 `*`
X:MOV DL,2A
MOV AH,02
INT 21
LOOP X
MOV CX, 0004 ; Imprime 4 espacios
Y:MOV DL,20
MOV AH,02
INT 21
LOOP Y
MOV DL,0A ; Imprime Line Feed
MOV AH,02
INT 21
MOV DL,0D ; Imprime Carry Return
MOV AH, 02
INT 21
POP CX
LOOP DENUEZ ; si CX aún no es cero causa que el IP
regrese a la etiqueta DENUEZ.
Dos variaciones de ciclos
Existen dos variaciones de la instrucción LOOP , ambas también decrementan el CX en 1:
LOOP/LOOPZ Repite el ciclo mientras sea igual o repite el
ciclo mientras sea cero.
LOOPNE/LOOPNZ Repite el ciclo mientras no sea igual o repite
el ciclo mientras no sea cero.
3.6 Depurador para lenguaje de bajo nivel
Dentro de la programación del lenguaje ensamblador, se considera que una de las fases
más importantes del desarrollo de cualquier programa es el proceso de depuración. Dicho
proceso adquiere aún más importancia al programar en ensamblador, dado que las
operaciones efectuadas son de muy bajo nivel y cualquier fallo puede provocar un
funcionamiento erróneo o incluso el fallo del sistema. Un ejemplo de un depurador es “
Debug” que funciona en plataforma del sistema operativo DOS y ejecuta líneas de
comandos accediendo a posiciones de memoria para editar código en lenguaje
ensamblador. Debug trabaja en el sistema hexadecimal para el ingreso de datos y para
visualizar sólo muestra los caracteres o símbolos disponibles en código ASCII.
Características de DEBUG:
› Despliega todo el código del programa y los datos en forma hexadecimal.
› Permite ejecutar un programa en modo de paso sencillo (un paso a la vez), de
manera que pueda ver el efecto de cada instrucción sobre las localidades de memoria y los
registros.
INSTALACIÓN DEL DEBUG
En las arquitecturas X86 de 64 bits, el debug se utiliza mediante el “DOSBOX” que se
descarga en la dirección https://www.dosbox.com/download.php?main=1. Una vez
instalado el DOSBOX, se agrega automáticamente el ícono que se muestra en la figura 1.
Posteriormente se debe descargar el archivo empaquetado, “debug.exe”, de la página
http://www.mediafire.com/file/bopdmu16tav8thg/debug.zip/file; Una vez descargado, lo
recomendable crear una carpeta con el nombre debug (figura 2), en la raíz del disco duro y
, desempaquetarlo en dicha carpeta (figura 3), de tal manera que pueda ser más fácil
montarlo en la aplicación del DOSBOX para ejecutarlo.
Figura 1. Ícono debug DosBox
Figura 2. Archivo debug.exe desempaquetado en la unidad C del disco duro.
Figura 3. Archivo debug,exe guardado en la carpeta Debug de la unidad C.
INSTRUCCIONES PARA EJECUTAR EL DEBUG
Los pasos a seguir para ejecutar los comandos del debug son los siguientes:
1. Ejecutar el DOSBox, al hacerlo aparecerá una pantalla como la de la figura 4, en la cual se
puede observar que la aplicación queda activa en la unidad Z.
2. Considerando que se tiene el archivo “debug.exe” en la carpeta Debug de la unidad C:\, el
siguiente paso es activar o “montar” la unidad y la carpeta, para que pueda ser reconocida
por la aplicación del DOSBox, tecleando la siguiente instrucción de la línea de comando del
DosBox (ver figura 5):
Mount c: c:\Debug
3. En la línea de comandos escribimos c: (ver figura 6). AL hacerlo cambiamos de la unidad Z a
la unidad C, y más específicamente al directorio Debug.
4. Finalmente, ejecutamos el depurador escribiendo el comando “debug”; al hacerlo aparecerá
un guion medio (-), que indica que ya esta activa la línea de comandos del depurado, como
se muestra en la figura 8.
Figura 4. Entorno de comandos del debug DosBox
Figura 5. Ejecución del comando “mount” para activar la unidad c,y el directorio Debug del
dico duro.
Figura 6. Instrucción para cambiar de unidad.
Figura 7. Ejecutar el archivo debug para activar el depurador.
COMANDOS DEL DEBUG
ASSEMBLE (A)
El comando A se usa para introducir mnemotécnicos de ensamblador y que éstos se
traduzcan directamente a lenguaje de máquina en memoria.
La sintaxis es
A <dirección>
Prácticamente cualquier mnemotécnico es soportado por DEBUG, incluyendo los
especificadores de "override" de segmento (CS:, DS:, ES:, SS:).
Ejemplo
- a 0100 Indica la dirección donde se empezarán a almacenar las instrucciones del programa
(ver figura 8)
Figura 8. Ejemplo de la ejecución del comando “a”.
COMPARE (C)
Este comando compara y reporta diferencias entre los contenidos de dos bloques de
memoria.
La sintaxis es:
C <bloque> <dirección>
<bloque> es la dirección de inicio y fin de un bloque o, si se preceden con "L", la dirección
de inicio y la longitud del bloque;
<dirección> es el inicio de otro bloque. Se presupone que la longitud de ambos bloques es
la misma.
DUMP (D)
Este comando despliega el contenido de una serie de localidades de memoria.
La sintaxis es:
D <dirección1> <dirección2>
Ambas direcciones son opcionales. La primeraa es la dirección de inicio de despliegue; la
segunda es la dirección de fin.
ENTER (E)
Este comando permite cambiar los contenidos de localidades específicas de memoria.
La sintaxis es:
E <dirección> <cambios>
<dirección> es el inicio de los cambios y
<cambios> es una lista opcional de los cambios deseados. Los cambios pueden ser
especificados en la línea de comandos en cualquier combinación de números
hexadecimales o caracteres ASCII; los caracteres ASCII deben estar entre comillas simples
o dobles.
Por ejemplo:
E 100 'Buenas Tardes'
Establece el patrón "42 75 65 6E 61 73 20 54 61 72 64 65 73" en memoria a partir de la
localidad 100H.
Cuando no se especifica <cambios> se entra en un modo especial en el que DEBUG
despliega los valores de <dirección>. Entonces es posible teclear nuevos valores que
reemplacen a los que se muestran. Si se teclea "-" DEBUG regresa a la localidad anterior. Si
se activa la barra espaciadora DEBUG pasa a la siguiente localidad.
FILL (F)
Este comando llena un bloque de memoria con un valor específico o una serie de valores.
La sintaxis es:
F <bloque> <valor de relleno>
<bloque> es la dirección de inicio y final o , si se preceden con "L", la dirección de inicio y la
longitud del bloque;
<valor de relleno> es(son) el(los) valor(es) con los que debe de llenarse el bloque. Si <valor
de relleno> representa menos bytes que los que se necesitan para llenar el bloque, la serie
se repite hasta llenar el bloque.
Por ejemplo, cualquiera de las siguientes dos líneas, llena (con 0s) el bloque DS:00FF:
F DS:0000 DS:00FF 0
F DS:0000 LFF 0
GO (G)
Este comando ejecuta el código en memoria. Si se está depurando un programa, permite
ejecutar el código cargado en memoria. También permite establecer puntos de quiebre
(breakpoints) que son direcciones en las que se detiene la ejecución del programa.
La sintaxis es:
G =<inicio> <quiebre1> <quiebre2> ... <quiebre10>
<inicio> es la dirección de inicio de ejecución;
<quiebre1> hasta <quiebre10> son direcciones opcionales de paro del programa.
Si no se especifica <inicio>, Go inicia con la dirección contenida en CS:IP. Para lograr los
quiebres, DEBUG reemplaza el código en las direcciones de quiebre por el valor
hexadecimal CC, que es el código de interrupción.
Si DEBUG llega a CC, todos los puntos de quiebre son restituidos, los registros se
despliegan y se para la ejecución.
LOAD (L)
Este comando se usa para cargar un archivo o sectores de disco a memoria.
La sintaxis es:
L <buffer> <numdisco> <sectorini> <numsector>
<buffer> es la dirección en donde se carga la información;
<numdisco> es el número (opcional) del disco de donde se leerá la información (0=A, 1=B,
2=C, etc.);
<sectorini> es el sector de disco absoluto (en hexadecimal) a leer;
<numsector> es la cantidad de sectores a leer.
No se pueden leer más de 80H (128) sectores. Si no se suministra la combinación
<numdisco> <sectorini> <numsector> DEBUG presume que se desea leer un archivo. En
este caso <buffer> es opcional.
Debe usarse el comando N para especificar el archivo a leer. Éste se carga en CS:0100.
MOVE (M)
Este comando mueve un bloque de memoria de una localidad a otra.
La sintaxis es:
M <bloque> <dirección>
<bloque> es la dirección de inicio y final o , si se preceden con "L", la dirección de inicio y la
longitud del bloque ;
<dirección> es la dirección destino.
El bloque de origen y la dirección destino pueden traslaparse.
NAME (N)
Este comando se usa para especificar el nombre del archivo usado por los comandos
LOAD y WRITE.
La sintaxis es:
N <nomarch1< <nomarch2>
<nomarch1> es la especificación de archivo completa que será "parseada" y colocada en el
bloque de control en CS:005C.
<nomarch2> es la especificación de archivo que será colocada en CS:006C.
La expresión tal cual se tecleó se almacena en CS:0081, precedida por el número de bytes
tecleados.
OUTPUT (O)
Este comando pone un byte en el puerto especificado.
La sintaxis es:
O <puerto< <valor>
<valor> es el byte hexadecimal a escribir en <puerto>.
QUIT (Q)
Este comando se usa para salir de DEBUG.
REGISTER (R)
Este comando despliega los registros del CPU y los valores de las banderas.
La sintaxis es:
R <registro>
<registro> es el nombre opcional y puede ser alguno de los siguientes: AX, BX, CX, DX, SP,
BP, SI, DI, DS, ES, SS, CS, IP, PC o F. IP y PC son sinónimos.
SEARCH (S)
Este comando permite buscar en un bloque de memoria una secuencia específica de
valores.
La sintaxis es:
S <bloque> <valor_a_buscar>
<bloque> <bloque> es la dirección de inicio y final o , si se preceden con "L", la dirección de
inicio y la longitud del bloque ;
<valor_a_buscar> es(son) el(los) valor(es) que deseamos buscar en el bloque.
TRACE (T)
Este comando permite ejecución paso-a-paso de las instrucciones de máquina. Después
de cada instrucción se muestra el estado de los registros.
La sintaxis es:
T =<inicio> <cuenta>
<inicio> es la dirección de inicio de la traza;
<cuenta> es el número de instrucciones a trazar.
UNASSEMBLE (U)
Este comando decodifica los valores de un grupo de localidades de memoria a
mnemotécnicos de 8086.
La sintaxis es la siguiente:
U <alcance>
<alcance>, que es opcional, es ya sea un par de direcciones de inicio y fin o, si se precede
con "L", la dirección de inicio y la longitud del área a desensamblar.
WRITE (W)
Este comando se usa para escribir un archivo a sectores individuales de disco a disco.
La sintaxis es:
W <buffer> <numdisco> <sectorini> <numsector>
<buffer> es la dirección de donde se carga la información;
<numdisco> es el número (opcional) del disco en donde se escribirá la información (0=A,
1=B, 2=C, etc.);
<sectorini> es el sector de disco absoluto (en hexadecimal) en donde empieza la escritura;
<numsector> es la cantidad de sectores a leer. No se pueden escribir más de 80H (128)
sectores.
Si no se suministra la combinación <numdisco> <sectorini> <numsector> DEBUG presume
que el inicio de archivo es CS:100. En este caso <buffer> es opcional. Debe usarse el
comando N para especificar el archivo a escribir.
Antes de escribir BX:CX debe ajustarse al número de bytes que desean grabarse.
W no puede escribir a archivos con la extensión EXE o HEX.
REGLAS DEL DEBUG
En DEBUG se especifican segmentos y desplazamientos con dos puntos (:)
en la forma:
segmento : desplazamiento
04BC:0100
DESPLIEGUE DEL DEBUG
Consiste en tres partes:
1. Dirección hexadecimal del último byte de la izquierda que se despliega en la
forma de segmento:desplazamiento
2. El área amplia del centro es la representación hexadecimal del área desplegada
3. A la derecha está la representación en ASCII
Dirección Representación hexadecimal ASCII
LÍMITES DE LOS SEGMENTOS
Un segmento inicia en un párrafo, que es por lo común una dirección divisible
por 16 dec. o 10H.
En todos los casos, el último dígito hexadecimal de la derecha es 0 los
diseñadores de computadora decidieron que sería innecesario almacenar el
dígito 0 en el registro del segmento.
3.7 CONVERSIÒN DE FORMATO ASCII A BINARIO
Realizar aritmética en formato ASCII o BCD sólo es adecuado para campos pequeños.
Para muchos propósitos aritméticos, es más práctico convertir tales números a formato
binario. De hecho, es más fácil convertir desde ASCII a binario, de manera directa, que
convertir de ASCII s BCD y luego binario.
El método de conversión, está basado en el hecho de que un número ASCII está en base
10 y la computadora realiza la aritmética en base 2. Aquí está el procedimiento:
1. Inicie con el byte de más a la derecha del número ASCII y procese de derecha a izquierda.
2. Quite el 3 del dígito hexadecimal de la izquierda de cada byte ASCII, para formar un número
BCD empaquetado.
3. Multiplique el primer dígito BCD por 1, el segundo por 10 (0Ah), el tercero por 100 ( 64h ) y
así sucesivamente, y sume los productos.
El ejemplo siguiente convierte el número ASCII 1234 a binario:
Decimal Hexadecimal
Paso Producto Paso Producto
4x1 = 4 4 x 01h = 4h
3 x 10 = 30 3 x 0Ah = 1Eh
2 x 100 = 200 2 x 64h = C8h
1 x 1000 = 1000 1 x 3E8h = 3E8h
Total: 1234 04D2h
Verifique que la suma 04D2h sea en realidad igual a 1234 decimal.
CONVERSIÒN DE FORMATO BINARIO A ASCII
Para imprimir o desplegar el resultado de aritmética binaria, tiene que convertirlo en
formato ASCII. La operación implica el inverso de los pasos anteriores: en lugar de
multiplicar, se debe dividir de manera continua entre 10 (0Ah) hasta que el cociente sea
menor que 10. Los residuos, que sólo puede ser del 0 al 9, generan de manera sucesiva el
número ASCII. Como un ejemplo, convierta 4D2h de regreso a formato decimal.
DIVIDE ENTRE 10 COCIENTE RESIDUO
A 4D2 7B 4
A 7B C 3
A C 1 2
Como el cociente (1) ahora es menor que el divisor (0Ah) la operación está terminada. Los
residuos, junto con el último cociente forman el resultado BCD, de derecha a izquierda:
1234. Todo lo que resta por hacer es almacenar estos dígitos en memoria, con los 3 ASCII,
como 31323334.
UNIDAD 4. Interrupciones y Traps.
INTERRUPCIONES
Una interrupción es una operación que interrumpe la ejecución de un programa para
que el Sistema pueda realizar una acción Especial.
Ejemplo de interrupción Trap. Connota la idea de alterar el flujo del programa cuando
una condición especial ocurre. Otros ejemplos de interrupción ocurren cuando sucede
un overflow, la función de la tecla Print Screen, división por cero, etc.
En general las interrupciones se clasifican en dos categorías a saber: Hardware y
software, es decir esta categorización se asocia a la forma en la que las interrupciones
son invocadas o provocadas. El esquema siguiente representa la jerarquía completa
de la clasificación de las interrupciones:
Tipos de Interrupciones
Hardware software
Externa Interna Sistema Usuario
Mascarable No mascarable Dos Bios
Interrupciones por Software
Estas interrupciones se dan como una respuesta a la instrucción ensamblador Int.
Cuando esta instrucción sucede se ejecuta un programa asociado a cada interrupción
invocada y que se llama rutina de servicio. Esta rutina de servicio se encarga de
realizar una tarea específica.
Sintaxis:
INT tipo_Interrupción
Cada Interrupción
1. Identifica un vector de 4 Bytes (en el Vector de Interrupción)
2. La dirección se encuentra multiplicando el tipo de Interrupción por 4.
3. La dirección especificada por el vector de Interrupciones es la dirección de
la rutina de Servicio de Interrupción asociada con el tipo de Interrupción.
Los vectores de las Interrupciones están almacenados en memoria y contienen una
dirección lógica completa:
- 2 Bytes de Segmento
- 2 Bytes de Offset
la suma de estos 4 bytes dan la dirección real del programa que contiene la rutina
de servicio asociada a cada interrupción.
VECTOR DE INTERRUPCIONES
CS Tipo 255
IP
.
.
.
0016 CS Tipo 5 Print Screen
0014 IP
0012 CS Tipo 4 Overflow
0010 IP
000E CS Tipo 3 Breakpoint
000C IP
000A 0010 010F CS Tipo 2 NMI
0008 7F41 112B IP
0006 001F
004B
F04B
007A CS Tipo 1 Single Step
0004 IP
0002 CS Tipo 0 División por 0
0000 IP
Obtener vector de interrupciones de un tipo de Interrupción:
Mov AH,35h
Mov AL,5h
Int 21h
Mov word PTR HOFFSET,BX
Mov word PTR LOFFSET,ES
Cargar Nuevo Segmento
Mov AX,SEG datas
Mov DS,AX
Instalar Nueva Interrupción
Lea DX, newint 5h
Mov Ah,25h
Mov Al,5
Int 21h
• A excepción de 2 los primeros 5 se usan con Interrupciones de Hardware
Interno.
• Otros vectores no reservados se usan para propósitos de software de
usuario.
• Los usuarios pueden cambiar los vectores de Interrupción reservados y
usar sus propias rutinas.
- Se salva el Registro de Banderas, offset y la dirección
delsegmento del programa Interrumpido en el Snack
Cuando Sucedeuna Interrupción
- Limpia el Trap y prende la Bandera de Interrupción
- Calcula la dirección del vector de Interrupción y carga
el CS e IP con la dirección de la rutina e interrupción.
Nota: Las direcciones donde se localiza el Vector de Interrupción nunca cambian.
INTERRUPCIONES POR HARDWARE
¿Cómo saber si un evento ha ocurrido? Una posibilidad es proporcionar un bit de
estado del teclado que indique si una tecla ha sido presionada.
Begin
Keyboard
Service
No Kb Action
Check
Keyboard
Status
Read in Key
Code Process
Key stoke
En el teclado, es el teclado quien llama a la Interrupción 9.
Cuando se necesita atención una interrupción es automáticamente generada
por la acción del teclado con el controlador de Instrucciones 8259 y la
transferencia a la rutina de servicio de Interrupción del teclado se efectúa.
Int 9h Hardware
Int 16h Generada por Software que accesa la rutina de teclado de BIOS.
• Dentro de esta rutina del teclado del BIOS, es la rutina de S.I.
normalmente accesada por Int 9H.
• Las Interrupciones de Orden de Int 9H se llaman
Interrupciones mascarables.
• IF (bandera de interrupción habilitada ) se prende.
• En general si una interrupción ocurre durante la ejecución de
una Instrucción espera hasta que la Instrucción se complete
antes de tomar efecto, a excepción de repeat, lock, mov y pop.
• Las Interrupciones no mascarables usan la line signal NMI en el
Intel 8088. Esas Interrupciones no pueden ser deshabilitadas y
prácticamente se usan cuando ocurren eventos críticos de
tiempo que requieren atención del procesador.
• Int 2: No Mascarable. USO: Señalar al procesador cuando
ocurrió un error de paridad.
UNIDAD 5. Ensambladores y macroensambladores
¿QUÉ ES UN PROGRAMA EN ENSAMBLADOR?
El proceso de convertir o traducir cada mnemónico de las Instrucciones de un
programa a su código de operación, se conoce como “Ensamblar un programa”
y al resultado se conoce como “Programa Objeto”.
Para Solucionar el Problema de ensamblar, se tiene un programa que permite
traducir los mnemónicos de las instrucciones a los patrones binarios o códigos
de Operación.
Fuente Ensamblador Objeto
CARACTERÍSTICAS DE LOS ENSAMBLADORES
Además de traducir mnemónicos
1. Asignar nombres a localidades de memoria y dispositivos de E/S.
2. Convertir datos y direcciones de Sistema Decimal, Octal y Hexadecimal a
Binario.
3. Efectuar algunas Operaciones(Sumas, restas, multiplicación, división,
etc) para generar datos y direcciones.
4. Indicar al “cargador” a partir de que localidad de memoria se deben
cargar los programas, las rutinas y datos.
5. Proporcionar información de la biblioteca de programas y otros al
programa de ensamble.
6. Determinar cuántos operandos requiere cada Instrucción y de qué tipo?
7. Proporcionar mensajes de error.
TIPOS DE ENSAMBLADORES
Existen dos demarcaciones, por su implantación o por la forma de ensamblar
un programa. Por su implantación, se clasifican a los diferentes tipos de
ensambladores:
CROSS ASSEMBLER. Ensamblador que corre en un computadora para
ensamblar programas para otra computadora. Generalmente la computadora
donde se corre el Cross Assembler ensambla los programas utilizaba un
microprocesador 8080 , 6800 o z-80.
ENSAMBLADOR PROPIO O RESIDENTE. Es un ensamblador que corre en la
computadora para la cual ensambla programas.
MACRO ENSAMBLADOR. Es un ensamblador que permite al programador
definir una secuencia o grupos de Instrucciones como Macros.
Por la forma de ensamblar un programa los ensambladores se clasifican como
ensamblador de un paso o ensamblador de 2 pasos.
Ensamblador de 1 paso. Es un ensamblador que lee y procesa el programa
fuente sólo una vez. Este ensamblador debe tener alguna forma de resolver
el problema que se presenta cuando una instrucción hace referencia a una
etiqueta que se encuentra definida mas adelante en el programa..
Ensamblador de 2 pasos: Ensamblador que lee y procesa el programa
fuente 2 veces. La primera vez el ensamblador identifica y le da un valor a las
etiquetas y a las Instrucciones. En el segundo paso, reemplaza el valor de las
etiquetas en aquellas instrucciones en las que hace referencia. La mayoría de
ensambladores de computadoras son de 2 pasos.
MACROENSAMBLADOR
FORMATO GENERAL DE UN PROGRAMA EN ENSAMBLADOR
[NOMBRE]بOPERACIONبOPERANDO[S]
132 Caracteres por Línea Máximo
CAD DB’............... ’,’$’
CONT DB 3
MOV AX,0
NOMBRE: Puede usar los siguientes caracteres
A-Z, 0-9, ?, . ,@,_,$
OPERACIÓN: Indica que “acción” la expresión debe realizar.
En el segmento de Datos una Operación define un Campo, area de Trabajo
o Constante.
En el Segmento de Código una Operación Indica una Acción.
OPERANDOS: Indica donde realizar la Acción. En el Segmento de Datos
Indica el contenido del Campo Definido.
En el Segmento de Código un Operando puede tener, uno, dos o ninguno.
RET
INC CX
ADD AX, 1249
PSEUDO-OPERACIONES[LISTADOS]
Las Pseudo-Operaciones sirven para controlar la forma en la que un programa
se ensambla y lista y actúan solo durante el ensamblado de un programa y no
generan código de máquina ejecutable.
PAGE. Poner número de líneas por páginas y un máximo de caracteres por
Línea.
PAGE 60,132
10,255 60,132 Default PAGE - 66,80
TITLE. Imprime título en el Inicio de cada página.
TITLE Texto
PSEUDO-OPERACIÓN[SEGMENTO]
SEGMENT: Define un segmento
Formato:
NOMBRE SEGMENT [OPCIONES]
.
.
NOMBRE ENDS
NOMBRE: Es único, el ENDS indica el fin del segmento y debe contener el
mismo nombre que SEGMENT.
3 Tipos de Opciones: Alineamiento, combinar o Clase
1. Alineamiento. Límite en el que el segmento empieza el requerimiento
típico es ‘PARA’ que alinea el segmento en un límite.
Dirección de Inicio “divisible por 16” default es PARA.
2. Tipo Combinado. Si se va ha combinar con Otros Segmentos cuando
se lleva a cabo el “Ligado”.
TIPOS: STACK,COMMON,PUBLIC, AT y MEMORY
PUBLIC, COMMON Y MEMORY se usan cuando los programas son ensamblados
separadamente.
3. Tipos de Clase. Encerrado en Apóstrofes y se usa para agrupar
segmentos relacionados cuando se ligan como sigue:
NOMBRE SEGMENT PARA STACK ‘STACK’
PSEUDO-OPERACIÓN PROC (PROCEDIMIENTOS)
El Segmento de Código contiene el Código de un programa ejecutable. Este
segmento puede también contener uno ó mas procedimientos definidos con
PROC.
SEGNAME SEGMENT PARA
PROCNAME PROC FAR
.
Call x
RET
PROCNAME ENDP
X proc near
Ret
X endp
SEGNAME ENDS
NOMBRE: Es único
FAR: Indica al Cargador del Programa DOS que este PROC es el punto de
Entrada para ejecutar el programa.
PROC. ENDP. Indica el fin de un procedimiento y contiene el mismo nombre que
RET. Termina el procedimiento, no hay mas instrucciones que ejecutar y
regresa el control a DOS.
PSEUDO-OPERACIÓN ASSUME
El procesador 8086 / 8088 usa SS, DS, y CS. Pero hay que Indicar al
ensamblador el propósito de cada segmento.
Assume está codificado en el segmento de Código como sigue:
ASSUME SS:STACKNAME, DS:DATASEGNAME, CS: CODESEGNAME, ES: NOTHING
PSEUDO-OPERACIÓN END
ENDS: Términa un segmento
ENDP : Termina Procedimiento
END: Términa el Programa Entero.
END[PROCNAME]
INICIALIZACION DE UN PROGRAMA
4 Requerimientos para inicializar un programa ensamblador:
1) Notificar al Ensamblador que segmentos asociar con que registros
de Segmento.
2) Almacenar en el Stack la dirección que está en el DS cuando el
programa inicia su ejecución.
3) Almacenar en el Stack una dirección Cero.
4) Cargar el DS con la dirección del Data Segment actual.
Práctica de laboratorio:
STACKSEG SEGMENT PARA STACK 'STACK'
DW 256 DUP(?)
STACKSEG ENDS
DATASEG SEGMENT PARA 'DATA'
CON DB 0
DATASEG ENDS
CODESEG SEGMENT PARA 'CODE'
PRINCIPAL PROC FAR
ASSUME CS:CODESEG,DS:DATASEG,SS:STACKSEG ; Paso 1
PUSH DS ; Paso 2
XOR AX,AX
PUSH AX ; Paso3
MOV AX,DATASEG
MOV DS,AX ; Paso 4
RET
PRINCIPAL ENDP
CODESEG ENDS
END PRINCIPAL
Nota: El anterior Programa no realiza tarea alguna pero cualquier programa
en ensamblador debe tener como mínimo esta estructura incluyendo los cuatro
pasos necesarios para iniciar un programa en Ensamblador.
Justifiquemos ahora cada Paso:
1) Notificar al Ensamblador que segmentos asociar con que
registros de Segmento.
2) PUSH DS: El cargador del Programa usa DS para establecer el
Punto de Inicio del PSP (Program Segment Prefix).
3) SUB AX,AX: Limpiamos el Acumulador, para que la siguiente
dirección en el Stack sea cero.
4) MOV AX,DATASEG
MOV DS, AX
El cargador del Programa ha inicializado bien el SS y CS, pero el DS
hay que guardarlo nuevamente.
RET: Usa esta dirección para regresar al DOS.
EL PSP
Area de 100H bytes creada por el Sistema Operativo para guardar datos
respectivos del programa y para que el programa se ejecute correctamente y termine
normalmente. Se encuentra Justo antes del Programa Ejecutable en Memoria.
PSEUDO_OPERACIÓN (Definición de Datos)
Formato General
[NOMBRE] Expresión
Opcional DB,DW,DD,DQ Y DT
• El campo de Expresión puede contener una Expresión constante tal
como:
VAR1 DB 25
ó una ? para indicar un campo no inicializado como:
FLAB DB ? ? = Campo sin Inicializar
Puede tener múltiples datos como:
FLD3 DB 11,12,13,14...
ENSAMBLADO Constantes en bytes Adyacentes.
▪ Una referencia a FLD3 es a la primera constante 11 y una referencia a
FLD3+1 es a la segunda constante y así sucesivamente MOV AL, FLD3 + 3=
▪ La expresión También permite la duplicación de constantes de la forma:
[NOMBRE] Dn REPEATCOUNT DUP[expresión]
Ejemplos:
DW 10 DUP(?)
DB 5 DUP(14)
DB 3 DUP(4 DUP(8))
CADENAS DE CARACTERES
CAD DB 1000 DUP(‘*’)
Deben estar contenidos dentro de ‘ ’ ó ” ”
DB pueden definir cadenas que excedan dos caracteres.
DB
línea. DB Carácter. Puede contener una cadena de longitud mayor que el fin del
DB Número. Puede contener una o más constantes.
FLD2 DB ‘PERSONAL COMPUTER’ ;Cadena
FLD3 DB 25 ;Variable cuyo valor es 25
DW. Define 2 BYTES DE LONGITUD
DW CARÁCTER. 2 Caracteres.
DW NUMERO. Puede contener una o más constantes de una
Palabra.
DD. Define Doble word. Define campos que son doble-word en longitud
(4 Bytes)
FLD3 DW 12345
FLD4 DW FLD3DB_FLD2DB
DQ. Define campos que son 4 words (8 Bytes)
CAD2 DB ‘HOLAMUNDO COMPUTACIONAL’,’$’
MOVSB
MOVSW
FLD2 DQ 03C32h
DT. Define campos de 10 Bytes de Longitud.
INSTRUCCIONES QUE PERMITEN OPERANDOS
INMEDIATO: Mover y Comparar: MOV,CMP
ARITMÉTICA: ADC,ADD,SBB,SUB.
CORRIMIENTOS: RCL,RCR,ROL,ROR,SHL,SAR,SHR
LÓGICOS: AND,OR,TEST,XOR
PSEUDO-OPERACIÓN EQU
Define un valor que puede usarse para sustituir en otras Instrucciones a
diferencia de los otros, no define un dato de campo.
TIMES EQU 10
Si TIMES aparece en otra PSEUDO-INSTRUCCIÓN el ensamblador sustituye
el valor de 10.
FIELDA DB TIMES DUP(?)
FIELDA DB 10 DUP(?)
COUNT EQU 05
MOV CX,COUNT
MOV CX,05
Realicemos ahora un Ejercicio para Imprimir el ASCII asociado al
33d
STACKSEG SEGMENT PARA STACK 'STACK'
DW 256 DUP(?)
STACKSEG ENDS
DATASEG SEGMENT PARA 'DATA'
VECTOR DB 1,2,-3,-4,5,6,-7,-8,9,10
CONT DW 10
DATASEG ENDS
CODESEG SEGMENT PARA 'CODE'
PRINCIPAL PROC FAR
ASSUME CS:CODESEG,DS:DATASEG,SS:STACKSEG
PUSH DS
XOR AX,AX
PUSH AX
MOV AX,DATASEG
MOV DS,AX
MOV AL,0
MOV SI,0
MOV CX,CONT
ETIQ:CMP VECTOR[SI],0
JL NEXT
ADD AL,VECTOR[SI]
NEXT:INC SI
LOOP ETIQ
MOV DL,AL
MOV AH,02
INT 21H
RET
PRINCIPAL ENDP
CODESEG ENDS
END PRINCIPAL
Realize la conversión a Hexadecimal y Decimal.
Realize un programa que imprima la tabla ASCII en tres columnas: decimal,
hexadecimal y ascii
PROCESAMIENTO DE PANTALLA
Desplegado a color soporta por ejemplo 16 KB de memoria e Indica
en la dirección B8000.
8K bytes son para los datos de la pantalla.
8K bytes para un atributo que especifica video reverso, parpadeo,
alta Intensidad y subrayado.
Atributo: Determina las características de cada carácter desplegado.
Proporciona las siguientes características.
7 6 5 4 3 2 1 0
ATRIBUTO BL R G B I R G B
Flash Background Intensity Foreground
RGB Representa rojo, verde y azul.
Atributos Comunes
No display 0000 0000
Normal bco/negro 0000 0111
Normal bco/negro flash 87h
Normal bco/Negro Intenso 0Fh
Negro Reverso en blanco 70h
Negro Reverso en blanco flash F0h
Se puede generar un atributo de pantalla a tráves de Int 10h, BL contiene el
atributo requerido y el AH contiene 06(scrollup), 07(scrolldown), 08 (Leer un
carácter con atributo), 09 (Escribir un carácter con atributo)
Int 10h
Función 02 AH-02. Posiciona el cursor BH = # de Pagina, DX = Ren/Col.
MOV AH,02
MOV BH,00
MOV DX,Ren/Col
Int 10h
AH = 03 Lee la posición actual del cursor.
MOV AH,03
MOV BH,00
Int 10h
AH = 09. Escribe un caracter con atributo en la posición actual
MOV AH,09
MOV AL,Char_to_display
MOV BH, page#
MOV BL, Atributo
MOV CX, repetición
INT 10h
AH=08 Lee un carácter con atributo en la posición actual del cursor.
MOV AH,08
MOV BH,00
Int 10h
Por ejemplo:
Cad DB ‘Hola’,’$’
MOV SI , 0
Mov CONT , 0
Etiq: Mov AH,09h
Mov AL, CAD[SI]
Mov BH, 00
MovBL, 87h
Mov CX,1
Int 10h
Inc SI
Dec CONT
JNZ Etiq
Nota: La función 9h de la interrupción 10h no realiza el posicionamiento
automático del cursor.
BIBLIOGRAFÍA.
1. Abel, P(2001). IBM PC Assembly Language and Programming (5ta. Edición). USA, Prentice Hall
2. Yale, N, P(2004). Introducción a los Sistemas de Cómputo (2ª. Edición). México: McGraw Hill.
3. Kip Irvine(2014). Assembly Language for x86 Processors (7th Edition) 7th Edition. Prentice-Hall
(Pearson Education)
4. aniel Kusswurm(2014). Modern X86 Assembly Language Programming: 32-bit, 64-bit, SSE, and
AVX. Apress.