Logo Studenta

Apunte-Lenguaje_Ensamblador-2018

¡Este material tiene más páginas!

Vista previa del material en texto

LENGUAJE ENSAMBLADOR LABORATORIO DE COMPUTADORAS 
Ing. Sánchez Rivero Página 1 
 
INTRODUCCIÓN 
 
El documento que está visualizando tiene la función primordial de introducirlo a la 
programación en lenguaje Ensamblador. Su contenido se enfoca completamente hacia las 
computadoras que operan con procesadores de la familia x86 de Intel y, considerando que el 
ensamblador basa su funcionamiento en los recursos internos del procesador, los ejemplos 
descriptos no son compatibles con ninguna otra arquitectura. 
 
 
GENERALIDADES 
 
Unidades de información 
 
Para que la PC pueda procesar la información es necesario que ésta se encuentre en celdas 
especiales llamadas registros. 
Los registros son conjuntos de 8 o 16 flip-flops (basculadores o biestables). 
Un flip-flop es un dispositivo capaz de almacenar dos niveles de voltaje, uno bajo, 
regularmente, alrededor, de 0.5 volts y otro alto comúnmente de 5 volts. El nivel bajo de 
energía en el flip-flop se interpreta como apagado o 0, y el nivel alto como prendido o 1. A 
estos estados se les conoce usualmente como bits, que son la unidad más pequeña de 
información en una computadora. 
A un grupo de 16 bits se le conoce como palabra, una palabra puede ser dividida en grupos 
de 8 bits llamados bytes, y a los grupos de 4 bits les llamamos nibbles. 
 
Sistemas numéricos 
 
El sistema numérico que utilizamos a diario es el sistema decimal, pero este sistema no es 
conveniente para las máquinas debido a que la información se maneja codificada en forma 
de bits prendidos o apagados; esta forma de codificación nos lleva a la necesidad de conocer 
el cálculo posicional que nos permita expresar un número en cualquier base que lo 
necesitemos. 
 
Proceso de creación de un programa 
 
Para la creación de un programa es necesario seguir cinco pasos: 
♦ Diseño del algoritmo. 
♦ Codificación del mismo. 
♦ Su traducción a lenguaje máquina. 
♦ La prueba del programa. 
♦ La depuración del programa. 
 
En la etapa de diseño se plantea el problema a resolver y se propone la mejor solución, 
creando diagramas esquemáticos utilizados para el mejor planteamiento de la solución. 
La codificación del programa consiste en escribir el programa en algún lenguaje de 
programación; en este caso específico en ensamblador, tomando como base la solución 
propuesta en el paso anterior. 
La traducción al lenguaje máquina es la creación del programa objeto, esto es, el programa 
escrito como una secuencia de ceros y unos que pueda ser interpretado por el procesador. 
La prueba del programa consiste en verificar que el programa funcione sin errores, o sea, 
que haga lo que tiene que hacer. 
La última etapa es la eliminación de las fallas detectadas en el programa durante la fase de 
prueba. La corrección de una falla normalmente requiere la repetición de los pasos 
comenzando desde el primero o el segundo. 
Para crear un programa en ensamblador existen dos opciones, la primera es utilizar algún 
software específico, por ejemplo el MASM (Macro Assembler, de Microsoft), y la segunda es 
utilizar el debugger del DOS; en esta primera sección utilizaremos este último ya que se 
encuentra en cualquier PC con el sistema operativo MS-DOS, lo cual lo pone al alcance de 
cualquier usuario que tenga acceso a una máquina con estas características. 
Debug solo puede crear archivos con extensión .COM, y por las características de este tipo 
de programas no pueden ser mayores de 64 Kb, además deben comenzar en el 
desplazamiento, offset, o dirección de memoria 0100H dentro del segmento específico. 
 
 
LENGUAJE ENSAMBLADOR LABORATORIO DE COMPUTADORAS 
Página 2 Ing. Sánchez Rivero 
 
Componentes Básicos de un Sistema MS-DOS 
 
 
Fig. 1: Componentes de un sistema DOS. 
 
Las operaciones de un sistema de computación incluyendo un IBM PC’s y compatibles están 
basadas en un concepto simple. Ellas guardan instrucciones y datos en la memoria y usan la 
CPU para repetir instrucciones y datos recibidos desde la memoria y ejecutan las 
instrucciones para manipular los datos (Computadoras basadas en la Arquitectura de Von 
Newmann), por lo tanto la CPU y la memoria son los dos componentes básicos de cualquier 
sistema de computación. La memoria se encuentra definida en dos tipos: Random Access 
Memory (RAM) la que permite la escritura y la lectura de cualquier localidad de memoria y la 
Read Only Memory (ROM), que es la que contiene valores que pueden ser leídos pero no 
alterados. La ROM es usada para almacenar pequeños primitivos programas para ejecutar 
instrucciones de entrada y salida y control de periféricos. La RAM es usada por el Sistema 
Operativo y los programas para los usuarios. El Sistema Operativo es un componente 
fundamental en un sistema. Este programa de computadoras se toma la tarea de cargar otros 
programas y ejecutarlos, provee acceso a los archivos del sistema, maneja la E/S, y hace 
interfaces interactivas con el usuario. El sistema operativo es el que provee al sistema su 
personalidad. MS-DOS, OS/2, UNIX son ejemplo de algunos Sistema Operativos para PC, 
similarmente CP/M es un Sistema Operativos para antiguos microprocesadores de INTEL de 
8 Bits como el 8080. El hardware de toda computadora, incluyendo las computadoras que 
usan el MS-DOS, está interconectado. 
La CPU, memoria, y periféricos de entrada (teclado, escáner, lápiz óptico, lector de código de 
barras, micrófono, mouse, etc.) y periféricos de salida (monitor, impresora, parlantes, etc.) 
están todos interconectados por una serie de cables llamados Buses y cada bus esta 
claramente definido. Un Bus es un hardware que especifica una señal y tiempo estándar que 
son seguidos y entendidos por la CPU y su circuito de soporte (incluyendo periféricos aún no 
instalados). Los buses a su vez se clasifican en Bus de Datos, Bus de Direcciones y Bus de 
Control. 
 
ARQUITECTURA INTERNA DEL INTEL 80x86 
 
Fue el primer microprocesador de 16 bits que INTEL fabricó a principios del año 1978. Los 
objetivos de la arquitectura de dicho procesador fueron los de ampliar la capacidad del INTEL 
80x80 de forma simétrica, añadiendo una potencia de proceso no disponible en los micros de 
8 bits. Algunas de estas características son: aritmética en 16 bits, multiplicación y división con 
o sin signo, manipulación de cadena de caracteres y operación sobre bits. También se han 
realizado mecanismos de software para la construcción de códigos reentrante y reubicable. 
Su estructura interna esta representada por la Fig. 2. 
Consta de 2 unidades claramente diferenciadas denominadas EU (Unidad de Ejecución) y 
BIU (Interfaces del Bus) 
La EU ejecuta las operaciones requeridas por las instrucciones sobre una UAL de 16 bits. No 
tiene conexión con el exterior y solamente se comunica con la BIU que es la parte que realiza 
todas las operaciones en el bus solicitadas por la EU. Un mecanismo, tal vez único dentro de 
los microprocesadores aunque muy empleado dentro de los mínimos y grandes 
computadores, es el denominado de búsqueda anticipada de instrucciones (prefetch). En el 
INTEL 8086 existe una estructura FIFO en RAM de 6 octetos de capacidad que es llenada 
por la BIU con los contenidos de las instrucciones siguientes a la que la EU está ejecutando 
en ese momento. 
LENGUAJE ENSAMBLADOR LABORATORIO DE COMPUTADORAS 
Ing. Sánchez RiveroPágina 3 
 
 
Fig. 2: Las unidades EU y BIU 
 
El 8086 representa la arquitectura base para todos los microprocesadores de 16 bits de Intel: 
8088, 8086, 80188, 80186 y 80286. Aunque han aparecido nuevas características a medida 
que estos microprocesadores han ido evolucionando; todos los procesadores Intel, usados 
en la actualidad en los PC’s y compatibles son miembros de la familia 8086. El conjunto de 
instrucciones, registros y otras características son similares, a excepción de algunos detalles. 
Toda la familia 80x86 en adelante posee dos características, en común: 
 
a) Arquitectura Segmentada: esto significa que la memoria es divida en segmentos con 
un tamaño máximo de 64k (información importante para el direccionamiento de la 
memoria en la futura programación segmentada en el lenguaje ensamblador). 
b) Compatibilidad: las instrucciones y registros de las anteriores versiones son 
soportados por las nuevas versiones, y estas versiones son soportadas por versiones 
anteriores. 
 
La familia de microprocesadores 80x86 consta de los siguientes microprocesadores: 
 
♦ El 8088 es un microprocesador de 16 bits, usado en las primeras PC´S (XT 
compatibles). Soporta solamente el modo real. Es capaz de direccionar un megabyte 
de memoria y posee un bus de datos de 8 bits. 
♦ El 8086 es Similar al 8088, con la excepción de que el bus de datos es de 16 bits. 
♦ El 80188 es similar al 8088, pero con un conjunto de instrucciones extendido y ciertas 
mejoras en la velocidad de ejecución. Se incorporan dentro del microprocesador 
algunos chips que anteriormente eran externos, consiguiéndose unas mejoras en el 
rendimiento del mismo. 
♦ El 80186 es igual al 80188 pero con un bus de datos de 16 bits. 
♦ El 80286 Incluye un conjunto de instrucciones extendidos del 80186, pero además 
soporta memoria virtual, modo protegido y multitarea. 
♦ El 80386 soporta procesamientos de 16 y 32 bits. El 80386 es capaz de manejar 
memoria real y protegida, memoria virtual y multitarea. Es más rápido que el 80286 y 
contiene un conjunto de instrucciones ampliables. 
♦ El 80386SX es similar al 80386 por un bus de datos de solo 16 bits. 
♦ El 80486 incorpora un caché interno de 8 kb y ciertas mejoras de velocidad con 
respecto al 80386. Incluye un coprocesador matemático dentro del mismo chip. 
♦ El 80486SX es similar a los 80486 con la diferencia que no posee coprocesador 
matemático. 
♦ El 80486DX2 es similar al 80486, pero con la diferencia de que internamente, trabaja 
al doble de la frecuencia externa del reloj. 
 
 
 
 
 
LENGUAJE ENSAMBLADOR LABORATORIO DE COMPUTADORAS 
Página 4 Ing. Sánchez Rivero 
 
Modelo Bus de Datos Coprocesador matemático 
80386DX 32 Si 
80386SL 16 No 
80386SX 16 No 
80486SX 32 No 
80486DX 32 Si 
 
El 80x86 tiene dos procesadores en el mismo chip. Estos son La Unidad de Ejecución y La 
Unidad de Interface con los Buses, como ya se mencionó antes. Cada uno de ellos contiene 
su propio registro, su propia sección aritmética, sus propias unidades de control y trabajan de 
manera asincrónica el uno con el otro para proveer la potencia total de cómputo. La Unidad 
de Interface de Bus se encarga de buscar las instrucciones para adelantar su ejecución y 
proporciona facilidades en el manejo de las direcciones. Luego, la Unidad de Interface se 
responsabiliza del control de la adaptación con los elementos externos del CPU central. 
Dicha Unidad de Interface proporciona una dirección de 20 Bits o un dato de 16 para la 
unidad de memoria o para la unidad de E/S en la estructura externa del computador. 
 
Terminales del microprocesador 8086 
 
El microprocesador 8086 puede trabajar en dos modos diferentes: el modo mínimo y el modo 
máximo. En el modo máximo el microprocesador puede trabajar en forma conjunta con un 
microprocesador de datos numérico 8087 y algunos otros circuitos periféricos. En el modo 
mínimo el microprocesador trabaja de forma más autónoma al no depender de circuitos 
auxiliares, pero esto a su vez le resta flexibilidad. 
En cualquiera de los dos modos, las terminales del microprocesador se pueden agrupar de la 
siguiente forma: 
• Alimentación 
• Reloj 
• Control y estado 
• Direcciones 
• Datos 
El 8086 cuenta con tres terminales de alimentación: tierra (GND) en las terminales 1 y 20 y 
Vcc = 5V en la terminal 40. 
En la terminal 19 se conecta la señal de reloj, la cual debe provenir de un generador de reloj 
externo al microprocesador. 
El 8086 cuenta con 20 líneas de direcciones (al igual que el 8088). Estas líneas son llamadas 
A0 a A19 y proporcionan un rango de direccionamiento de 1MB. 
Para los datos, el 8086 comparte las 16 líneas más bajas de sus líneas de direcciones, las 
cuales son llamadas AD0 a AD15. Esto se logra gracias a un canal de datos y direcciones 
multiplexado. 
En cuanto a las señales de control y estado tenemos las siguientes: 
La terminal MX/MN controla el cambio de modo del microprocesador. 
Las señales S0 a S7 son señales de estado, éstas indican diferentes situaciones acerca del 
estado del microprocesador. 
La señal RD en la terminal 32 indica una operación de lectura. 
En la terminal 22 se encuentra la señal READY. Esta señal es utilizada por los diferentes 
dispositivos de E/S para indicarle al microprocesador si se encuentran listos para una 
transferencia. 
La señal RESET en la terminal 21 es utilizada para reinicializar el microprocesador. 
La señal NMI en la terminal 17 es una señal de interrupción no enmascarable, lo cual 
significa que no puede ser manipulada por medio de software. 
LENGUAJE ENSAMBLADOR LABORATORIO DE COMPUTADORAS 
Ing. Sánchez Rivero Página 5 
La señal INTR en la terminal 18 es también una señal de interrupción, la diferencia radica en 
que esta señal si puede ser controlada por software. Las interrupciones se estudian más 
adelante. 
La terminal TEST se utiliza para sincronizar al 8086 con otros microprocesadores en una 
configuración en paralelo. 
Las terminales RQ/GT y LOCK se utilizan para controlar el trabajo en paralelo de dos o más 
microprocesadores. 
La señal WR es utilizada por el microprocesador cuando éste requiere realizar alguna 
operación de escritura con la memoria o los dispositivos de E/S. 
Las señales HOLD y HLDA son utilizadas para controlar el acceso al bus del sistema. 
 
Unidad aritmético-lógica 
 
Conocida también como ALU, este componente del microprocesador es el que realmente 
realiza las operaciones aritméticas (suma, resta, multiplicación y división) y lógicas (and, or, 
xor, etc.) que se obtienen como instrucciones de los programas. 
 
Buses internos (datos y direcciones) 
 
Los buses internos son un conjunto de líneas paralelas (conductores) que interconectan las 
diferentes partes del microprocesador. 
Existen dos tipos principales: el bus de datos y el bus de direcciones. El bus de datos es el 
encargado de transportar los datos entre las distintas partes del microprocesador; por otro 
lado, el bus de direcciones se encarga de transportar las direcciones para que los datos 
puedan ser introducidos o extraídos de la memoria o dispositivos de entrada y salida. 
 
Cola de instrucciones 
 
La cola de instrucciones es una pila de tipo FIFO (primero en entrar, primero en salir) donde 
las instrucciones son almacenadas antes de que la unidad de ejecución las ejecute. 
 
 
TIPOS DE PROGRAMAS EJECUTABLES 
 
 
ESTRUCTURA DEL PROGRAMA CON EXTENSIÓN .COM 
 
Un programa con extensión .COM está almacenado en un archivo que contiene una copia fiel 
del código aser ejecutado. Ya que no contienen información para la reasignación de 
localidades, son más compactos y son cargados más rápidamente que sus equivalentes 
EXE. 
El MS-DOS no tiene manera de saber si un archivo con extensión .COM es un programa 
ejecutable válido. Este simplemente lo carga en memoria y le transfiere el control. Debido al 
hecho de que los programas COM son siempre cargados inmediatamente después del PSP y 
no contienen encabezado que especifique el punto de entrada al mismo, siempre debe 
comenzar en la dirección 0100h. Esta dirección deberá contener la primera instrucción 
ejecutable. La longitud máxima de un programa COM es de 65536 bytes, menos la longitud 
de PSP (256 bytes) y la longitud de la pila (mínimo 2 bytes). 
Cuando el sistema operativo transfiere el control a un programa COM, todos los registros de 
segmento apuntan al PSP. El registro apuntador de pila (SP) contiene el valor en la memoria 
de OFFFEh si la memoria lo permite. En otro caso adopta el mínimo valor posible menos dos 
bytes (el MS-DOS introduce un cero en la pila antes de transferir el control al programa). Aún 
cuando la longitud de un programa COM no puede exceder de los 64 kb; las versiones 
actuales del MS-DOS reservan toda la memoria disponible. Si un programa .COM debe 
ejecutar otro proceso, es necesario que el mismo libere la memoria no usada de tal manera 
que pueda ser empleada por otra aplicación. Cuando un programa .COM termina; puede 
retornar al control del sistema operativo por varios medios. El método preferido es el uso de 
la función 4Ch de la Int 21h, la cual permite que el programa devuelva un código de retorno 
al proceso que invocó. Sin embargo, si el programa está ejecutándose bajo la versión 1.00 
del MS.DOS, el control debe ser retornado mediante el uso de la Int 20h. Un programa .COM 
puede ser ensamblado a partir de varios módulos objeto, con la condición de todos ellos 
empleen los mismos nombres y clases de segmentos y asegurando que el módulo inicial, con 
el punto de entrada en 0100h sea enlazado primero. Adicionalmente todos los 
procedimientos y funciones deben tener el atributo NEAR, ya que todo el código ejecutable 
estará dentro del mismo segmento. 
LENGUAJE ENSAMBLADOR LABORATORIO DE COMPUTADORAS 
Página 6 Ing. Sánchez Rivero 
Al enlazar un programa .COM, el enlazador mostrará el siguiente mensaje; "Warning: no 
stack segment". Este mensaje puede ser ignorado, ya que el mismo se debe a que se ha 
instruido al enlazador para que genere un programa con extensión .EXE donde el segmento 
de pila debe ser indicado de manera explícita, y no así en los .COM donde ésta es asumida 
por defecto. En la zona desde 000Ah hasta 0015h dentro del PSP se encuentran las 
direcciones de las rutinas manejadoras de los eventos Ctrl-C y Error crítico. Si el programa 
de aplicación altera estos valores para sus propios propósitos, el MS-DOS los restaura al 
finalizar la ejecución del mismo. 
 
ESTRUCTURA DEL PREFIJO DE PROGRAMA (PSP) 
 
0000h INT 20 
0002h Segmento final del bloque de asignación 
0004h Reservado 
0005h Invocación FAR a la función despachadora del MS-DOS 
000Ah Vector de interrupción de terminación (Int22h) 
000Eh Vector de interrupción Ctrl-C (Int23h) 
0012h Vector de interrupción de error crítico (Int24h) 
0016h Reservado 
002Ch Segmento de bloque de variables de ambiente 
002Eh 
005Ch Bloque de control de archivo por defecto (#1) 
006Ch Bloque de control de archivo por defecto (#2) 
0080h Líneas de comandos y área de transferencia de disco 
00FFh Final del PSP 
 
La palabra de datos en desplazamiento 002Ch contiene la dirección del segmento de bloque 
de variables de ambiente (Environment block), el cual contiene una serie de cadenas ASCII. 
Este bloque es heredado del proceso que causó la ejecución del programa de aplicación. 
Entre la información que contiene tenemos el paso usado por el COMAND.COM para 
encontrar el archivo ejecutable, el lugar del disco donde se encuentra el propio 
COMAND.COM y el formato del prompt empleado por éste. La cola de comandos, la cual 
está constituida por los caracteres restantes en la línea de comandos, después del nombre 
del programa, es copiada a partir de la localidad 0081h en el PSP. La longitud de la cola, sin 
incluir el carácter de retorno al final, está ubicada en la posición 0080h. Los parámetros 
relacionados con redireccionamiento o piping no aparecen en esta posición de la línea de 
comandos, ya que estos procesos son transparentes a los programas de aplicación. Para 
proporcionar compatibilidad con CP/M, el MS-DOS coloca los dos primeros comandos en la 
cola, dentro de los bloques de control del archivo (FCB) por defecto en las direcciones 
PSP:005Ch y PSP:006Ch asumiendo que pueden ser nombres de archivos. Sin embargo, si 
alguno de estos comandos son nombres de archivos que incluyen especificaciones del paso, 
la información colocada en los FCB no será de utilidad ya que estas estructuras no soportan 
el manejo de estructuras jerárquicas de archivos y subdirectorios. Los FCB son de muy 
escaso uso en los programas de aplicación modernos. El área de 128 bytes ubicado entre las 
direcciones 0080h y 00FFh en el PSP puede también servir como área de transferencia de 
disco por defecto (DTA), la cual es establecida por el MS-DOS antes de transferir el control al 
programa de aplicación. A menos que el programa establezca de manera explícita otra DTA, 
este será usado como buffer de datos para cualquier intercambio con disco que este efectué. 
Los programas de aplicación no deben alterar la información contenida en el PSP a partir de 
la dirección 005Ch. 
 
ESTRUCTURA DE UN PROGRAMA DE EXTENSIÓN .EXE 
 
Los programas .EXE son ilimitados en tamaño (el límite lo dictamina la memoria disponible 
del equipo). Además, los programas .EXE pueden colocar el código, los datos y la pila en 
distintos segmentos de la memoria. La oportunidad de colocar las diversas partes de un 
LENGUAJE ENSAMBLADOR LABORATORIO DE COMPUTADORAS 
Ing. Sánchez Rivero Página 7 
programa en fragmentos diferentes de memoria y la de establecer segmentos de memoria 
con solamente códigos que pudieran ser compartidos por varias tareas, es muy significativo 
para ambientes multitareas tales como el Microsoft Windows. El cargador del MS-DOS sitúa 
al programa .EXE, inmediatamente después del PSP, aunque el orden de los segmentos que 
lo constituyen pueden variar. El archivo .EXE contiene un encabezado, bloque de 
información de control, con un formato característico. El tamaño de dicho encabezado puede 
variar dependiendo del número de instrucciones que deben ser localizadas al momento de 
carga del programa, pero siempre será múltiplo de 512. Antes de que el MS-DOS transfiera 
el control al programa, se calculan los valores iniciales del registro del segmento de código 
(CS) y el apuntador de instrucciones (IP) basados en la información sobre el punto de 
entrada al programa, contenida en el encabezado del archivo .EXE. Esta información es 
generada a partir de la instrucción END en el módulo principal del programa fuente. Los 
registros de segmentos de datos y segmentos extras son inicializados de manera que 
apunten al PSP de modo que el programa pueda tener acceso a la información contenida. 
 
IMAGEN DE MEMORIA DE UN PROGRAMA .EXE TÍPICO 
 
SS:SP Segmento de Pila 
SS:0000h Datos del Programa 
CS:0000h Código del Programa 
DS:0000h Prefijo del segmento del Programa 
ES: 0000h 
 
FORMATO DE UN ARCHIVO DE CARGA EXE 
 
0000h Primera partedel identificador del archivo EXE (4Dh) 
0001h Segunda parte del identificador de archivo EXE (5Ah) 
0002h Longitud del archivo MOD 512 
0004h Tamaño del archivo, en páginas de 512 bytes, incluyendo encabezado 
0008h Número de ítems en la tabla de relocalizaciones 
000Ah Tamaño del encabezado en párrafos (16 bytes) 
000Ch Número mínimo de párrafos requeridos para el programa 
000Eh Máximo número de párrafos deseables para el programa 
0010h Desplazamiento del segmento del módulo de pila 
0012h Suma de chequeo 
0016h Contenido del apuntador de instrucciones al comenzar el programa 
0018h Desplazamiento del segmento del módulo de código 
001Ah Desplazamiento del primer ítem en la tabla de relocalizaciones 
001Bh Número de overplay (0 para la parte residente del programa) 
 Tabla de relocalizaciones 
 Espacio reservado (longitud variable) 
 Segmento de programas y datos 
 Segmento de pila 
 
El contenido inicial del segmento de pila y del apuntador de pila proviene también del 
encabezado del archivo. Esta información es derivada de la declaración del segmento de pila 
efectuada mediante la sentencia STACK. El espacio reservado para la pila puede ser 
inicializado o no dependiendo de la manera como este haya sido declarado. Puede ser 
conveniente en muchos casos inicializar el segmento de pila con un patrón de caracteres 
predeterminados que permitan su posterior inspección. Cuando el programa .EXE finaliza su 
ejecución debe retornar el control al sistema operativo mediante la función 4Ch de la Int 21h. 
LENGUAJE ENSAMBLADOR LABORATORIO DE COMPUTADORAS 
Página 8 Ing. Sánchez Rivero 
Existen otros métodos, pero no ofrecen ninguna otra ventaja y son considerablemente menos 
convenientes "Generalmente requieren que el registro CS apunte al segmento de PSP". 
Un programa .EXE puede ser construido a partir de varios módulos independientes. Cada 
módulo puede tener nombres diferentes para el segmento de código y los procedimientos 
pueden llevar el atributo NEAR o FAR, dependiendo del tamaño del programa ejecutable. El 
programador debe asegurarse de que los módulos a ser enlazados solo tengan una 
declaración de segmento de pila y que haya sido definido un único punto de entrada (por 
medio de la directiva END). La salida del enlazador es un archivo con extensión .EXE el cual 
puede ser ejecutado inmediatamente. 
 
REGISTROS DE LA CPU 
 
Los registros del procesador se emplean para controlar instrucciones en ejecución, manejar 
direccionamiento de memoria y proporcionar capacidad aritmética. Los registros son 
espacios físicos dentro del microprocesador con capacidad de 4 bits hasta 64 bits 
dependiendo del microprocesador que se emplee. Los registros son direccionables por medio 
de una viñeta, que es una dirección de memoria. Los bits, por conveniencia, se numeran de 
derecha a izquierda (15,14,13…. 3,2,1,0), los registros están divididos en seis grupos los 
cuales tienen un fin especifico. Los registros se dividen en: 
 
• Registros de segmento. 
• Registro apuntador de instrucciones. 
• Registros apuntadores. 
• Registros de propósitos generales. 
• Registros índices. 
• Registro de banderas. 
 
REGISTROS DE SEGMENTO 
 
Un registro de segmento se utiliza para alinear en un limite de párrafo o dicho de otra forma 
codifica la dirección de inicio de cada segmento y su dirección en un registro de segmento 
supone cuatro bits 0 a su derecha. 
Un registro de segmento tiene 16 bits de longitud y facilita un área de memoria para 
direccionamientos conocidos como el segmento actual. Los registros de segmento son: 
 
• Registro CS 
• Registro DS 
• Registro SS 
• Registro ES 
• Registro FS y GS 
 
Registro CS 
El DOS almacena la dirección inicial del segmento de código de un programa en el registro 
CS. Esta dirección de segmento, más un valor de desplazamiento en el registro apuntador de 
instrucciones (IP), indica la dirección de una instrucción que es buscada para su ejecución. 
Para propósitos de programación normal, no se necesita referenciar el registro CS. 
 
Registro DS 
La dirección inicial de un segmento de datos de un programa es almacenada en el registro 
DS. En términos sencillos, esta dirección más un valor de desplazamiento en una instrucción, 
genera una referencia a la localidad de un byte especifico en el segmento de datos. 
 
Registro SS 
El registro SS permite la colocación en memoria de una pila, para almacenamiento temporal 
de direcciones y datos. El DOS almacena la dirección de inicio del segmento de pila de un 
programa en el registro SS. Esta dirección de segmento, más un valor de desplazamiento en 
el registro apuntador de la pila (SP), indica la palabra actual en la pila que está siendo 
direccionada. Para propósitos de programación normal, no se necesita referenciar el registro 
SS. 
 
Registro ES 
Algunas operaciones con cadenas de caracteres (datos de caracteres) utilizan el registro de 
segmento extra para manejar el direccionamiento de memoria. En este contexto, el registro 
LENGUAJE ENSAMBLADOR LABORATORIO DE COMPUTADORAS 
Ing. Sánchez Rivero Página 9 
ES esta asociado con el registro DI (índice). Un programa que requiere el uso del registro ES 
puede inicializarlo con una dirección apropiada. 
 
Registros FS y GS 
Son registros extra de segmento en los procesadores 80386 y posteriores a estos 
procesadores. 
 
Registro Apuntador de instrucciones (IP) 
El registro apuntador de instrucciones (IP) de 16 bits contiene el desplazamiento de dirección 
de la siguiente instrucción que se ejecuta. 
El registro IP esta asociado con el registro CS en el sentido de que el IP indica la instrucción 
actual dentro del segmento de código que se está ejecutando actualmente. 
En el ejemplo siguiente, el registro CS contiene 25A4[0]H y el IP contiene 412H. Para 
encontrar la siguiente instrucción que será ejecutada el procesador combina las direcciones 
en el CS y el IP así: 
 
Segmento de dirección en el registro CS: 25A40H 
Desplazamiento de dirección en el registro IP: + 412H 
Dirección de la siguiente instrucción: 25E52H 
 
 
Registros apuntadores 
 
Los registros apuntadores están asociados con el registro SS y permiten al procesador 
accesar datos en el segmento de pila; los registros apuntadores son dos: 
 
• El registro SP 
• El registro BP 
 
Registro SP 
El apuntador de pila SP de 16 bits está asociado con el registro SS y proporciona un valor de 
desplazamiento que se refiere a la palabra actual que está siendo procesada en la pila. 
El ejemplo siguiente el registro SS contiene la dirección de segmento 27B3[0]H y el SP el 
desplazamiento 312H Para encontrar la palabra actual que esta siendo procesada en la pila 
el microprocesador combina las direcciones en el SS y el SP: 
 
Dirección de segmento en el registro SS: 27B30H 
Desplazamiento en el registro SP: + 312H 
Dirección en la Pila: 27E42H 
 
 
 ……. 
27B3[0]H 312H 
Dirección del segmento SS Desplazamiento del SP 
 
Registro BP 
El registro BP de 16 bits facilita la referencia de parámetros, los cuales son datos y 
direcciones transmitidos vía la pila. 
 
Registros de propósitos generales. 
 
Los registros de propósitos generales AX, BX, CX y DX son los caballos de batalla o las 
herramientas del sistema. Son únicos en el sentido de que se puede direccionarlos como una 
palabra o como una parte de un byte. Elbyte de la izquierda es la parte "alta", y el byte de la 
derecha es la parte "baja". Por ejemplo, el registro CX consta de una parte CH (alta) y una 
parte CL (baja), y usted puede referirse a cualquier parte por su nombre. Las instrucciones 
siguientes mueven ceros a los registros CX, CH y CL respectivamente: 
 
Mov CX, 00 
Mov CH, 00 
Mov CL, 00 
 
Los procesadores 80386 y posteriores permiten el uso de todos estos registros de propósito 
general, más las versiones de 32 bits: EAX, EBX, ECX y EDX. 
LENGUAJE ENSAMBLADOR LABORATORIO DE COMPUTADORAS 
Página 10 Ing. Sánchez Rivero 
Registros AX 
El registro AX, el acumulador principal, es utilizado para operaciones que implican 
entrada/salida y la mayor parte de la aritmética. Por ejemplo, las instrucciones para 
multiplicar, dividir y traducir suponen el uso del AX. También, algunas operaciones generan 
código más eficientes si se refiere al AX en lugar de los otros registros. 
 
Registro BX 
El BX es conocido como el registro base ya que es el único registro de propósito general que 
puede ser índice para el direccionamiento indexado. También es común emplear al BX para 
cálculos. 
 
Registro CX 
El CX es conocido como el registro contador. Puede contener un valor para controlar el 
número de veces que un ciclo se repite o un valor para corrimiento de bits, hacia la derecha o 
hacia la izquierda. El CX también es usado para muchos cálculos. 
 
Registro DX 
El DX es conocido como el registro de datos. Algunas operaciones de entrada/salida 
requieren su uso, y las operaciones de multiplicación y división con cifras grandes suponen al 
DX y al AX trabajando juntos. 
Puede usar los registros de propósito general para suma y resta de cifras de 8, 16 o 32 bits. 
 
Registros índices 
 
Los registros SI y DI están disponibles para direccionamientos indexados y para sumas y 
restas. 
 
Registro SI 
El registro índice fuente SI de 16 bits es requerido por algunas operaciones con cadenas (de 
caracteres). En este contexto, el SI está asociado con el registro DS. Los procesadores 
80386 y posteriores permiten el uso de un registro ampliado a 32 bits: el ESI. 
 
Registro DI 
El registro índice destino DI también es requerido por algunas operaciones con cadenas de 
caracteres. En este contexto, el DI está asociado con el registro ES. Los procesadores 80386 
y posteriores permiten el uso de un registro ampliado a 32 bits: el EDI. 
 
Registro de banderas 
Los registros de banderas sirven parar indicar el estado actual de la máquina y el resultado 
del procesamiento. Cuando algunas instrucciones piden comparaciones o cálculos 
aritméticos cambian el estado de las banderas. 
Las banderas están en el registro de banderas en las siguientes posiciones: 
 
 bits 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 
 O D I T S Z A P C 
 
Banderas 
 
Las banderas más comunes son las siguientes: 
 
OF (Overflow flag, desbordamiento) 
 
Indica el desbordamiento de un bit de orden alto (más a la izquierda) después de una 
operación aritmética. 
 
DF (Direction flag, Dirección) 
 
Designa la dirección hacia la izquierda o hacia la derecha para mover o comparar cadenas 
de caracteres. 
 
IF (Interruption flag, Interrupción) 
 
Indica que una interrupción externa, como la entrada desde el teclado sea procesada o 
ignorada. 
LENGUAJE ENSAMBLADOR LABORATORIO DE COMPUTADORAS 
Ing. Sánchez Rivero Página 11 
 
TF (Trap flag, Trampa) 
 
Examina el efecto de una instrucción sobre los registros y la memoria. Los programas 
depuradores como DEBUG, activan esta bandera de manera que pueda avanzar en la 
ejecución de una sola interrupción a un tiempo. 
 
SF (Sign flag, Signo) 
 
Contiene el signo resultante de una operación aritmética (0 = positivo y 1 = negativo). 
 
ZF (Zero flag, Cero) 
 
Indica el resultado de una operación aritmética o de comparación (0 = resultado diferente de 
cero y 1 = resultado igual a cero) 
 
AF (Auxiliary carry flag, Acarreo auxiliar) 
 
Contiene un acarreo externo del bit 3 en un dato de 8 bits, para aritmética especializada 
 
PF (Parity flag, Paridad) 
 
Indica paridad par o impar de una operación en datos de ocho bits de bajo orden (más a la 
derecha) 
 
CF (Carry flag, Acarreo) 
 
Contiene el acarreo de orden más alto (más a la izquierda) después de una operación 
aritmética; también lleva el contenido del ultimo bit en una operación de corrimiento o 
rotación. 
 
CUADRO COMPARATIVO 
 
TIPOS DE REGISTROS FUNCIÓN 
Registros de Segmento Un registro de segmento tiene 16 bits de longitud y facilita un área de 
memoria para el direccionamiento conocida como el segmento actual 
Registros de Apuntador de 
Instrucciones 
Este registro esta compuesto por 16 bits y contiene el desplazamiento de 
la siguiente instrucción que se va a ejecutar. Los procesadores 80386 y 
posteriores tiene un IP ampliado de 32 bits llamado EIP. 
Registros Apuntadores Permiten al sistema accesar datos al segmento de la pila. Los 
procesadores 80386 tiene un apuntador de pila de 32 bits llamado ESP. 
El sistema maneja de manera automática estos registros. 
Registros de Propósito 
General 
Son los caballos de batalla del sistema y pueden ser direccionados como 
una palabra o como una parte de un bytes. Los procesadores 80386 y 
posteriores permiten el uso de todos los registros de propósitos general 
más sus versiones ampliadas de 32 bits llamados EAX, EBX, ECX y EDX. 
Registros Índices Sirven para el direccionamiento de indexado y para las operaciones de 
sumas y restas. 
Registros de Banderas Sirven para indicar el estado actual de la máquina y el resultado del 
procesamiento. De los 16 bits de registro de bandera 9 son comunes a 
toda la familia de los procesadores 8086. 
 
Ejemplo de Representación de los Registros 
 
Después de haber conceptualizado e interpretado los diferente tipos de registro nes 
necesario plantear un ejemplo no muy practico pero si muy significativo, en el cual se 
representa la forma estructurada de un programa en el lenguaje ensamblador y como se 
utilizan los diferentes términos investigados, se verá que en el programa o en una pequeña 
porción de él se muestra como se colocan dentro, los diferentes tipos registros. 
 
TITLE P17HANRD(EXE) Lectura secuencial de registros. 
.MODEL SMALL 
.STACK 64 
LENGUAJE ENSAMBLADOR LABORATORIO DE COMPUTADORAS 
Página 12 Ing. Sánchez Rivero 
/------------------------------------------------------------------------------------------ 
.DATA 
ENDCDE DB 00 ;FIN DEL INDICADOR DE PROCESO. 
HANDLE DW ? 
IOAREA DB 32 DUP(´ ´) 
OPENMSG DB ´*** Open error ***´ 0DH, 0AH 
PATHNAM DB ´D:\NAMEFILE.SRT´, 0 
READMSD DB ´*** Read error ***´ 0DH, 0AH 
ROW DB 00 
/--------------------------------------------------------------------------------------------- 
.CODE 
BEGIN PROC FAR 
MOV AX,@data ;inicializa 
MOV DS,AX ;registro de 
MOV ES,AX ;segmento 
MOV AX,0600H 
 
Es posible visualizar los valores de los registros internos de la UCP utilizando el programa 
Debug. 
 
LENGUAJE ENSAMBLADOR LABORATORIO DE COMPUTADORAS 
Ing. Sánchez RiveroPágina 13 
 
MODOS DE DIRECCIONAMIENTO 
 
Se les llama modos de direccionamiento a las distintas formas de combinar los operadores 
según el acceso que se hace a memoria. 
Dicho de otra manera, un modo de direccionamiento será una forma de parámetro para las 
instrucciones. Una instrucción que lleve un parámetro, por lo tanto, usará un modo de 
direccionamiento, que dependerá de cómo direccionará (accesará) al parámetro; una 
instrucción de dos parámetros, combinará dos modos de direccionamiento. 
 
Estos pueden clasificarse en 5 grupos: 
 
1. Direccionamientos accesando dato inmediato y registro de datos (modos 
inmediato y de registro) 
2. Direccionamiento accesando datos en memoria (modo memoria) 
3. Direccionamiento accesando puertos E/S. (modo E/S) 
4. Direccionamiento relativo 
5. Direccionamiento implícito. 
 
1. DIRECCIONAMIENTO ACCESANDO DATO Y REGISTRO INMEDIATO 
 
1.1 Direccionamiento de registro. 
 
Especifica el operando fuente y el operando destino. Los registros deben ser del mismo tamaño. 
Ej. MOV DX, CX 
 MOV CL, DL. 
 
1.2 Direccionamiento inmediato. 
 
Un dato de 8 o 16 bits se especifica como parte de la instrucción. p.ej. MOV CL, 03H. Aquí el 
operando fuente está en modo inmediato y el destino en modo registro. 
 
2. DIRECCIONAMIENTO ACCESANDO DATOS EN MEMORIA 
 
2.1 Direccionamiento directo. 
 
La dirección efectiva (EA) de 16 bits se toma directamente del campo de desplazamiento de la 
instrucción. El desplazamiento se coloca en la localidad siguiente al código de operación. Esta 
EA o desplazamiento es la distancia de la localidad de memoria al valor actual en el segmento 
de datos (DS) en el cual el dato está colocado. 
Ej. MOV CX, START. 
START puede definirse como una localidad de memoria usando las pseudoinstrucciones DB o 
DW. 
 
2.2 Direccionamiento de registro indirecto. 
 
La dirección efectiva EA está especificada en un registro apuntador o un registro índice. El 
apuntador puede ser el registro base BX o el apuntador base BP; el registro índice puede ser el 
Índice Fuente (SI) o el Índice Destino (DI). 
 
Ej. MOV (DI),BX 
 
2.3 Direccionamiento base (Relativo a la base). 
 
La EA se obtiene sumando un desplazamiento (8 bits con signo o 16 bits sin signo) a los 
contenidos de BX o BP. Los segmentos usados son DS y SS. Cuando la memoria es accesada, 
la dirección física de 20 bits es calculada de BX y DS, por otra parte, cuando la pila es 
accesada, la dirección es calculada de BP y SS. 
Ej. MOV AL, START (BX), el operando fuente está en modo base, y la EA se obtiene sumando 
los valores de START y BX. 
 
2.4 Direccionamiento indexado (Indexado Directo). 
 
EA se calcula sumando un desplazamiento (8 o 16 bits) a los contenidos de SI o DI. 
Ej. MOV BH,START (SI). 
LENGUAJE ENSAMBLADOR LABORATORIO DE COMPUTADORAS 
Página 14 Ing. Sánchez Rivero 
 2.5 Direccionamiento base indexado. 
 
EA se calcula sumando un registro base (BX o BP), un registro índice (DI o SI), y un 
desplazamiento (8 o 16 bits). 
Ej. MOV ALPHA (SI)(BX),CL. 
Este direccionamiento proporciona una forma conveniente para direccionar un arreglo 
localizado en la pila. 
 
2.6 Direccionamiento (cadena) 
 
Este modo usa registros índice. La cadena de instrucciones automáticamente asume que SI 
apunta al primer byte o palabra del operando destino. Los contenidos de SI y DI son 
incrementados automáticamente (poniendo a 0 DF mediante la instrucción CLD) o 
decrementados (poniendo a 1 DF mediante la instrucción STD) para apuntar al siguiente byte o 
palabra. El segmento del operando fuente es DS y puede ser encimado. 
El segmento del operando destino debe ser ES y no puede ser encimado. Ej. MOVS BYTE. 
 
3. DIRECCIONAMIENTO ACCESANDO PUERTOS (E/S) 
 
Hay dos tipos de direccionamiento usando puertos: directo e indirecto. 
En el modo directo, el número de puerto es el operando inmediato de 8 bits, lo cual permite 
accesar puertos numerados del 0 al 255. 
Ej. OUT 05H,AL. 
En el modo indirecto, el número de puerto se toma de DX, permitiendo así 64K puertos de 8 bits 
o 32K puertos de 16 bits. 
Las transferencias E/S de 8 y 16 bits deben hacerse vía AL y AX, respectivamente. 
 
4. DIRECCIONAMIENTO RELATIVO. 
 
En este modo el operando se especifica como un desplazamiento de 8 bits con signo, relativo al 
PC. 
Ej. JNC START. Si C=0, entonces el PC se carga con PC+el valor de START. 
 
5. DIRECCIONAMIENTO IMPLICITO. 
 
Las instrucciones que usan este modo no tienen operandos. 
Ej. CLC. 
 
LENGUAJE ENSAMBLADOR LABORATORIO DE COMPUTADORAS 
Ing. Sánchez Rivero Página 15 
 
TRABAJANDO CON EL DEBUG 
 
Para empezar a trabajar con Debug digite en el prompt de la computadora: 
 
C:\> Debug [Enter] 
 
En la siguiente línea aparecerá un guión, éste es el indicador del Debug, en este momento se 
pueden introducir las instrucciones del Debug. Utilizando el comando: 
 
- r [Enter] 
 
Se desplegaran todos los contenidos de los registros internos de la UCP; una forma 
alternativa de mostrarlos es usar el comando "r" utilizando como parámetro el nombre del 
registro cuyo valor se quiera visualizar. Por ejemplo: 
 
- rbx [Enter] 
 
Esta instrucción desplegará únicamente el contenido del registro BX y cambia el indicador del 
Debug de " - " a " : " 
 
Estando así el prompt es posible cambiar el valor del registro que se visualiza tecleando el 
nuevo valor y a continuación [Enter], o se puede dejar el valor anterior presionando [Enter] 
sin teclear ningún valor. 
 
Estructura de una instrucción en ensamblador 
 
En el lenguaje ensamblador las líneas de código están constituidas de dos partes: la primera 
es el nombre de la instrucción que se va a ejecutar y la segunda son los parámetros del 
comando u operandos. Por ejemplo: 
 
add ah, bh 
 
Aquí "add" es el comando a ejecutar (en este caso una adición) y tanto "ah" como "bh" son 
los parámetros. 
 
El nombre de las instrucciones en este lenguaje esta formado por dos, tres o cuatro letras. A 
estas instrucciones también se les llama nombres mnemónicos o códigos de operación, ya 
que representan alguna función que habrá de realizar el procesador. 
 
Existen algunos comandos que no requieren parámetros para su operación, así como otros 
que requieren solo un parámetro. 
 
Algunas veces se utilizarán las instrucciones como sigue: 
 
add al, [170] 
 
Los corchetes en el segundo parámetro nos indican que vamos a trabajar con el contenido 
de la casilla de memoria número 170 y no con el valor 170, a esto se le conoce como 
direccionamiento directo. 
 
Primer programa 
 
Se creará un programa que sirva para ilustrar lo analizado. Lo que se hará es una suma de 
dos valores que introduciremos directamente en el programa. 
El primer paso es iniciar el Debug, este paso consiste únicamente en teclear debug [Enter] 
en el prompt del sistema operativo. 
Para ensamblar un programa en el Debug se utiliza el comando "a" (Assembler); cuando se 
utiliza este comando se le puede dar como parámetro la dirección donde se desea que se 
inicie el ensamblado. 
Si se omite el parámetro el ensamblado se iniciará en la localidad especificada por CS: IP, 
usualmente 0100H, que es la localidad donde deben iniciar los programas con extensión 
.COM, y será la localidad que utilizaremos debido a que Debug solo puede crear este tipo 
específico de programas. 
LENGUAJE ENSAMBLADOR LABORATORIO DE COMPUTADORAS 
Página 16Ing. Sánchez Rivero 
Aunque en este momento no es necesario darle un parámetro al comando "a" es 
recomendable hacerlo para evitar problemas una vez que se haga uso de los registros CS: 
IP, por lo tanto tecleamos: 
 
- a0100 [Enter] 
 
Al hacer esto aparecerá en la pantalla algo como: 0C1B:0100 y el cursor se posiciona a la 
derecha de estos números. Nótese que los primeros cuatro dígitos (en sistema hexadecimal) 
pueden ser diferentes, pero los últimos cuatro deben ser 0100, ya que es la dirección que 
indicamos como inicio. 
Ahora podemos introducir las instrucciones: 
 
0C1B:0100 mov ax,0002 ;coloca el valor 0002 en el registro ax 
0C1B:0103 mov bx,0004 ;coloca el valor 0004 en el registro bx 
0C1B:0106 add ax,bx ;le adiciona al contenido de ax el contenido de bx 
0C1B:0108 int 20 ;provoca la terminación del programa. 
0C1B:010A 
 
No es necesario escribir los comentarios que van después del ";". Una vez digitado el último 
comando, int 20, se le da [Enter] sin escribir nada más, para volver al prompt del debugger. 
La última línea escrita no es propiamente una instrucción de ensamblador, es una llamada a 
una interrupción del sistema operativo, estas interrupciones serán tratadas más a fondo 
posteriormente, por el momento solo es necesario saber que nos ahorran un gran número de 
líneas y son muy útiles para accesar a funciones del sistema operativo. 
Para ejecutar el programa que escribimos se utiliza el comando "g", al utilizarlo veremos que 
aparece un mensaje que dice: "Program terminated normally". Naturalmente con un mensaje 
como éste no podemos estar seguros que el programa haya hecho la suma, pero existe una 
forma sencilla de verificarlo, utilizando el comando "r" del Debug podemos ver los contenidos 
de todos los registros del procesador, simplemente teclee: 
 
- r [Enter] 
 
Aparecerá en pantalla cada registro con su respectivo valor actual: 
 
AX=0006 BX=0004 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000 
DS=0C1B ES=0C1B SS=0C1B CS=0C1B IP=010A NV UP EI PL NZ NA PO NC 
0C1B:010A 0F DB oF 
 
Existe la posibilidad de que los registros contengan valores diferentes, pero AX y BX deben 
ser los mismos, ya que son los que acabamos de modificar. 
Otra forma de ver los valores, mientras se ejecuta el programa es utilizando como parámetro 
para "g" la dirección donde queremos que termine la ejecución y muestre los valores de los 
registros, en este caso sería: g108, esta instrucción ejecuta el programa, se detiene en la 
dirección 108 y muestra los contenidos de los registros. 
También se puede llevar un seguimiento de lo que pasa en los registros utilizando el 
comando "t" (trace), la función de este comando es ejecutar línea por línea lo que se 
ensambla mostrando cada vez los contenidos de los registros. 
Para salir del Debug se utiliza el comando "q" (quit). 
 
Guardar y cargar los programas 
 
No sería práctico tener que digitar todo un programa cada vez que se necesite, para evitar 
eso es posible guardar un programa en el disco, con la enorme ventaja de que ya 
ensamblado no será necesario correr de nuevo Debug para ejecutarlo. 
Los pasos a seguir para guardar un programa ya almacenado en la memoria son: 
 
♦ Obtener la longitud del programa restando la dirección final de la dirección inicial, 
naturalmente en sistema hexadecimal. 
♦ Darle un nombre al programa y extensión. 
♦ Poner la longitud del programa en el registro CX. 
♦ Ordenar a Debug que escriba el programa en el disco. 
 
Utilizando como ejemplo el programa anterior se tendrá una idea más clara de como llevar 
estos pasos. 
LENGUAJE ENSAMBLADOR LABORATORIO DE COMPUTADORAS 
Ing. Sánchez Rivero Página 17 
Al terminar de ensamblar el programa se vería así: 
 
0C1B:0100 mov ax,0002 
0C1B:0103 mov bx,0004 
0C1B:0106 add ax,bx 
0C1B:0108 int 20 
0C1B:010A 
- h 10a 100 
020a 000a 
- n prueba.com 
- rcx 
CX 0000 
:000a 
-w 
Writing 000A bytes 
 
Para obtener la longitud de un programa se utiliza el comando "h", el cual muestra la suma y 
resta de dos números en hexadecimal. Para obtener la longitud de nuestro programa le 
proporcionamos como parámetros el valor de la dirección final de nuestro programa (10A) y 
el valor de la dirección inicial (100). El primer resultado que nos muestra el comando es la 
suma de los parámetros y el segundo es la resta. 
El comando "n" nos permite poner un nombre al programa. 
El comando "rcx" nos permite cambiar el contenido del registro CX al valor que obtuvimos del 
tamaño del archivo con "h", en este caso 000a, ya que nos interesa el resultado de la resta 
de la dirección inicial a la dirección final. 
Por último el comando “w” escribe nuestro programa en el disco, indicándonos cuantos bytes 
escribió. 
Para cargar un archivo ya guardado son necesarios dos pasos: 
 
♦ Proporcionar el nombre del archivo que se cargará. 
♦ Cargarlo utilizando el comando "l" (load). 
 
Para obtener el resultado correcto de los siguientes pasos es necesario que previamente se 
haya creado el programa anterior. 
Dentro del Debug escribimos lo siguiente: 
 
- n prueba.com 
- l 
- u 100 109 
0C3D:0100 B80200 MOV AX,0002 
0C3D:0103 BB0400 MOV BX,0004 
0C3D:0106 01D8 ADD AX,BX 
0C3D:0108 CD20 INT 20 
 
El último comando, "u", se utiliza para verificar que el programa se cargó en memoria, lo que 
hace es desensamblar el código y mostrarlo ya desensamblado. Los parámetros le indican a 
Debug desde donde y hasta donde desensamblar. 
Debug siempre carga los programas en memoria en la dirección 100H, a menos que se le 
indique alguna otra dirección. 
 
Condiciones, ciclos y bifurcaciones 
 
Estas estructuras, o formas de control le dan a la máquina un cierto grado de decisión 
basado en la información que recibe. 
La forma más sencilla de comprender este tema es por medio de ejemplos. 
Se crearán tres programas que hagan lo mismo: desplegar un número determinado de veces 
una cadena de caracteres en la pantalla. 
 
- a100 
0C1B:0100 jmp 125 ; brinca a la dirección 125H 
0C1B:0102 [Enter] 
- e 102 'Cadena a visualizar 15 veces' 0d 0a '$' 
- a125 
0C1B:0125 MOV CX,000F ; veces que se desplegará la cadena 
0C1B:0128 MOV DX,0102 ; copia cadena al registro DX 
LENGUAJE ENSAMBLADOR LABORATORIO DE COMPUTADORAS 
Página 18 Ing. Sánchez Rivero 
0C1B:012B MOV AH,09 ; copia valor 09 al registro AH 
0C1B:012D INT 21 ; despliega cadena 
0C1B:012F LOOP 012D ; si CX>0 brinca a 012D 
0C1B:0131 INT 20 ; termina el programa. 
 
Por medio del comando "e" es posible introducir una cadena de caracteres en una 
determinada localidad de memoria, dada como parámetro, la cadena se introduce entre 
comillas, le sigue un espacio, luego el valor hexadecimal del retorno de carro, un espacio, el 
valor de línea nueva y por último el símbolo '$' que el ensamblador interpreta como final de la 
cadena. La interrupción 21 utiliza el valor almacenado en el registro AH para ejecutar una 
determinada función, en este caso mostrar la cadena en pantalla, la cadena que muestra es 
la que está almacenada en el registro DX. La instrucción LOOP decrementa 
automáticamente el registro CX en uno y si no ha llegado el valor de este registro a cero 
brinca a la casilla indicada como parámetro, lo cual crea un ciclo que se repite el número de 
veces especificado por el valor de CX. La interrupción 20 termina la ejecución del programa. 
 
Otra forma de realizar la misma función pero sin utilizar el comando LOOP es la siguiente: 
 
- a100 
0C1B:0100 jmp 125 ; brinca a la dirección 125H 
0C1B:0102 [Enter] 
- e 102 'Cadena a visualizar 15 veces'0d 0a '$' 
- a125 
0C1B:0125 MOV BX,000F ; veces que se desplegará la cadena 
0C1B:0128 MOV DX,0102 ; copia cadena al registro DX 
0C1B:012B MOV AH,09 ; copia valor 09 al registro AH 
0C1B:012D INT 21 ; despliega cadena 
0C1B:012F DEC BX ; decrementa en 1 a BX 
0C1B:0130 JNZ 012D ; si BX es diferente a 0 brinca a 012D 
0C1B:0132 INT 20 ; termina el programa. 
 
En este caso se utiliza el registro BX como contador para el programa, y por medio de la 
instrucción "DEC" se disminuye su valor en 1. La instrucción "JNZ" verifica si el valor de B es 
diferente a 0, esto con base en la bandera NZ, en caso afirmativo brinca hacia la dirección 
012D. En caso contrario continúa la ejecución normal del programa y por lo tanto se termina. 
 
Una última variante del programa es utilizando de nuevo a CX como contador, pero en lugar 
de utilizar LOOP utilizaremos decrementos a CX y comparación de CX a 0. 
 
- a100 
0C1B:0100 jmp 125 ; brinca a la dirección 125H 
0C1B:0102 [Enter] 
- e 102 'Cadena a visualizar 15 veces' 0d 0a '$' 
- a125 
0C1B:0125 MOV DX,0102 ; copia cadena al registro DX 
0C1B:0128 MOV CX,000F ; veces que se desplegará la cadena 
0C1B:012B MOV AH,09 ; copia valor 09 al registro AH 
0C1B:012D INT 21 ; despliega cadena 
0C1B:012F DEC CX ; decrementa en 1 a CX 
0C1B:0130 JCXZ 0134 ; si CX es igual a 0 brinca a 0134 
0C1B:0132 JMP 012D ; brinca a la dirección 012D 
0C1B:0134 INT 20 ; termina el programa 
 
En este ejemplo se usó la instrucción JCXZ para controlar la condición de salto, el significado 
de tal función es: brinca si CX=0 
El tipo de control a utilizar dependerá de las necesidades de programación en determinado 
momento. 
 
 
LENGUAJE ENSAMBLADOR LABORATORIO DE COMPUTADORAS 
Ing. Sánchez Rivero Página 19 
 
PROGRAMACIÓN EN ENSAMBLADOR 
 
IMPORTANCIA DEL LENGUAJE ENSAMBLADOR 
 
El lenguaje ensamblador es la forma más básica de programar un microprocesador para que 
éste sea capaz de realizar las tareas o los cálculos que se le requieran. 
El lenguaje ensamblador es conocido como un lenguaje de bajo nivel, esto significa que nos 
permite controlar el 100 % de las funciones de un microprocesador, así como los periféricos 
asociados a éste. 
A diferencia de los lenguajes de alto nivel, por ejemplo "Pascal", el lenguaje ensamblador no 
requiere de un compilador, esto es debido a que las instrucciones en lenguaje ensamblador 
son traducidas directamente a código binario y después son colocadas en memoria para que 
el microprocesador las tome directamente. 
Aprender a programar en lenguaje ensamblador no es fácil, se requiere un cierto nivel de 
conocimiento de la arquitectura y organización de las computadoras, además del 
conocimiento de programación en algún otro lenguaje 
 
La primera razón para trabajar con ensamblador es que proporciona la oportunidad de 
conocer más a fondo la operación de su PC, lo que permite el desarrollo de software de una 
manera más consistente. 
 
La segunda razón es el control total de la PC que se tiene con el uso del mismo. 
 
Otra razón es que los programas de ensamblador son más rápidos, más compactos y tienen 
mayor capacidad que los creados en otros lenguajes. 
Por último el ensamblador permite una optimización ideal en los programas tanto en su 
tamaño como en su ejecución. 
El Lenguaje Ensamblador es importante como se puede ver; es directamente traducible al 
Lenguaje de Máquina, y viceversa; simplemente, es una abstracción que facilita su uso para 
los seres humanos. Por otro lado, la computadora no entiende directamente al Lenguaje 
Ensamblador; es necesario traducirle a Lenguaje de Máquina. Pero, al ser tan directa la 
traducción, pronto aparecieron los programas Ensambladores, que son traductores que 
convierten el código fuente (en Lenguaje Ensamblador) a código objeto (es decir, a Lenguaje 
de Máquina). Surge como una necesidad de facilitar al programador la tarea de trabajar con 
lenguaje máquina sin perder el control directo con el hardware. 
 
VENTAJAS Y DESVENTAJAS DEL LENGUAJE ENSAMBLADOR 
 
Conocida es la evolución de los lenguajes de programación, cabe preguntarse: ¿En estos 
tiempos "modernos", para qué quiero el Lenguaje Ensamblador? 
El proceso de evolución trajo consigo algunas desventajas, que se verán luego así como las 
ventajas de usar el Lenguaje Ensamblador, respecto a un lenguaje de alto nivel: 
Ventajas del lenguaje ensamblador: 
 
• Velocidad de ejecución de los programas 
• Tamaño 
• Flexibilidad 
 
VELOCIDAD 
 
El proceso de traducción que realizan los intérpretes, implica un proceso de cómputo 
adicional al que el programador quiere realizar. Por ello, nos encontraremos con que un 
intérprete es siempre más lento que realizar la misma acción en Lenguaje Ensamblador, 
simplemente porque tiene el costo adicional de estar traduciendo el programa, cada vez que 
lo ejecutamos. 
De ahí nacieron los compiladores, que son mucho más rápidos que los intérpretes, pues 
hacen la traducción una vez y dejan el código objeto, que ya es Lenguaje de Máquina, y se 
puede ejecutar muy rápidamente. Aunque el proceso de traducción es más complejo y 
costoso que el de ensamblar un programa, normalmente podemos despreciarlo, contra las 
ventajas de codificar el programa más rápidamente. 
Sin embargo, la mayor parte de las veces, el código generado por un compilador es menos 
eficiente que el código equivalente que un programador escribiría. La razón es que el 
compilador no tiene tanta inteligencia, y requiere ser capaz de crear código genérico, que 
sirva tanto para un programa como para otro; en cambio, un programador humano puede 
LENGUAJE ENSAMBLADOR LABORATORIO DE COMPUTADORAS 
Página 20 Ing. Sánchez Rivero 
aprovechar las características específicas del problema, reduciendo la generalidad pero al 
mismo tiempo, no desperdicia ninguna instrucción, no hace ningún proceso que no sea 
necesario. 
Para darnos una idea, en una PC, y suponiendo que todos son buenos programadores, un 
programa para ordenar una lista tardará cerca de 20 veces más en Visual Basic (un 
intérprete), y 2 veces más en C (un compilador), que el equivalente en Ensamblador. 
Por ello, cuando es crítica la velocidad del programa, Ensamblador se vuelve un candidato 
lógico como lenguaje. 
Ahora bien, esto no es un absoluto; un programa bien hecho en C puede ser muchas veces 
más rápido que un programa mal hecho en Ensamblador; sigue siendo sumamente 
importante la elección apropiada de algoritmos y estructuras de datos. Por ello, se 
recomienda buscar optimizar primero estos aspectos, en el lenguaje que se desee, y 
solamente usar Ensamblador cuando se requiere más optimización y no se puede lograr por 
estos medios. 
 
TAMAÑO 
 
Por las mismas razones que vimos en el aspecto de velocidad, los compiladores e intérpretes 
generan más código máquina del necesario; por ello, el programa ejecutable crece. Así, 
cuando es importante reducir el tamaño del ejecutable, mejorando el uso de la memoria y 
teniendo también beneficios en velocidad, puede convenir usar el lenguaje Ensamblador. 
Entre los programas que es crítico el uso mínimo de memoria, tenemos a los virus y 
manejadores de dispositivos (drivers). Muchos de ellos, por supuesto, están escritos en 
lenguaje Ensamblador. 
 
FLEXIBILIDAD 
 
Las razones anteriores son cuestión de grado: podemos hacer las cosas en otro lenguaje, 
pero queremos hacerlas más eficientemente. Pero todos los lenguajes de alto nivel tienen 
limitantes en el control; al hacer abstracciones, limitan su propia capacidad. Es decir, existen 
tareasque la máquina puede hacer, pero que un lenguaje de alto nivel no permite. Por 
ejemplo, en Visual Basic no es posible cambiar la resolución del monitor a medio programa; 
es una limitante, impuesta por la abstracción del GUI Windows. En cambio, en ensamblador 
es sumamente sencillo, pues tenemos el acceso directo al hardware del monitor. 
Por otro lado, al ser un lenguaje más primitivo, el Ensamblador tiene ciertas desventajas 
respecto a los lenguajes de alto nivel: 
 
Desventajas del lenguaje ensamblador: 
 
• Tiempo de programación 
• Programas fuentes grandes 
• Peligro de afectar recursos inesperadamente 
• Falta de portabilidad 
 
TIEMPO DE PROGRAMACIÓN 
 
Al ser de bajo nivel, el Lenguaje Ensamblador requiere más instrucciones para realizar el 
mismo proceso, en comparación con un lenguaje de alto nivel. Por otro lado, requiere de más 
cuidado por parte del programador, pues es propenso a que los errores de lógica se reflejen 
más fuertemente en la ejecución. 
Por todo esto, es más lento el desarrollo de programas comparables en Lenguaje 
Ensamblador que en un lenguaje de alto nivel, pues el programador goza de una menor 
abstracción. 
 
PROGRAMAS FUENTE GRANDES 
 
Por las mismas razones que aumenta el tiempo, crecen los programas fuentes; simplemente, 
requerimos más instrucciones primitivas para describir procesos equivalentes. Esto es una 
desventaja porque dificulta el mantenimiento de los programas, y nuevamente reduce la 
productividad de los programadores. 
 
PELIGRO DE AFECTAR RECURSOS INESPERADAMENTE 
 
LENGUAJE ENSAMBLADOR LABORATORIO DE COMPUTADORAS 
Ing. Sánchez Rivero Página 21 
Tenemos la ventaja de que todo lo que se puede hacer en la máquina, se puede hacer con el 
Lenguaje Ensamblador (flexibilidad). El problema es que todo error que podamos cometer, o 
todo riesgo que podamos tener, podemos tenerlo también en este Lenguaje. Dicho de otra 
forma, tener mucho poder es útil pero también es peligroso. 
En la vida práctica, afortunadamente no ocurre mucho; sin embargo, al programar en este 
lenguaje verán que es mucho más común que la máquina se "cuelgue", "bloquee" o "se le 
vaya el avión"; y que se reinicialize. ¿Por qué?, porque con este lenguaje es perfectamente 
posible (y sencillo) realizar secuencias de instrucciones inválidas, que normalmente no 
aparecen al usar un lenguaje de alto nivel. 
En ciertos casos extremos, puede llegarse a sobrescribir información del CMOS de la 
máquina (no he visto efectos más riesgosos); pero, si no la conservamos, esto puede causar 
que dejemos de "ver" el disco duro, junto con toda su información. 
 
FALTA DE PORTABILIDAD 
 
Como ya se mencionó, existe un lenguaje ensamblador para cada máquina; por ello, 
evidentemente no es una selección apropiada de lenguaje cuando deseamos codificar en 
una máquina y luego llevar los programas a otros sistemas operativos o modelos de 
computadoras. Si bien esto es un problema general a todos los lenguajes, es mucho más 
notorio en ensamblador: yo puedo reutilizar un 90% o más del código que desarrollo en "C", 
en una PC, al llevarlo a una RS/6000 con UNIX, y lo mismo si después lo llevo a una 
Macintosh, siempre y cuando esté bien hecho y siga los estándares de "C", y los principios 
de la programación estructurada. En cambio, si escribimos el programa en Ensamblador de 
la PC, por bien que lo desarrollemos y muchos estándares que sigamos, tendremos 
prácticamente que reescribir el 100 % del código al llevarlo a UNIX, y otra vez lo mismo al 
llevarlo a Mac. 
 
 
LENGUAJE ENSAMBLADOR LABORATORIO DE COMPUTADORAS 
Página 22 Ing. Sánchez Rivero 
SINTAXIS DE UNA LÍNEA EN ENSAMBLADOR 
 
Un programa fuente en ensamblador contiene dos tipos de sentencias: las instrucciones y 
las directivas. Las instrucciones se aplican en tiempo de ejecución, pero las directivas sólo 
son utilizadas durante el ensamblaje. 
El formato de una sentencia de instrucción es el siguiente: 
 
 [etiqueta] nombre_instrucción [operandos] [comentario] 
 
Los corchetes, como es normal al explicar instrucciones en informática, indican que lo 
especificado entre ellos es opcional, dependiendo de la situación que se trate. 
 
 Campo de etiqueta: Es el nombre simbólico de la primera posición de una instrucción, 
puntero o dato. Consta de hasta 31 caracteres que pueden ser las letras de la A a la Z, los 
números del 0 al 9 y algunos caracteres especiales como «@», «_», «.» y «$». 
Reglas: 
• Si se utiliza el punto «.», éste debe colocarse como primer carácter de la etiqueta. 
• El primer carácter no puede ser un dígito. 
• No se pueden utilizar los nombres de instrucciones o registros como nombres de 
etiquetas. 
 
 Las etiquetas son de tipo NEAR cuando el campo de etiqueta finaliza con dos puntos 
(:); esto es, se considera cercana: quiere esto decir que cuando realizamos una llamada 
sobre dicha etiqueta el ensamblador considera que está dentro del mismo segmento de 
código (llamadas intrasegmento) y el procesador sólo carga el puntero de instrucciones IP. 
Téngase en cuenta que hablamos de instrucciones; las etiquetas empleadas antes de las 
directivas, como las directivas de definición de datos por ejemplo, no llevan los dos puntos y 
sin embargo son cercanas. 
 Las etiquetas son de tipo FAR si el campo de etiqueta no termina con los dos puntos: 
en estas etiquetas la instrucción a la que apunta no se encuentra en el mismo segmento de 
código sino en otro. Cuando es referenciada en una transferencia de control se carga el 
puntero de instrucciones IP y el segmento de código CS (llamadas intersegmento). 
 
 Campo de nombre: Contiene el mnemónico de las instrucciones o bien una directiva. 
 
 Campo de operandos: Indica cuales son los datos implicados en la operación. Puede 
haber 0, 1 ó 2; en el caso de que sean dos al 1º se le llama destino y al 2º -separado por una 
coma- fuente. 
 mov ax, es:[di] --> ax destino 
 
 --> es:[di] origen 
 
Campo de comentarios: Cuando en una línea hay un punto y coma (;) todo lo que sigue en 
la línea es un comentario que realiza aclaraciones sobre lo que se está haciendo en ese 
Programa; resulta de gran utilidad de cara a realizar futuras modificaciones al mismo. 
 
CONSTANTES Y OPERADORES 
 
Las sentencias fuente -tanto instrucciones como directivas- pueden contener constantes y 
operadores. 
 
CONSTANTES 
 
Pueden ser binarias (ej. 10010b), decimales (ej. 34d), hexadecimales (ej. 0E0h) u octales (ej. 
21o ó 21q); también las hay de tipo cadena (ej. 'pepe', "juan") e incluso con comillas dentro 
de comillas de distinto tipo (como 'hola,"amigo"'). En las constantes hexadecimales, si el 
primer dígito no es numérico hay que poner un 0. Sólo se puede poner el signo (-) en las 
decimales (en las demás, calcúlese el complemento a dos) Por defecto, las numéricas están 
en base 10 si no se indica lo contrario con una directiva (poco recomendable como se verá). 
 
OPERADORES ARITMÉTICOS 
 
LENGUAJE ENSAMBLADOR LABORATORIO DE COMPUTADORAS 
Ing. Sánchez Rivero Página 23 
Pueden emplearse libremente (+), (-), (*) y (/) - en este último caso la división es siempreentera-. Es válida, por ejemplo, la siguiente línea en ensamblador (que se apoya en la 
directiva DW, que se verá más adelante, para reservar memoria para una palabra de 16 bits): 
 
 Dato DW 12*(numero+65)/7 
 
También se admiten los operadores MOD (resto de la división) y SHL/SHR (desplazar a la 
izquierda/derecha cierto número de bits). Obviamente, el ensamblador no codifica las 
instrucciones de desplazamiento (al aplicarse sobre datos constantes el resultado se calcula 
en tiempo de ensamblaje): 
 
 Dato DW (12 SHR 2) + 5 
 
OPERADORES LÓGICOS 
 
Pueden ser el AND, OR, XOR y NOT. Realizan las operaciones lógicas en las expresiones. 
Ej.: 
 MOV BL,(255 AND 128) XOR 128 ; BL = 0 
 
OPERADORES RELACIONALES 
 
Devuelven condiciones de Verdadero (0FFFFh ó 0FFh) o Falso (0) evaluando una expresión. 
Pueden ser: EQ (igual), NE (no igual), LT (menor que), GT (mayor que), LE (menor o igual 
que), GE (mayor o igual que). 
Ejemplo: 
 
 dato EQU 100 ; «dato» vale 100 
 MOV AL,dato GE 10 ; AL = 0FFh (Verdadero) 
 MOV AH,dato EQ 99 ; AH = 0 (Falso) 
 
OPERADORES DE RETORNO DE VALORES 
 
* Operador SEG: devuelve el valor del segmento de la variable o etiqueta, sólo se 
puede emplear en programas de tipo EXE: 
 
 MOV AX,SEG tabla_datos 
 
* Operador OFFSET: devuelve el desplazamiento de la variable o etiqueta en su 
segmento: 
 
 MOV AX,OFFSET variable 
 
Si se desea obtener el offset de una variable respecto al grupo (directiva GROUP) de 
segmentos en que está definida y no respecto al segmento concreto en que está definida: 
 
 MOV AX,OFFSET nombre_grupo:variable 
 
También es válido: 
 
 MOV AX,OFFSET DS:variable 
 
* Operador .TYPE: devuelve el modo de la expresión indicada en un byte. El bit 0 
indica modo «relativo al código» y el 1 modo «relativo a datos»; si ambos bits están inactivos 
significa modo absoluto. El bit 5 indica si la expresión es local (0 si está definida 
externamente o indefinida); el bit 7 indica si la expresión contiene una referencia externa. 
Este operador es útil sobre todo en las macros para determinar el tipo de los parámetros: 
 
 info .TYPE variable 
 
* Operador TYPE: devuelve el tamaño (bytes) de la variable indicada. No válido en 
variables DUP: 
 
 kilos DW 76 
 MOV AX,TYPE kilos ; AX = 2 
 
LENGUAJE ENSAMBLADOR LABORATORIO DE COMPUTADORAS 
Página 24 Ing. Sánchez Rivero 
Tratándose de etiquetas -en lugar de variables- indica si es lejana o FAR (0FFFEh) o cercana 
o NEAR (0FFFFh). 
 
* Operadores SIZE y LENGTH: devuelven el tamaño (en bytes) o el nº de elementos, 
respectivamente, de la variable indicada (definida obligatoriamente con DUP): 
 
 matriz DW 100 DUP (12345) 
 MOV AX,SIZE matriz ; AX = 200 
 MOV BX,LENGTH matriz ; BX = 100 
 
* Operadores MASK y WIDTH: informan de los campos de un registro de bits (véase 
RECORD). 
 
OPERADORES DE ATRIBUTOS 
 
* Operador PTR: redefine el atributo de tipo (BYTE, WORD, DWORD, QWORD, 
TBYTE) o el de distancia (NEAR o FAR) de un operando de memoria. Por ejemplo, si se 
tiene una tabla definida de la siguiente manera: 
 
 Tabla DW 10 DUP (0) ; 10 palabras a 0 
 
Para colocar en AL el primer byte de la misma, la instrucción MOV AL,tabla es incorrecta, ya 
que tabla (una cadena 10 palabras) no cabe en el registro AL. Lo que desea el programador 
debe indicárselo en este caso explícitamente al ensamblador de la siguiente manera: 
 
 MOV AL,BYTE PTR tabla 
 
Trabajando con varios segmentos, PTR puede redefinir una etiqueta NEAR de uno de ellos 
para convertirla en FAR desde el otro, con objeto de poder llamarla. 
 
* Operadores CS:; DS:; ES: y SS: el ensamblador genera un prefijo de un byte que 
indica al microprocesador el segmento que debe emplear para acceder a los datos en 
memoria. Por defecto, se supone DS para los registros BX, DI o SI (o sin registros de base o 
índice) y SS para SP y BP. Si al acceder a un dato éste no se encuentra en el segmento por 
defecto, el ensamblador añadirá el byte adicional de manera automática. Sin embargo, el 
programador puede forzar también esta circunstancia: 
 
 MOV AL,ES:variable 
 
En el ejemplo, variable se supone ubicada en el Segmento Extra. Cuando se 
referencia una dirección fija hay que indicar el segmento, ya que el ensamblador no conoce 
en qué segmento está la variable; es uno de los pocos casos en que debe indicarse. Por 
ejemplo, la siguiente línea dará un error al ensamblar: 
 
 MOV AL,[0] 
 
Para solucionarlo hay que indicar en qué segmento está el dato (incluso aunque éste sea 
DS): 
 MOV AL,DS:[0] 
 
En este último ejemplo el ensamblador no generará el byte adicional ya que las instrucciones 
MOV operan por defecto sobre DS (como casi todas), pero ha sido necesario indicar DS para 
que el ensamblador nos entienda. Sin embargo, en el siguiente ejemplo no es necesario, ya 
que midato está declarado en el segmento de datos y el ensamblador lo sabe: 
 
 MOV AL,midato 
 
Por lo general no es muy frecuente la necesidad de indicar explícitamente el segmento: al 
acceder a una variable el ensamblador mira en qué segmento está declarada (véase la 
directiva SEGMENT) y según como estén asignados los ASSUME, pondrá o no el prefijo 
adecuado según sea conveniente. Es responsabilidad exclusiva del programador inicializar 
los registros de segmento al principio de los procedimientos para que el ASSUME no se 
quede en tinta mojada... sí se emplean con bastante frecuencia, sin embargo, los prefijos CS 
LENGUAJE ENSAMBLADOR LABORATORIO DE COMPUTADORAS 
Ing. Sánchez Rivero Página 25 
en las rutinas que gestionan interrupciones (ya que CS es el único registro de segmento que 
apunta en principio a las mismas, hasta que se cargue DS u otro). 
 
* Operador SHORT: indica que la etiqueta referenciada, de tipo NEAR, puede 
alcanzarse con un salto corto (-128 a +127 posiciones) desde la actual situación del contador 
de programa. El ensamblador TASM, si se solicitan dos pasadas, coloca automáticamente 
instrucciones SHORT allí donde es posible, para economizar memoria (el MASM no) 
 
* Operador '$': indica la posición del contador de posiciones («Location Counter») 
utilizado por el ensamblador dentro del segmento para llevar la cuenta de por dónde se llega 
ensamblando. Muy útil: 
 
 frase DB "simpático" 
 longitud EQU $-OFFSET frase 
En el ejemplo, longitud tomará el valor 9. 
 
* Operadores HIGH y LOW: devuelven la parte alta o baja, respectivamente (8 bits) de 
la expresión: 
 
 dato EQU 1025 
 MOV AL,LOW dato ; AL = 1 
 MOV AH,HIGH dato ; AH = 4 
 
 
LENGUAJE ENSAMBLADOR LABORATORIO DE COMPUTADORAS 
Página 26 Ing. Sánchez Rivero 
PRINCIPALES DIRECTIVAS 
 
La sintaxis de una sentencia directiva es muy similar a la de una sentencia de instrucción: 
 
 [nombre] nombre_directiva [operandos] [comentario] 
 
Sólo es obligatorio el campo «nombre_directiva»; los campos han de estar separados por al 
menos un espacio en blanco. La sintaxis de «nombre» es análoga a la de la «etiqueta» de 
las líneas de instrucciones, aunque nunca se pone el sufijo «:». El campo de comentario 
cumple también las mismas normas.

Otros materiales

Materiales relacionados

103 pag.
Curso de programacion de virus

Vicente Riva Palacio

User badge image

ninette

29 pag.
Sistemas Numéricos e Conversões

BUAP

User badge image

Estudiando Y Aprendendo

Preguntas relacionadas