You are on page 1of 21

PROGRAMACION EN LENGUAJE ENSAMBLADOR

PARA EL 8086
Introduccin.
El lenguaje ensamblador como cualquier lenguaje de programacin es un conjunto de palabras que le indican
al ordenador lo que tiene que hacer. Sin embargo la diferencia fundamental es que cada instruccin escrita en
lenguaje ensamblador tiene una correspondencia exacta con una operacin en el procesador. Por lo que son
operaciones muy sencillas. Las instrucciones del lenguaje ensamblador son nemotcnicos que representan el
cdigo mquina, es decir codificacin binaria de cadenas de 1's y 0's, codificacin que entiende el procesador.
Cada procesador tiene su propio lenguaje ensamblador exclusivo de su CPU, excepto cuando existe
compatibilidad entre familias de procesadores. El lenguaje ensamblador es usado principalmente porque hay
aplicaciones o programas que deben tratar directamente con los registros de la mquina, la memoria,
dispositivos de E/S, etc.

Arquitectura del 8086.


En 1978 Intel present el procesador 8086. Poco despus, desarroll una variacin del 8086 para ofrecer
un diseo ligeramente ms sencillo y compatibilidad con los dispositivos de entrada/salida de ese
momento. Este nuevo procesador, el 8088, fue seleccionado por IBM para su PC en 1981. Ambos poseen
una arquitectura interna de 16 bits y pueden trabajar con operandos de 8 y 16 bits; una capacidad de
direccionamiento de 20 bits, es decir, existe la posibilidad de direccionar 220 posiciones de memoria (bytes),
lo que equivale a 1Mb de memoria principal y comparten el mismo conjunto de 92 instrucciones.
La estructura interna del 8086 puede verse en la Figura 1. El 8086 se divide en dos unidades lgicas: una
unidad de ejecucin (EU) y una unidad de interfaz del bus (BIU). El papel de la EU es ejecutar
instrucciones, mientras que la BIU enva instrucciones y datos a la EU. La EU posee una unidad aritmticolgica, una unidad de control y 10 registros. Permite ejecutar las instrucciones, realizando todas las
operaciones aritmticas, lgicas y de control necesarias.

Figura 1. Arquitectura interna del 8086.

Registros del 8086. Segmentacin


Los registros del procesador tienen como misin fundamental almacenar las posiciones de memoria que van
a sufrir repetidas manipulaciones, ya que los accesos a memoria son mucho ms lentos que los accesos a
los registros. El 8086 dispone de 14 registros de 16 bits que se emplean para controlar la ejecucin de
instrucciones, direccionar la memoria y proporcionar capacidad aritmtica y lgica. Cada registro puede
1

almacenar datos o direcciones de memoria. Los registros son direccionables por medio de un nombre. Por
convencin los bits de un registro se numeran de derecha a izquierda:

15
1

14
0

13
0

12
0

11
0

10
1

9
1

8
0

7
1

6
0

5
0

4
0

3
1

2
1

1
1

0
0

Los diferentes registros del 8086 se clasifican en: registros de propsito general o de datos, registros de
segmento, registro apuntador de instrucciones (IP), registros apuntadores (SP y BP), registros ndice (SI y
DI) y registro de banderas, FLAGS o registro de estado (FL).
AX
BX
CX
DX
Registros de
Proposito general o
de datos

SP
BP
SI
DI
Registros punteros y
Registros indices

CS
DS
SS
ES
Registros de
segmento

IP
FLAGS o FL
Registro puntero
de instrucciones; y
Registro de
banderas, FLAGS o
de estado (FL)

Figura 2. Registros del 8086/88 y del 80286.

Registros de propsito general.


Se utilizan para clculo y almacenamiento de propsito general. Los programas leen datos de memoria y los
dejan en estos registros, ejecutan operaciones sobre ellos, y guardan los resultados en memoria. Hay cuatro
registros de propsito general que, aparte de ser usados a voluntad por el programador, tienen fines
especficos:
Registro AX
Registro BX

Registro CX
Registro DX

Este registro es el acumulador principal, implicado en gran parte de las


operaciones de aritmticas y de E/S.
Recibe el nombre de registro base ya que es el nico registro de propsito general
que se usa como un ndice en el direccionamiento indexado. Se suele utilizar para
clculos aritmticos.
El CX es conocido como registro contador ya que puede contener un valor para
controlar el nmero de veces que se repite una cierta operacin.
Se conoce como registro de datos. Algunas operaciones de E/S requieren su uso,
y las operaciones de multiplicacin y divisin con cifras grandes suponen que el
DX y el AX trabajando juntos

Los registros de propsito general se pueden direccionar como una palabra o como un byte. El byte de la
izquierda es la parte alta o byte ms significativo y el byte de la derecha es la parte o byte menos
significativo.

RX
RH

RL

Siguiendo esta nomenclatura, es posible referirse a cada uno de los dos bytes, byte de orden alto o ms
significativo y byte de orden bajo o menos significativo, de cada uno de estos registros. Por ejemplo: AH
es el byte ms significativo del registro AX, mientras que AL es el byte menos significativo.
As, por ejemplo, si AX contiene 00FFh, AH=00h (su parte alta) y AL=FFh (su parte baja); si lo
incrementamos en 1, AX pasa a valer 0100h (lgicamente), y con ello AH=01h, AL=00h. Si en lugar de
incrementar en 1 AX lo hacemos con AL (byte inferior), AH se quedar como estaba y AL ser
FFh+01h=00h, es decir, AX=0000h (vamos, que cuando se manipula una parte del registro la otra no se
ve afectada en absoluto, pero, obviamente, s el registro completo)
Uno puede mover los datos de unos registros a otros con prcticamente total libertad. Tambin
podremos realizar operaciones sobre ellos, como sumar el contenido de BX y DX para guardar el resultado
en DX, y cosas as. La primera restriccin al respecto (y bastante razonable) es que los operandos tendrn
que ser del mismo tamao (no podremos sumar BX con DH, por ejemplo).

Registros de Segmento.
Los registros de segmento son registros de 16 bits que constituyen la implementacin fsica de la
2

arquitectura segmentada del 8086. Para entender para qu sirven estos registros primero debemos
explicar brevemente en que consiste la segmentacin.

Segmentos y direccionamiento
Para acceder a una direccin de memoria lo lgico sera colocar dicha direccin completa en un registro y
acceder mediante este. Sin embargo el 8086 tiene 20 lneas en el bus de direcciones (20 bits) mientras
que sus registros son de 16 bits, de forma que siguiendo esta filosofa solo podramos direccionar 64KBytes
(216) del mega posible (220).
La solucin a esto consisti en usar dos registros de 16 bits, pero no dispuestos consecutivamente, ya que
obtendramos una direccin de 32 bits pasndonos del rango de memoria disponible, sino que un registro
especifica un bloque de memoria, el segmento, y el otro un desplazamiento u offset dentro de este bloque.
Puesto que utilizamos registros de 16 bits tendremos 64K posibles segmentos de 64 KBytes cada uno.
Para direccionar cualquier posicin de memoria, el procesador combina la direccin del segmento que se
encuentra en un registro de segmento con un valor de desplazamiento, para calcular la direccin real de 20
bits.

Figura 3. Construccin de una direccin de memoria en base a una direccin de segmento y una
direccin de offset.
Como vemos en la figura anterior, lo primero que se hace es aadir 4 bits a 0 al valor que se encuentra en el
registro de segmento, lo cual es equivalente a multiplicar dicho valor por 16. Es por esto que cualquier
segmento empieza siempre en una direccin de memoria (de 20 bits) mltiplo de 16, esto es, el segmento 0
comenzara en la direccin 00000h y acabara en la 0FFFFh; el segmento 1 comenzara en la direccin
00010h (16 en hexadecimal) y acabara en la 1000Fh; etc

Figura 4. Segmentacin de la memoria


Por tanto, como podemos ver en la figura, los distintos segmentos se solapan, esto es, hay pares
segmento-offset que apuntan a la misma direccin de memoria.
Por ejemplo, dado el segmento 045EH y un desplazamiento de 0032H:
Direccin del segmento:
045E0H
Desplazamiento dentro del segmento:
+0032H
Direccin real:
04612H
Y, dado el segmento 045FH y un desplazamiento de 0022H:
3

Direccin del segmento:


Desplazamiento dentro del segmento:
Direccin real:

045F0H
+0022H
04612H

Ahora bien, un programa puede tener uno o varios segmentos, los cuales pueden comenzar en casi cualquier
lugar de la memoria, variar en tamao y estar en cualquier orden, pero en general, tendr un segmento para
el cdigo, otro para los datos y otro para la pila. Para apuntar a estos segmentos es para lo que sirven los
registros de segmento:
Registro CS
Registro DS
Registro SS
Registro ES

Registro Segmento de Cdigo. Establece el rea de memoria dnde est el


programa durante su ejecucin.
Registro Segmento de Datos. Especifica la zona donde los programas leen y
escriben sus datos.
Registro Segmento de Pila. Permite la colocacin en memoria de una pila, para
almacenamiento temporal de direcciones y datos.
Registro Segmento Extra. Para acceder a un segmento distinto de los anteriores
sin necesidad de modificar los otros registros de segmento.

El segmento de cdigo contiene las instrucciones que sern ejecutadas, mientras que el segmento de datos
contiene los datos a los que las instrucciones hacen referencia.

Registro Apuntador de Instrucciones (IP).


Se trata de un registro de 16 bits que contiene el desplazamiento de la direccin de la siguiente instruccin
que se ejecutar. Est asociado con el registro CS en el sentido de que IP indica el desplazamiento de la
siguiente instruccin a ejecutar dentro del segmento de cdigo determinado por CS:
Direccin del segmento de cdigo en CS:
Desplazamiento dentro del segmento de cdigo en IP:
Direccin de la siguiente instruccin a ejecutar:

25A40H
+ 0412H
25E52H

Registros Apuntadores (SP y BP).


Los registros apuntadores estn asociados al registro de segmento de pila, SS, y permiten acceder a los
datos almacenados en la pila. Representan un desplazamiento respecto a la direccin determinada por SS:
Registro SP
Registro BP

Proporciona un valor de desplazamiento que se refiere a la palabra actual que est


siendo procesada en la pila.
Facilita la referencia a los parmetros de las rutinas, los cuales son datos y
direcciones transmitidos va la pila.

En general, el registro IP indica el desplazamiento de la instruccin actual que es ejecutada dentro del
segmento de cdigo; el registro SP indica el desplazamiento dentro del segmento de pila, apuntando al
ltimo elemento introducido en la pila; y un operando (que sea una referencia a memoria) de una
instruccin indica un desplazamiento en el segmento de datos del programa.

Figura 5 Esquema de direccionamiento para un programa.

Registros ndice (SI y DI).


Los registros ndice se utiliza fundamentalmente en operaciones con cadenas y para direccionamiento
indexado:
Registro SI

Registro ndice fuente requerido en algunas operaciones con cadenas de


caracteres. Este registro est asociado con el registro DS.
Registro ndice destino requerido tambin en determinadas operaciones con
cadenas de caracteres. Est asociado al registro DS o ES.

Registro DI

Los registros de ndice se pueden usar como registros de datos sin problemas para sumas, movimiento de
datos... no as los de segmento, que tienen fuertes limitaciones. Cuando se diga "un registro" como
operando de una instruccin, eso incluye en principio cualquier registro menos los de segmento.

Registro de banderas, FLAGS, o registro de estado (FL).


Es un registro de 16 bits, pero slo se utilizan nueve de ellos. Sirven para indicar el estado actual de la
mquina y el resultado del procesamiento. La mayor parte de las instrucciones de comparacin y
aritmticas modifican este registro. Algunas instrucciones pueden realizar pruebas sobre este registro para
determinar la accin siguiente (como las instrucciones de salto)

15
-

14
-

13
-

12
-

11
O

10
D

9
I

8
T

7
S

6
Z

5
-

4
A

3
-

2
P

1
-

0
C

Los bits 0, 2, 4, 6, 7 y 11 son indicadores de condicin que reflejan los resultados de las operaciones del
programa; los bits 8 al 10 son indicadores de control que, modificados por el programador, sirven para
controlar ciertos modos de procesamiento, y el resto no se utilizan. El significado de cada uno de los bits
es el siguiente:
OF
DF
IF
TF
SF
ZF

Bit de Overflow o desbordamiento. Indica desbordamiento de un bit de orden alto (ms a


la izquierda), despus de una operacin aritmtica.
Bit de Direccin. Designa la direccin, creciente (0) o decreciente (1), en operaciones con
cadenas de caracteres.
Bit de Interrupcin. Indica que una interrupcin externa, como la entrada desde el
teclado, sea procesada o ignorada.
Bit de Trap o Desvo. Procesa o ignora la interrupcin interna de trace (procesamiento
paso a paso).
Bit de Signo. Indica el valor del bit ms significativo del registro despus de una
operacin aritmtica o de desplazamiento.
Bit Cero. Se pone a 1 si una operacin produce 0 como resultado
5

AF
PF
CF

Bit de Carry Auxiliar. Se pone a 1 si una operacin aritmtica produce un acarreo del bit
3 al 4. Se usa para aritmtica especializada (ajuste BCD).
Bit de Paridad. Se activa si el resultado de una operacin tiene paridad par.
Bit de Acarreo. Contiene el acarreo de una operacin aritmtica o de desplazamiento de
bits.

Modos de direccionamiento.
Las operaciones se hacen entre registros o registros y memoria, pero nunca entre memoria y memoria
(salvo algunas operaciones con cadenas de caracteres). Los modos de direccionamiento determinan el
lugar en que reside un operando, un resultado o la siguiente instruccin a ejecutar, segn el caso, en
memoria. Para ilustrar los distintos modos de direccionamiento, vamos a usar la instruccin
MOVE destino, fuente
que carga el contenido del operando fuente en el destino
1.- INMEDIATO. El operando aparece especificado directamente en la instruccin.
Ejemplo: El operando fuente en MOVE AX, 789AH => copia el valor 789AH en AX
2.- MODO REGISTRO. El operando es un registro.
Ejemplo: Los operandos en MOV AX, CX => se copia en AX el contenido de CX
3.- DIRECTO ABSOLUTO A MEMORIA. El operando es una direccin de memoria a la que se quiere acceder.
Ejemplo: El operando fuente en MOV AX, [078AH] => copia en AX el contenido de la direccin
DS:078AH

4.- DIRECTO RELATIVO A UN REGISTRO BASE. El operando es una direccin de memoria a la que se
desea acceder, y se calcula mediante un registro base. Este registro base ser el BX o el BP segn deseemos
trabajar con el segmento DS o SS respectivamente.
Ejemplo: El operando fuente en MOV AX, [BX + 2] => copia en AX el contenido de la direccin DS:BX+2
5.- DIRECTO RELATIVO A UN REGISTRO INDICE. El operando es una direccin de memoria a
la que se desea acceder, y se calcula en base a un registro ndice. Este registro ndice ser el SI o el DI.
Ejemplo: El operando fuente en MOV AX, [SI + 10] => copia en AX el contenido de la direccin DS:SI+10
Si el desplazamiento no existe en los dos ltimos modos, hablamos de direccionamiento indirecto
por registro base o por registro ndice.
6.- INDEXADO A PARTIR DE UNA BASE. El operando es una direccin de memoria a la que se desea
acceder, y se calcula en base a un registro base y un registro ndice. Hay cuatro configuraciones posibles: el
registro base puede ser el BX o el BP, y el registro ndice puede ser el SI o el DI.
Ejemplo: El operando destino en MOV [BP + DI + 2], AX => copia en la direccin SS:BP+DI+2 el contenido
de AX

Estos tres ltimos modos de direccionamiento pueden resumirse en:


[BX | BP] + [SI | DI] + [Desplazamiento]
Si aparece BP el registro de segmento por defecto es SS, en caso contrario es DS.
6

Nota: Los modos de direccionamiento del 3 al 6 pueden estar precedidos de un registro de segmento:
MOV AX, ES: [BX + SI + 6].

Registros de Segmento por defecto.


Existen unos segmentos asociados por defecto a los registros de desplazamiento (IP, SP, BP, BX, DI y
SI). Slo es necesario declarar el segmento cuando no coincide con el asignado por defecto.
La Figura 6 muestra los segmentos que se emplean por defecto para cada uno de los registros que se
encuentran en la primera columna:

IP
SP
BP
BX
SI
DI

CS
S
Nunca
Prefijo
Prefijo
Prefijo
Prefijo

SS
Nunca
S
Por Defecto
Prefijo
Prefijo
Prefijo

DS
Nunca
Nunca
Prefijo
Por Defecto
Por Defecto
Por Defecto

ES
Nunca
Nunca
Prefijo
Prefijo
Prefijo
Por Defecto Cadenas

Figura 6. Segmentos por defecto.

Direccionamiento de Localidades de Memoria.


El 8086 posee un bus de datos de 16 bits y por tanto manipula cantidades de esta longitud (llamadas
palabras). Cada palabra a la que se accede consta de dos bytes, un byte de orden alto o ms significativo
y un byte de orden bajo o menos significativo. El sistema almacena en memoria estos bytes de la siguiente
manera: el byte menos significativo en la direccin baja de memoria y el byte ms significativo en la
direccin alta de memoria, tal y como se muestra en la Figura 7.

Figura 7. Direccionamiento de Localidades de Memoria.

Pila (STACK).
La pila no es ms que un rea para el almacenamiento temporal de direcciones y datos de tipo LIFO (Last In First Out),
esto es, el ltimo dato en entrar en la pila es el primero en salir. El registro SS indica la direccin de inicio de la pila,
mientras que el registro SP apunta al byte siguiente al ltimo que pertenece a la pila. La pila se caracteriza
porque empieza a almacenar datos en la localidad ms alta y avanza hacia abajo en la memoria, esto es, cada

vez que se introduce un dato en la pila se decrementa SP, y cuando se saca, se incrementa. Existen
instrucciones especiales para introducir (PUSH) y sacar (POP) datos de la pila que se encargar de
modificar apropiadamente el registro SP. Los datos que se introduzcan en la pila siempre son de dos
bytes.
Ejemplo: Introducimos en la pila los registros AX y BX que contienen FA01H y 35A9H respectivamente.
Suponemos que el registro SP contiene 50 bytes.

SS: direccin del segmento de pila

Ultimo elemento de la pila SP=50

3428H
7

PUSH AX: Se introduce en la pila AX se decrementa SP y se introduce el dato

SS: direccin del segmento de pila

SP=48

FA01H
3428H

PUSH BX: Se introduce en la pila BX  se decrementa SP y se introduce el dato


SS: direccin del segmento de pila

A935H
FA01H
3428H

SP=46

POP BX: Se extrae de la pila un dato y se introduce en BX se extrae el dato y se incrementa SP.
SS: direccin del segmento de pila

SP=48

FA01H
3428H

PROGRAMACIN DEL PC SOBRE DOS


Directivas del ensamblador.
El programa ensamblador permite usar diferentes enunciados que sirven para controlar la forma en
que un programa se ensambla y lista. Estos enunciados reciben el nombre de directivas. Se caracterizan
porque slo tienen influencia durante el proceso de ensamblado, pero no generan cdigo ejecutable
alguno. Estas directivas pueden variar algo de un programa ensamblador a otro. Nosotros explicaremos
algunas de las ms usadas en el TASM.

Directivas para declaracin y manejo de segmentos.


Directiva
Descripcin
Formato
Ejemplo

.MODEL (ntese .)
Especifica el modelo de memoria utilizado.
.MODEL modelo
.MODEL Compact

La siguiente tabla resume los distintos tipos de modelos de memoria:


MODELO
TINY
SMALL
COMPACT
LARGE
HUGE

Directiva
Descripcin
Formato
Directiva
Descripcin
Formato
Directiva
Descripcin
Formato
Directiva
Descripcin
Formato

CARACTERSTICAS
Datos y cdigo cogen en un solo segmento de 64K.
Un segmento de datos y otro de cdigo.
Mltiples segmentos de datos y un nico segmento de cdigo. Este modelo y el
anterior son los que normalmente se utilizan.
Mltiples segmentos de datos y de cdigo.
Mltiples segmentos de datos y de cdigo. Los segmentos pueden pasar 64K, pero
haciendo operaciones especiales de normalizacin de direcciones

.DATA (ntese .)
Las declaraciones siguientes se insertarn en el segmento de datos. Se
contina donde la anterior directiva .DATA termin (vase seccin 4.2).
.DATA
.CODE (ntese .)
Las declaraciones siguientes se insertarn en el segmento de cdigo. Se
contina donde la anterior directiva .CODE termin (vase seccin 4.2)
.CODE
. STACK (ntese .)
Las declaraciones siguientes se insertarn en el segmento de pila. Se
contina donde la anterior directiva .STACK termin. (vase seccin 4.2)
. STACK
PROC
Para definir cada uno de los procedimientos incluidos en el segmento de
cdigo.
NombreProc PROC
...
NombreProc ENDP

Ejemplo
Directiva
Descripcin
Formato

END
Finaliza todo el programa.
END [dir_inicial] ; Generalmente etiqueta del PROC principal.

Directivas para definicin de datos.


El ensamblador permite definir elementos para datos de diferentes longitudes de acuerdo con un conjunto
de directivas especficas para ello. El formato general es el siguiente:
[nombre]

Dn

Contador_Repeticiones DUP (expresin)

Donde Dn es una de las directivas de la siguiente tabla:


DIRECTIVA
DB
DW
DD
DF
DQ
DT
EJEMPLO
DATO1
DB
DATO2
DB
DATO3
DB
DATO4
DB
DATO5
DB
DATO6
DB
DATO7
DB
DATO8
DB
DATO9
DW
DATO10 DW
DATO11 DD
DATO12 DD

DESCRIPCIN
Definir un byte. Sirve adems para definir
cadenas de caracteres.
Definir una palabra (2 bytes).
Definir una palabra doble (4 bytes).
Definir una palabra larga (6 bytes).
Definir una palabra cudruple (8 bytes).
Definir diez bytes (10 bytes).

?
25
10101011B
1BH
1,2,3,4,5,6,7,8,9,10
5 DUP(?)
5 DUP(14)
Cadena de caracteres
0FFF0H
10,12,14,16,18,20
?
14,49

COMENTARIO.
No se inicializa.
Constante decimal.
Constante binaria.
Constante hexadecimal.
Diez bytes inicializados.
Cinco bytes no inicializados.
Cinco bytes incializados a 14.
Cadena de caracteres. 1 byte por cada caracter
Constante hexadecimal.
Seis palabras inicializadas.
No se inicializa.
Dos palabras dobles inicializadas.

Los datos se almacenan en memoria en el orden en que han sido declarados y podemos acceder a
ellos usando el nombre dado en la declaracin. Por ejemplo, si declaramos los siguientes datos:
Numero dw 5
Tabla 3, 4, 5
Cadena db hola
El aspecto de la memoria sera el siguiente:

El nombre de cada dato es equivalente a una direccin de memoria, de forma que si sumamos o restamos
un valor al nombre de una variable, accedemos a otra direccin de memoria. Por ejemplo:
MOV
MOV
MOV
MOV
MOV

AX,
AL,
AL,
AL,
AL,

Numero
AX=0005
Tabla
AL = 02
Tabla + 1 AL = 03
Cadena
AL = h (cdigo ASCII de la h)
Tabla + 3 AL = h

10

Asimismo, al igual que cuando operamos con dos registros, el tamao de la variable debe ser el mismo
que el del otro operando, esto es, operaciones como las siguientes daran un error al ensamblar:
MOV AL, Numero
MOV AX, Tabla

Etiquetas y variables.
Un identificador es un nombre aplicado a elementos incluidos en el programa ensamblador. Hay dos
tipos de identificadores que son:
Nombre o etiqueta de dato: se refiere a la direccin de un dato almacenado en una determinada
posicin de memoria, esto es, una variable.
Etiqueta de instruccin: se refiere a la direccin de una instruccin. En TASM la etiqueta se debe
escribir al principio de la lnea seguida de dos puntos (:)
etiqueta:

MOV AX, BX

Las mismas reglas se aplican tanto para los nombres como para las etiquetas:
LETRAS DEL ALFABETO
DGITOS
CARACTERES ESPECIALES

De la A a la Z.
Del 0 al 9 (no puede ser el
primer carcter).
Signo de interrogacin ( ? )
Subrayado ( _ ) Signo
del dlar ( $ ) Arroba
(@)
Punto ( . )

Nota: ciertas palabras en lenguaje ensamblador estn reservadas para propsitos especficos y no pueden
ser usadas como identificadores (instrucciones, directivas, operadores y todos aquellos smbolos
predefinidos usados por el ensamblador).

Constantes Numricas.
Las constantes numricas se usan para definir valores aritmticos y direcciones de memoria. Las
constantes numricas no llevan comillas, como sucede con las cadenas de caracteres, y van seguidas de un
indicador de la base utilizada. Si se omite ste, se supone el sistema decimal.

CONSTANTE
DECIMAL
HEXADECIMAL
BINARIO

FORMATO
[-] 0...9[D]
0...F[H]
0/1[B]

EJEMPLO
1234D
0F0AH
11101000B

Si el primer dgito de una constante hexadecimal es una letra (A..F), debe anteponerse
un cero, para que el ensamblador pueda distinguir que se trata de una constante numrica
y no una cadena de caracteres.

La Directiva EQU.
La directiva EQU no define ningn tipo de dato, sino que define constantes, o sea, define valores que
el ensamblador puede sustituir en otras instrucciones. Por ejemplo,
VALOR EQU 100
Cada vez que en el programa aparezca VALOR, el ensamblador lo sustituir por 100. As,
MOV AX, VALOR
11

Es equivalente a
MOV AX, 100
Es muy til para evitar tener que actualizar en varias instrucciones una constante que se repite y que se
modifica al depurar el programa.

Esquema de un programa
Llegados a este punto ya podemos mostrar la estructura tpica de un programa en ensamblador
del 8086 con TASM:
.MODEL small

;obligatorio especificar el modelo de memoria

.STACK 100H

;reservamos memoria para la pila

.DATA
;declaracin de datos o variables, si las hay

.CODE
MOV AX, @DATA
MOV DS, AX ;inicializamos DS
;aqu nuestro cdigo
MOV AH, 4Ch
INT 21h
END
Todo el texto que haya en una lnea despus de un ; (punto y coma) el TASM lo trata como un
comentario. Las dos primeras lneas del cdigo sirven para que el registro DS tenga el valor del segmento
donde el sistema operativo a introducido los datos al cargar el programa en memoria. Los registros CS y SS
no es necesario inicializarlos, ya el Sistema Operativo se encarga de que apunten correctamente a los
segmentos correspondientes, el de cdigo y el de la pila, respectivamente.
Las dos ltimas lneas indican al Sistema Operativo que el programa ha terminado y le devuelve el
control del sistema.

Ensamblado, linkado y montado.


El cdigo descrito en el apartado anterior lo habremos escrito en un fichero de texto, con un editor
cualquiera de texto, y en el caso de usar TASM, le habremos dado la extensin .asm. Pero obviamente
este cdigo an no es ejecutable. Para que el procesador pueda interpretarlo debemos generar un fichero
ejecutable (.EXE o .COM).

Ensamblado
Un ensamblador es el programa que convierte un listado de cdigo fuente, escrito en un fichero de
texto, en cdigo objeto, es decir, lenguaje mquina (el que finalmente interpretar el procesador) en el que
slo le faltan las referencias a rutinas externas. El cdigo fuente es un fichero que contiene la secuencia de
instrucciones en lenguaje ensamblador que forma el programa, as como ciertas directivas o comandos
para el propio ensamblador, que ha sido creado utilizando un editor de texto. El cdigo objeto consta
del cdigo en lenguaje mquina y de la informacin necesaria para enlazarlo con otros mdulos objeto.
Con TASM el proceso de ensamblado se realiza escribiendo lo siguiente en la ventana de comandos:
tasm /zi /l nombre
donde nombre es el nombre del fichero .asm con el cdigo fuente. La extensin no es necesaria ponerla y
12

los parmetros /zi y /l slo son tiles si queremos hacer un proceso de depuracin (debug) con el Turbo
Debugger. Tras la ejecucin de esta lnea se nos crear un fichero nombre.obj

Linkado y Montado
Al construir un programa algunos de sus mdulos pueden colocarse en el mismo mdulo fuente y
ensamblarse juntos, otros pueden estar en mdulos diferentes y ser ensamblados separadamente. En
cualquier caso, los mdulos objeto resultantes, algunos de los cuales pueden estar agrupados en
libreras, deben ser enlazados para formar el mdulo de carga, antes de que se pueda ejecutar el
programa. Adems de dar como salida el mdulo de carga, el linker o enlazador imprime un mapa de
memoria que indica donde sern cargados los mdulos objeto en la memoria. Despus de crearse el mdulo
de carga, ste es cargado por el cargador en la memoria del ordenador y comienza la ejecucin. Para linkar
con TASM escribimos:
tlink /v nombre
Tras esto se nos crear el fichero ejecutable (.exe o .com) que el sistema operativo se encargar de
cargar en memoria cuando lo ejecutemos. De nuevo, la extensin no es necesaria ponerla y el
parmetro /v slo es til para el Turbo Debugger

Figura 8: Proceso de ensamblado, linkado y montado

Procedimientos
Una procedimiento no es ms que una subrutina, o un fragmento de cdigo al que se le llama, generalmente
varias veces, desde el programa principal, o desde una procedimiento, jerrquicamente superior. Un
procedimiento se declara mediante la directiva PROC, y se puede declarar en cualquier parte del segmento
de cdigo
.CODE
...
nombre_subrutina PROC
; cdigo de la subrutina
RET
ENDP
...
END
Cuando se llama a un procedimiento simplemente se realiza un salto al trozo de cdigo donde est definida
la subrutina, y cuando sta termina se vuelve al cdigo desde el que se realiz la llamada. La llamada
a la subrutina se realiza mediante la instruccin CALL y la vuelta al cdigo la realizamos con RET, por
lo que es importante acabar siempre los procedimientos con esta instruccin:

13

Lo que ocurre realmente al hacer CALL es que, antes de realizar el salto, se almacena en la pila la
direccin de retorno (la direccin de la siguiente instruccin a CALL), y la instruccin RET recupera esta
direccin de la pila y salta a la misma.
Una prctica muy comn y recomendable al escribir en una subrutina es guardar en la pila, al principio de
su cdigo, todos los registros que vaya a modificar y volverlos a sacar al final del cdigo (antes de la
instruccin RET). De esta forma el programa principal que realiza la llamada no tiene que preocuparse de
que la subrutina pueda modificarle el valor de algn registro que le fuese necesario.

Paso de parmetros a procedimientos


Registros.
Los parmetros para el procedimiento que se llama se pasan en los registros del procesador. De esta
forma, se establece un compromiso entre el procedimiento que llama y el llamado, ya que ste ltimo
espera cada parmetro en un determinado registro del procesador. Este mecanismo es sumamente rpido,
ya que no requiere realizar accesos a memoria. Por otro lado, adolece de dos inconvenientes importantes: el
nmero de registros del procesador es limitado, es decir, el nmero de los parmetros est
condicionado por los registros del procesador disponibles; tener los parmetros en registros supone
no poder usar estos registros para realizar cualquier otra operacin, a menos que se salvaguarden (por
ejemplo, en la pila), lo que significa ms accesos a memoria.
.MODEL SMALL
.DATA
DATO1 DW 25
DATO2 DW 33
.CODE
MOV AX, SEG DATO1 ;equivalente a @DATA
MOV DS, AX
MAIN:
MOV BX, DATO1
MOV CX, DATO2
CALL SUMA
; LA SUMA EST EN AX!!!
MOV AH, 4Ch
INT 21h
SUMA PROC
MOV AX,BX
ADD AX,CX
RET
SUMA ENDP
END MAIN

Memoria Intermedia.
Otra forma de pasar los parmetros a un procedimiento, es utilizar posiciones de memoria especficamente
dedicadas a ello. El procedimiento que llama almacena los parmetros en determinadas posiciones de
memoria, donde el procedimiento llamado acude a recogerlos. Con este esquema, los parmetros no
ocupan registros del procesador; como contrapartida se consume memoria, y el acceso a los
parmetros es ms lento que en el caso anterior. Otra desventaja adicional que escapa a primera
vista es que este tipo de paso de parmetros no permite procedimientos recursivos, ya que cada
vez que se llama al procedimiento se modifican los parmetros.
PARAM1 DB ?
PARAM2 DW ?
. . .
MOV PARAM1,6AH ;Guarda en PARAM1 el primer parmetro
MOV PARAM2,12345D ;Guarda en PARAM2 el segundo parmetro
14

CALL PROCEDIMIENTO ;Llama al procedimiento

Pila.
La tercera posibilidad para pasar los parmetros es hacer uso de la pila. sta es la que se usa formalmente,
aunque por su complejidad no la explicaremos en este manual. Antes de llamar a un procedimiento, el
llamante introduce en la pila los parmetros del procedimiento llamado. Este mecanismo supone igual que
en el caso anterior un consumo de memoria, pero en este caso slo temporalmente. Adems, esta
posibilidad permite el uso de procedimientos recursivos.

MACROS
Una macro es un fragmento de cdigo que el ensamblador copia, al ensamblar el cdigo, en las lneas
que contengan llamadas a la macro, esto es, cada vez que se realiza una llamada a una MACRO se
sustituye esa llamada por el cdigo de la MACRO. A diferencia del procedimiento no se realiza ningn
salto ni la definicin de la macro es cdigo realmente (se convierte en cdigo cuando lo copia en el
lugar de la llamada), por lo que podemos declarar la MACRO en cualquier parte, dentro o fuera de la
zona de cdigo, aunque siempre la declaracin debe estar antes que la llamada. Para poder utilizar
etiquetas dentro de las macros, debemos declararlas como locales, ya que en caso contrario, al hacer
distintas llamadas, tendramos varias etiquetas con el mismo nombre.
nombre_macro MACRO
LOCAL etiqueta_local
...
ENDM
.CODE
;programa principal
...
nombre_macro ;llamada a la MACRO. Esta lnea se
;sustituye por el cdigo dentro de la
;MACRO
END

Paso de parmetros a las MACROS


A las macros se les puede pasar cualquier nmero de parmetros como se ve en el siguiente
ejemplo:
Suma MACRO a, b
ADD a, b
ENDM
La llamada
Suma AX, BX
Es equivalente a
ADD AX, BX

Funciones DOS
El nmero de funcin se pasa en el registro AH

# de Funcin
00h
01h

Descripcin
Terminar un programa
Entrada de caracteres con salida
15

02h
03h
04h
05h
06h
07h
08h
09h
0Ah
0Bh
0Ch
0Dh
0Eh
0Fh
10h
11h
12h
13h
14h
15h
16h
17h
18h
19h
1Ah
1Bh
1Ch
1Dh/1Eh
1Fh
20h
21h
22h
23h
24h
25h
26h
27h
28h
29h
2Ah
2Bh
2Ch
2Dh
2Eh
2Fh
30h
31h
32h
33h
34h
35h
36h
37h
38h
39h

Salida de un carcter
Recepcin de un carcter por el puerto serial
Envo de un carcter por el puerto serial
Salida por puerto paralelo
Entrada/salida de caracteres directa
Entrada/salida de caracteres directa
Entrada de caracteres sin salida
Salida de un string de caracteres
Entrada de un string de caracteres
Leer estado de una entrada
Borra buffer de entrada y llama a entrada de caracteres
Reset de los drivers de bloques
Seleccin de unidad actual
Abrir archivo usando FCBs (File Control Blocks)
Cerrar archivo (FCBs)
Busca primera entrada de directorio (FCBs)
Busca siguiente entrada de directorio (FCBs)
Borrar archivo(s) (FCBs)
Lectura secuencial (FCBs)
Escritura secuencial (FCBs)
Crear o vaciar un archivo (FCBs)
Renombrar archivos (FCBs)
Obsoleta
Obtener denominacin de dispositivo, unidad actual
Fijar direccin para DTA (Disk Transfer Area)
Obtener informacin sobre unidad actual
Obtener informacin sobre una unidad cualquiera
Obsoletos
Fijar puntero a DPB (Drive Parameter Block) a la unidad actual
Obsoleta
Lectura random (FCB)
Escritura random (FCB)
Leer tamao de archivo (FCB)
Establecer nmero de registro (FCB)
Establecer vector de interrupcin
Crear nuevo PSP (Program Segment Prefix)
Lectura random de varios registros (FCB)
Escritura random de varios registros (FCB)
Transferir nombre de archivo al FCB
Obtener fecha
Establecer fecha
Obtener hora
Establecer hora
Fijar bandera de Verify
Obtener DTA
Obtener nmero de versin del DOS
Terminar programa pero dejarlo residente en memoria
Obtener puntero a DPB de una unidad especfica
Leer/escribir bandera de break
Obtener direccin de bandera INDOS
Leer vector de interrupcin
Obtener espacio de disco disponible
Obtener/fijar signo p/separador de lnea de comandos
Obtener/fijar formatos especficos de un pas
Crear subdirectorio
16

3Ah
3Bh
3Ch
3Dh
3Eh
3Fh
40h
41h
42h
43h
44h
45h
46h
47h
48h
49h
4Ah
4Bh
4Ch
4Dh
4Eh
4Fh
50h
51h
52h
53h
54h
55h
56h
57h
58h
59h
5Ah
5Bh
5Ch
5Dh
5Eh
5Fh
60h
61h
62h
63h/64h
65h
66h
67h
68h
69/6A/6B
6Ch

Borrar subdirectorio
Fijar directorio actual
Crear o vaciar archivo (handle)
Abrir archivo (handle)
Cerrar archivo (handle)
Leer desde archivo (handle)
Escribir en archivo (handle)
Borrar archivo (handle)
Mover puntero de archivo (handle)
Obtener/fijar atributo de archivo
Funciones IOCTL (control de I/O)
Duplicar handle
Duplicacin forzosa de handles
Obtener directorio actual
Reservar memoria RAM
Liberar memoria RAM
Modificar tamao de memoria reservada
EXEC: ejecutar o cargar programas
Terminar programa con valor de salida
Obtener valor de salida de un programa
Buscar primera entrada en el directorio (handle)
Buscar siguiente entrada en el directorio (handle)
Establecer PSP activo
Obtener PSP activo
Obtener puntero al DOS-info-block
Traducir Bios Parameter Block a Drive Parameter Block
Leer bandera Verify
Crear PSP nuevo
Renombrar o mover archivo
Obtener/fijar fecha y hora de modificacin de archivo
Leer/fijar estrategia de alocacin de memoria
Obtener informaciones de error ampliadas
Crear archivo temporal (handles)
Crear archivo nuevo (handles)
Proteger parte de un archivo contra accesos
Funciones de Share.exe
Obtener nombres de dispositivos de red
Obtener/fijar/borrar entrada de la lista de red
Ampliar nombre de archivo
No usada
Obtener direccin del PSP
No usadas
Obtener informacin ampliada de pais especfico
Obtener/fijar pgina de cdigos actual
Determinar el nmero de handles disponibles
Vaciar buffer de archivos
No usadas
Funcin Open ampliada

17

Ejemplo de Ensamblado, linkado y montado de un programa.


Para poder compilar y linkear nuestros programas vamos a hacer uso de la mquina virtual DOSBOX, para
ello deber descomprimir el archivo DOSBOX.zip y dentro de la carpeta descomprimida haga doble clic
sobre el file DOSBOX.bat, deber ver una pantalla como la siguiente:

Escriba cd LAB_01 y presione ENTER, sus programas debern de ser creados dentro de esta carpeta
(LAB_01) de la mquina virtual. Ahora escriba edit HOLA.asm y presione ENTER para empezar a editar
su cdigo fuente. Tenga cuidado de no hacer clic sobre la ventana mostrada pues el puntero del mouse
desaparecer, si esto le pasara entonces con hacer ALT+TAB volver a ver el puntero.

Para salir del edit y/o hacer uso de alguna opcin del Menu del Edit , solo presione ALT y se activara el
men, luego usando las teclas de flecha arriba, abajo, izquierda y derecha podr desplazarse por el men y
escoger la opcin deseada.

18

Ahora para crear el archivo ejecutable, primero deber compilarlo tipeando tasm /zi /l hola y presionando
ENTER, si hay errores, se mostraran en la pantalla, indicando la(s) lnea(s) donde se encuentra el error.

Si no hubo errores en la compilacin se podr a pasar a crear el archivo ejecutable en base al archivo OBJ que
se cre mediante el comando tasm del paso anterior, para ello escriba tlink /v hola y presione ENTER. Si no
hubiera errores de linkeo entonces se habr creado el archivo ejecutable.
Para correr su archivo ejecutable solo escriba hola y presione ENTER.

Para que se vaya familiarizando con el entorno, cambie el cdigo del programa anterior y muestre su apellido
y nombre en lneas diferentes, como en el ejemplo siguiente.
C:\LABS\LAB_01>hola
19

Valentin
Sarmiento

Ahora compile y ejecute el siguiente cdigo (TEST.c) y con la ayuda del documento JUEGO DE
INSTRUCCIONES.pdf describa lnea por lnea lo que hace el programa.
.model small
.data
msg1 db 10,13,"Enter first no.$"
msg2 db 10,13,"Enter second no.$"
msg3 db 10,13,"Addition is:$"
.code
mov ax,@data
mov ds,ax
lea dx,msg1
mov ah,09H
int 21H
mov ah,01H
int 21H
sub
cmp
JBE
sub

al,30H
al,09H
L1
al,07H

L1: mov cl,04H


ROL al,cl
mov bl,al
mov ah,01H
int 21H
sub
cmp
JBE
sub

al,30H
al,09H
L2
al,07H

L2: ADD bl,al


lea dx,msg2
mov ah,09H
int 21H
mov ah,01H
int 21H
sub
cmp
JBE
sub

al,30H
al,09H
L3
al,07H

L3: mov cl,04H


ROL al,cl
mov bh,al
mov ah,01H
int 21H
sub
cmp
JBE
sub

al,30H
al,09H
L4
al,07H

L4: ADD bh,al


ADD bl,bh
20

lea dx,msg3
mov ah,09H
int 21H
mov ch,02H
mov cl,04H
L5: ROL bl,cl
mov bh,bl
AND
cmp
JBE
ADD

bl,0FH
bl,09H
L6
bl,07H

L6: ADD bl,30H


mov dl,bl
mov ah,02H
int 21H
mov bl,bh
dec ch
JNZ L5
mov ah,4ch
int 21H
end
Para compilarlo, crear el ejecutable y correr el programa o cualquier otro puede usar el file batch EXE,bat del
siguiente modo:
C:\LABS\LAB_01>exe test

Recuerde presionar ENTER luego de escribir el nombre del archivo.

21

You might also like