Está en la página 1de 126

CAPITULO I INTRODUCION AL LENGUAJE ENSAMBLADOR

En este captulo encontraras el fundamento para aprender a programar en lenguaje ensamblador, programacin,
procesadores, lenguajes de computacin, sistemas de nmeros y software para desarrollo de herramientas.

Nuevos trminos

Procesador. El circuito, en la tarjeta principal de la mquina, que ejecuta las operaciones bsicas de la
computadora.

Conjunto de instruccin. El conjunto de todas las posibles instrucciones que el procesador puede
ejecutar.

Lenguaje Mquina. El conjunto de operaciones bsicas, ejecutadas por el procesador, adems de las
reglas para usarlas.

Lenguaje de alto nivel. Un lenguaje cuyas instrucciones estn muy lejanas del lenguaje mquina.

Lenguaje de bajo nivel. Un lenguaje cuyas instrucciones estn ms cercanas al lenguaje mquina.

Lenguaje Ensamblador. Es un tipo de lenguaje de bajo nivel en el cual abreviaciones mnemotcnicas
representan operaciones mquina y almacenan localidades. El lenguaje ensamblador hace posible
programar al procesador directamente sin usar lenguaje mquina.

Compilador. Un programa que traduce programas de alto nivel a lenguaje mquina para que estos
puedan ser ejecutados.

Interprete. Un programa que traduce programas de alto nivel a lenguaje mquina, una lnea a la vez,
conforme se van ejecutando.

Compilador Incremental. Un programa que combina compilacin e interpretacin para traducir un
programa de alto nivel a una forma intermedia (pseudo-cdigo) que es despus interpretado.

Pseudo-Cdigo. La forma en la cual un programa de alto nivel es parcialmente compilado por un
compilador incremental.

Ensamblador. (1) Un programa que traduce programas de bajo nivel a lenguaje mquina. (2) Un trmino
usado para nombrar al Lenguaje Ensamblador.

Coprocesador. Un procesador opcional usado para ejecutar operaciones matemticas, especialmente
clculos de punto flotante.

Modo Real. Un estado de operacin en el cual un 286, 386, o 486 se comportan como un 8088 rpido; en
el modo real, la computadora puede ejecutar muchos programas escritos por los miembros viejos de la
familia PC.

Modo Protegido. Un estado de operacin en el cual un 286, 386, o 486 pueden tener acceso a una gran
cantidad de memoria; este estado tambin permite las multitareas, particularmente para trabajos en
sistemas operativos y otros softwares sofisticados.

1
Memoria Virtual. Un sistema de administracin de la memoria en el cual la memoria del disco es usada
para simular grandes cantidades de memoria regular interna.

Multitareas. Ejecutar ms de un programa al mismo tiempo por medio de rpidos cambios entre los
programas.

Modo Virtual 86. Un estado de operacin en el cual un procesador 386, o 486 pueden correr mltiples
programas, donde cada uno tiene su propio procesador 8086.

Cdigo. (1) Usado como verbo el trmino se refiere a un programa escrito. (2) Usado como sustantivo el
trmino se refiere a las instrucciones de un programa.

Editor. Un programa que permite teclear un programa y hacerle cambios cuando sea necesario.

Enlazador (Linker). Un programa que procesa un programa traducido de ensamblador a una forma en
que puede ser ejecutado.

Programa Fuente Cdigo Fuente. Un programa en lenguaje ensamblador que va a ser traducido a
Ensamblador. Los programas fuente son almacenados en archivos con la extensin ASM.

Modulo Objeto. La traduccin a lenguaje mquina del programa fuente; los mdulos objeto son
almacenados en archivos con extensin OBJ.

Modulo Cargable (Load Module Run Module). Una versin ejecutable de un modulo objeto, tambin
llamado un run module, producido por el Enlazador. Los mdulos cargables son almacenados en archivos
con la extensin EXE (o algunas veces COM).

Depurador (Debugger). Un programa que provee un ambiente para probar load modules.



1.1 Orientacin.

En trminos informales el cerebro de la computadora es el procesador, un chip electrnico que, en
muchas computadoras, se encuentra en la tarjeta del sistema principal, las computadoras personales IBM
usan procesadores de la familia Intel 86. Estos procesadores son conocidos por un nmero de modelo,
desde los menos poderosos hasta los actuales, estos son: 8086, 8088, 186, 286, 386, 486, Pentium, etc.

Dentro de cada nmero de modelo hay variaciones, por ejemplo existen procesadores 386 SX y 386 DX.
La ms importante idea de IBM es que todos sus procesadores, menos alguno, corran los mismos
programas, asegurndose que los miembros de la familia Intel 86 sean mutuamente compatibles. Las
habilidades que aprendas del lenguaje ensamblador te permitirn programar cualquier PC, sin importar
que procesador uses.



1.2 Lenguaje Mquina.

La lista de todas las posibles instrucciones que cada procesador puede ejecutar es denominada
conjunto de instrucciones. La tabla 1-1 muestra el tamao del conjunto de instrucciones para varios
miembros de la familia Intel 86.

2



Tabla 1-1 Procesador Tamao del conjunto de instrucciones
8086/8088 115
186 126
286 142
386 200
486 206
Pentium 216

El conjunto de instrucciones que el procesador puede ejecutar directamente, y las reglas para usar esas
instrucciones se llama lenguaje mquina. En lenguaje mquina cada instruccin esta codificada con un
nmero. Si t ves un programa en lenguaje mquina veras una gran cadena de nmeros.

Los seres humanos no pueden programar en lenguaje mquina, debido a que un programa consiste de
cientos de miles de nmeros. De una forma ms simple nosotros podemos escribir programas usando
lenguajes de computacin. Nosotros podemos dividir los lenguajes de computacin en dos grupos: alto
nivel y bajo nivel. Los lenguajes de alto nivel tales como C, C++, Pascal o Basic, estn muy lejanos del
lenguaje mquina. Cuando t usas un lenguaje de alto nivel, te concentras en el problema a resolver, y no
necesitas saber nada acerca de como el procesador ejecutar el programa. Por supuesto antes de ejecutarlo
este tiene que ser convertido a lenguaje mquina.

Sin importar el lenguaje que uses, este debe ser traducido a instrucciones en lenguaje mquina, el cual es
el que comprende el procesador. Existen tres tipos de sistemas para traducir lenguajes de alto nivel:
Compiladores, Intrpretes y Compiladores Incrementales.

Los lenguajes de bajo nivel son una representacin del lenguaje mquina de forma que las personas
puedan trabajar con el. El Lenguaje Ensamblador es un lenguaje de bajo nivel, cuando usas un lenguaje
de bajo nivel, t tienes control directo sobre el procesador, otra ventaja es que los programas son ms
pequeos y ms rpidos.

Cuando trabajas con lenguajes de bajo nivel, el programa que traduce tu cdigo a lenguaje mquina es
llamado Ensamblador.



1.3 Lenguaje Ensamblador.

Un Ensamblador lee un programa en lenguaje ensamblador de bajo nivel y genera un programa
equivalente en lenguaje mquina.

Para programar en ensamblador debes conocer algunos aspectos extra: debes comprender no slo las
instrucciones que vas a usar sino tambin la arquitectura de la mquina, necesitas saber como se
almacenan los datos, como el procesador manipula los datos, etc.

Cuando programas en lenguajes de bajo nivel debes hacer ms que solo describir la solucin formal del
programa, debes dividir el programa en pasos pequeos y bsicos. Estos pasos le dirn al procesador que
hacer, una instruccin a la vez.



3
1.4 El Programador de lenguaje Ensamblador.

Para programar en cualquier lenguaje de computacin, necesitas buenas habilidades
organizacionales.
Fundamentalmente necesitas ser capaz de conceptuar un plan de accin basado en tiempo. Esto es, la
habilidad de tomar un problema y disear una solucin que involucre ejecutar ciertos pasos en cierto
orden.
Para programar en lenguaje ensamblador necesitas ms, debes tener una personalidad que disfrute atender
los detalles, y tener buenas habilidades aritmticas, en algunos casos debe tenerse mucha calma para
rastrear los problemas del cdigo (conocidos como bugs)
La recompensa de aprender y practicar con el lenguaje ensamblador es desarrollar una idea slida de
como opera una computadora, adems de escribir programas rpidos y pequeos para ejecutar tareas que
no son practicas (demasiado lentas) o no son posibles o demasiado complejas en lenguajes de alto nivel.

Los mejores programadores de ensamblador son obsesivos, esto no es necesario pero ayuda.



1.5 Procesadores y Coprocesadores.

Ya mencione anteriormente que el procesador es la parte de la computadora que hace casi todo el
trabajo. Las computadoras personales IBM y compatibles usan el procesador de la familia Intel 86 o un
procesador compatible de otra compaa, (ver tabla 1-1).

Los procesadores de la tabla 1-1 son de propsito general. Existen tambin coprocesadores matemticos
especiales que pueden ser usados para aumentar al procesador principal. Estos Coprocesadores ejecutan
operaciones matemticas, incluyendo aritmtica de punto flotante, y son extremadamente rpidos.

Los procesadores 486 y Pentium tiene un coprocesador matemtico nter construido, el cual es
funcionalmente equivalente a un 387. As puedes considerar un 486 como un mejorado 386 + 387 (en la
tabla 1-1, el tamao de las instrucciones no incluye las instrucciones matemticas).

Los Coprocesadores matemticos tienen su propio conjunto de instrucciones y requieren de una
programacin especial, para referencia la tabla 1-3 muestra el tamao de los varios conjuntos de
instrucciones matemticas.

Tabla 1-2 Procesador Coprocesador Math
8086/8088 8087
186 8087
286 287
386 387
486 ---
Pentium ---

Tabla 1-3 Coprocesador Tamao del conjunto de instrucciones
8087 77
287 74
387 80
486/487 80
Pentium 80


4




1.6 Programando para los Procesadores Intel 86

La Tabla 1-4 muestra el nmero de transistores en varios modelos del chip Intel 86. El nmero de
transistores de cada tipo de procesador se ha incrementado cuantitativamente, aunque es difcil definir lo
que significa un transistor, sin embargo, el nmero total de transistores es un buena indicacin de la
complejidad de un chip.

Programar en lenguaje Ensamblador en 386, 486 o Pentium es casi lo mismo que programar en el 8088.
Con cada nuevo procesador que Intel hace, se asegura que los programas hechos para los procesadores
anteriores funcionen. Esto significa que la computadora ms rpida y moderna puede correr los
programas escritos para la IBM PC original (la cual usaba el procesador 8086).

Tabla 1-4 Procesador Nmero aproximado Ao de Introduccin
de transistores
8086 29,000 1978
8088 29,000 1979
186 100,000 1982
286 134,000 1982
386 375,000 1985
486 1,200,000 1989
Pentium 3,100,000 1993

Una de las ms grandes limitantes de los primeros procesadores 8086, 8088, 186, era su incapacidad de
usar ms de 1 megabyte de memoria. El 286 resolvi ese problema operando en dos modos diferentes. En
modo real, una 286 acta como una 8086, 8088, o 186. El modo Real da la compatibilidad para todos los
programas de DOS que dependen de la arquitectura original de la 8088.

En modo protegido, la 286 ofrece tres funciones importantes: Primero, la 286 pude utilizar 16 megabytes
de memoria. Segundo, la 286 puede usar almacenamiento externo de disco para proveer 1 gigabyte de
memoria virtual, la cual es memoria simulada. Finalmente, el 286 ofrece hardware multitareas, la
habilidad de cambiar rpidamente de un programa a otro.

Infortunadamente, pocas personas podan tomar ventaja de las avanzadas facilidades del 286 debido a que
casi todos usaban DOS y DOS est basado en el viejo 8088. Esto significa que para propsitos prcticos,
se usaba el modo real y tenamos efectivamente rpidos 8088s.

El procesador 386 fue un importante cambio debido a su nueva facilidad aadida llamada modo virtual
86. Esto permiti al procesador correr ms de un programa DOS a la vez, cada uno de los cuales pensaba
que corra en sus propia mquina 8086. Adems, un 386 en modo protegido puede usar ms de 4
gigabytes de memoria real y ms de 64 terabytes de memoria virtual.

El 486 y Pentium combinan la funcionalidad de un 386 con un procesador matemtico nter construido
como tambin un controlador de cache (el cual controla la memoria especial de alta velocidad del
procesador). As desde el punto de vista de programacin, podemos considerar al 486 y al Pentium casi
iguales al 386.

5
Sin embargo todas las instrucciones extra que fueron adicionadas despus del 8088 son para programar en
modo protegido. A menos que t hagas software avanzado tal como un sistema operativo, un dispositivo
de driver o un compilador, no es factible que necesites esas instrucciones extra.
As casi todos los programadores en lenguaje ensamblador, programan para cualquier procesador de Intel
igual que como programaban para el 8086 original. Esto es especialmente cierto si t haces programas
para DOS.

1.7 Cuando usar el Lenguaje Ensamblador.

Te puedes preguntar: Cuando debo usar el Lenguaje Ensamblador y cuando puedo usar el Lenguaje
de alto nivel? Los lenguajes de alto nivel son menos detallados y ms conceptuales, y ellos deben ser tu
primera opcin la mayora de las veces. Comparados con los programas en lenguaje Ensamblador, los
programas de alto nivel son ms fciles de comprender y modificar. T slo debes usar ensamblador
cuando sea necesario.

La razn principal del porque usar ensamblador es si quieres hacer algo que es imposible o muy poco
prctico con un lenguaje de alto nivel. Debido a que el ensamblador te da control completo sobre el
procesador, puedes hacer cualquier cosa que la mquina sea capaz de hacer. Los lenguajes de alto nivel
no te dan este tipo de control.

La segunda razn del porque usar ensamblador es acelerar un programa lento. Los programas hechos con
lenguajes de alto nivel se ejecutan ms lentamente que sus equivalentes en ensamblador. El que tanto ms
rpido se ejecutan los programas depende de que tan bueno sea el compilador para generar cdigo en
lenguaje mquina eficiente.

En ciertas situaciones, necesitas acelerar cierta parte de un programa de alto nivel que es demasiado lento,
en este caso puedes analizar el programa para encontrar los puntos lentos. Como regla general, los
programas gastan el 90 % de su tiempo ejecutando el 10 % de las instrucciones. Usualmente estas
instrucciones son las que necesitan ser mejoradas. Si es posible manteniendo la mayora del programa
como alto nivel, rescribiendo partes seleccionadas en Lenguaje Ensamblador, y uniendo todas las piezas
juntas.

La tercera razn para usar Ensamblador es para disear programas tan pequeos como sea posible. Ahora
la memoria de la computadora es ms barata, y ahorrar espacio de memoria no es muy importante. Sin
embargo, cuando tienes que meter un programa en espacios de memoria pequeos, usar el ensamblador
es la mejor salida, puedes disear un programa que use menos espacio que uno generado por un
compilador.

La ltima razn para escoger Lenguaje Ensamblador es la ms importante: por diversin. Mucha gente
prefiere lenguaje Ensamblador a los lenguajes de alto nivel debido a que les divierte trabajar a nivel del
procesador.



1.8 El Sistema Operativo.

El sistema operativo es el control maestro de programas que corre la computadora. Como
programador en Lenguaje Ensamblador, puedes usar el sistema operativo de dos maneras:

Primero, sin importar que computadora uses, usas comandos que ejecuta el sistema
operativo: comandos para copiar archivos, iniciar un programa, listar un directorio,
etc.
6

Segundo, t llamas al sistema operativo dentro de tus programas para hacer ciertas
tareas; por ejemplo: entrada/salida, acceso al reloj, trabajar con archivos y directorios,
etc. Estas tareas pueden ser muy complicadas para hacerlas por ti mismo. De hecho,
puedes llamar al sistema operativo para que haga el trabajo por ti.

La mayora de nosotros usamos el sistema operativo DOS (Disk Operating System), si t estas
programando para Microsoft Windows, tambin puedes trabajar bajo DOS.



1.10 Desarrollo de un Programa en Ensamblador

Una vez que diseas un programa en Lenguaje Ensamblador, hay varios pasos que debes hacer antes
de poderlo ejecutar.
Primero debes meter el programa a la computadora. Para hacer esto, puedes usar un programa llamado
editor y salvar el programa a disco. Una vez que el programa esta almacenado en un archivo, usa un
Ensamblador para ejecutar la traduccin a lenguaje mquina. Sin embargo un programa en lenguaje
mquina no puede ser ejecutado directamente; este debe ser procesado por un enlazador. El enlazador
crea una forma de programa que est lista para ejecutarse. Tambin permite que hagas programas
separados que sern unidos juntos para ejecutarse como un todo (de ah el nombre enlazador).

Bajo DOS existen ciertas convenciones para nombrar a los archivos:

ASM Archivos de cdigo fuente.
OBJ Archivos producidos por la conversin de cdigo fuente a cdigo mquina.
EXE Archivos generados por el enlazamiento de archivos OBJ.

Por ejemplo si creas un programa fuente llamado TEST.ASM, el ensamblador lee el archivo, generando
un modulo objeto llamado TEST.OBJ y este a su vez puede ser ledo por el enlazador para generar el
programa ejecutable o el load module llamado TEST.EXE.

Cuando un programa esta totalmente terminado, puede ser probado bajo los auspicios de un debugger. Un
debugger es un programa que provee un ambiente para probar load modules. Usando un debugger, puedes
desplegar un programa, ejecutarlo una instruccin a la vez, ver los resultados de cada instruccin,
desplegar reas de la memoria, etc.



1.11 Que Software necesitas.

Sistema DOS en cualquier versin o Windows versin 3.x o 95.
Programa editor de textos. De preferencia el EDIT de DOS.
Programa MASM TASM (MacroAssembler TurboAssembler).
Programa LINK TLINK (enlazadores de MicroSoft Turbo).
Programa DEBUG.

Nota: No utilices editores de textos sofisticados (a menos que sea en modo texto), para teclear tus
programas ya que estos adicionan informacin extra a los archivos que ocasionan problemas al ensamblar
el cdigo fuente.


7

1.12 Que Conocimientos necesitas antes de empezar.

Hay ciertos prerrequisitos para programar en lenguaje Ensamblador:


Primero, debes conocer como utilizar el sistema operativo, no necesitas ser experto pero debes estar
familiarizado con las funciones bsicas, tales como manipulacin de archivos y uso de discos.

Segundo, debes conocer como usar t editor.

Tercero, debes tener alguna experiencia de programacin, no debes ser experto, pero debes tener alguna
idea de como usar la computadora para resolver problemas. Si no has programado antes mejor empieza
con un programa de alto nivel como Pascal C.

Finalmente, no debes escribir programas en Ensamblador a menos que comprendas la arquitectura y la
memoria de la computadora y la aritmtica hexadecimal, que se vern en los siguientes captulos.



{_____________o___________}































8







CAPITULO 2 SISTEMAS NUMERICOS


Nuevos Trminos.

Bit. Abreviacin de dgito binario. La unidad fundamental de almacenamiento de la memoria de la
computadora, un bit tiene uno de dos valores 1 0.

Byte. Una unidad de memoria que contiene 8 bits.

Word. Una unidad de memoria de contiene 16 bits (2 bytes).

Doubleword. Una unidad de memoria que contiene 32 bits (4 bytes, 2 words).

Quadword. Una unidad de memoria que contiene 64 bits (8 bytes, 4 words).

Paragraph (Prrafo). Una unidad de memoria que contiene 128 bits (16 bytes, 8 words).

ASCII. Abreviacin de Cdigo Estndar Americano para Intercambio de Informacin. Un cdigo
estndar, usado para almacenar caracteres de texto en la memoria, en la cual cada carcter est
representado por un patrn nico de 8 bits.

Sistema Decimal Base 10. Nuestro sistema aritmtico de todos los das, basado en 10 dgitos del 0 al 9.

Sistema Binario Base 2. Un sistema aritmtico usado por las computadoras, cuya base son los dgitos
0, 1.

Sistema Hexadecimal (Hex) Base 16. Un sistema aritmtico usado con las computadoras, que est
basado en 16 dgitos. Para representar 16 dgitos, el sistema hexadecimal usa 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A,
B, C, D, E, F.

Kilobyte K byte Kb. Una unidad de memoria que contiene 1024 bytes (2
10
).

Megabyte M byte MB. Una unidad de memoria que contiene 1,048,576 bytes (2
20
). 1 Mb contiene
1024 Kilobytes.



2.1 Bits y Bytes.

Para propsitos de programar en lenguaje ensamblador, piense en la memoria de la computadora
como en una secuencia larga de nmeros, 0s y 1s. Por ejemplo:


100100110110010111001001000100010011101011...
9


Cada 0 y 1 es llamado un bit, las computadoras almacenan informacin como una secuencia larga de bits,
cada grupo de 8 bits es llamado un byte. Existen otras agrupaciones, como se puede ver en la tabla 2-1.



Tabla 2-1 Nmero de bits Nombre
8 Byte
16 Word (2 bytes)
32 Doubleword (4 Bytes)
64 Quadword (8 bytes)
128 Paragraph (16 bytes)



2.2 Como son almacenados los caracteres.

Si una computadora slo puede almacenar secuencias largas de 0s y 1s Como puede almacenar
informacin diferente a esa? Existen varias maneras. El texto, el cual es informacin consistente de
caracteres, es representado por un cdigo.
Como sabemos, cada byte contiene 8 bits y cada uno de estos bits puede ser un 0 un 1; entonces hay 2
8

256 posibilidades diferentes. Esto es, existen slo 256 patrones diferentes.
Estos 256 patrones son usados para formar un cdigo. Un patrn es un smbolo. Por ejemplo la letra A
es 01000001; el patrn para la letra Q es 01010001.
Este conjunto de patrones, con todos los caracteres que lo forman es llamado American Standard Code
for Information Interchange, o ASCII.
As, si quieres decodificar una cadena larga de bits, hay que dividirlos en grupos de 8 para ver que
patrones forman.



2.3 El Sistema Binario.

Si la computadora slo almacena 0s y 1s, tiene sentido que la aritmtica que la computadora usa
este basado en estos nmeros. Nosotros utilizamos normalmente el sistema decimal sin embargo la
computadora utiliza el sistema binario o base 2.
Como en el sistema decimal nosotros podemos representar un cadena de nmeros posicionales donde
cada nmero representa la multiplicacin de ese dgito con una potencia de 10 de derecha a izquierda. En
el sistema binario es exactamente lo mismo slo que se utiliza una potencia de 2.
Cuando usamos ms de un sistema numrico debemos indicar que sistema estamos usando cada vez que
escribimos un nmero, por convencin dentro del ensamblador se utiliza una B al final de cada nmero
binario, ejemplo:

1000 (mil en decimal)
1000B (8 en binario)

La Tabla 2-2 muestra los nmeros decimales del 0 al 15. A un lado de cada nmero decimal esta su
equivalente en binario:

Tabla 2-2 Decimal Binario
0 0
10
1 1
2 10
3 11
4 100
5 101
6 110
7 111
8 1000
9 1001
10 1010
11 1011
12 1100
13 1101
14 1110
15 1111



2.4 El Sistema Hexadecimal.

La principal ventaja del sistema binario es que nos permite trabajar con nmeros exactamente como
son almacenados, es decir, como 0s y 1s. Sin embargo hay un inconveniente con el binario, que lo hace
muy difcil de utilizar. La razn es que es mucho ms largo que sus nmeros decimales equivalentes; y
adems, las cadenas de 0s y 1s son muy confusas.
Por ejemplo, puedes comprender inmediatamente la ecuacin:

125 + 75 = 200

Sin embargo en binario, quedara escrito como sigue:

1111101B + 1001011B = 11001000B

Obviamente necesitamos un sistema que sea compacto (como el decimal) y que pueda ser usado para
trabajar con los valores de la memoria (como el binario). El sistema hexadecimal, o base 16 tiene esas
caractersticas.
Hexadecimal, o Hex, es un sistema que usa 16 dgitos. Debido a que slo tenemos diez smbolos para
dgitos (0 al 9), usaremos las letras A, B, C, D, E, y F como los otros seis dgitos. En hex, la A es el
diez, B el once, etc. La tabla 2-4 muestra los equivalentes en decimal, binario y hexadecimal.
Cuando escribimos nmeros en hexadecimal, ponemos una H al final para reconocerlos, por ejemplo
12H.

La tabla 2-3 muestra algunas equivalencias entre decimales y hexadecimales.


Tabla 2-3 Decimal Hex
10 A
15 F
100 64
500 1F4
2730 AAA
65536 10000

11

Tabla 2-4 Decimal Binario Hex
0 0 0
1 1 1
2 10 2
3 11 3
4 100 4
5 101 5
6 110 6
7 111 7
8 1000 8
9 1001 9
10 1010 A
11 1011 B
12 1100 C
13 1101 D
14 1110 E
15 1111 F



2.5 Medidas del tamao de la Memoria.

Las computadoras manejan datos en bytes, no en bits. Por eso, cuando describes el tamao de la
memoria, dices cuantos bytes contiene. Debido a que la computadora tiene miles o millones de bytes, se
usan trminos como kilobytes megabytes. El prefijo kilo y mega esta tomado del sistema mtrico que
significa mil o un milln. Sin embargo mil o un milln no son nmeros redondos en el sistema binario.
De hecho, usamos 1024 (2
10
) y 1048576 (2
20
).

De esta manera 64 kilobytes no significa 64000 bytes; sino 64x1024 (65536) bytes. El prefijo kilo se
abrevia K y el prefijo Mega se abrevia M. Una relacin que debes recordar siempre es que 1024 K bytes
son 1 Mega.



2.6 Conversin entre Hexadecimal y Binario.

El sistema hexadecimal es importante debido a que proporciona un modo compacto de representar
largas cadenas de bits. En la tabla 2-5 se encuentran los primeros 16 nmeros hexadecimales y sus
equivalentes en binario, note que cada nmero binario esta formado por slo 4 dgitos, adicionando ceros
cuando sea necesario (Por supuesto adicionar ceros a la izquierda de un nmero no altera su valor).

Podemos representar cualquier secuencia de dgitos binarios por una secuencia ms pequea de dgitos
hex, por ejemplo 00001111B es igual a 0FH.

El siguiente es un ejemplo que convierte el nmero binario 10011010110101101B a hex. Primero
dividimos la cadena de derecha a izquierda en grupos de 4 bits:

1 0011 0101 1010 1101

Despus adicionamos 3 ceros al grupo de ms a la izquierda para tener 4 bits.

12
0001 0011 0101 1010 1101

Tabla 2-5 Hex Binario
0 0000
1 0001
2 0010
3 0011
4 0100
5 0101
6 0110
7 0111
8 1000
9 1001
A 1010
B 1011
C 1100
D 1101
E 1110
F 1111

Ahora usemos la tabla 2-5 para encontrar el dgito equivalente en hex para cada grupo:

0001 0011 0101 1010 1101
1 3 5 A D

As vemos que 10011010110101101B es 135AD en hex.

Similarmente si queremos convertir un nmero hexadecimal a binario todo lo que necesitamos es
reemplazar cada dgito hexadecimal por su equivalente de 4 bits. Por ejemplo para convertir 72AD2EH a
binario. Primero escribimos cada dgito separado.

7 2 A D 2 E

Luego usamos la tabla y escribimos el equivalente nmero de 4 bits debajo del dgito en hex.

7 2 A D 2 E
0111 0010 1010 1101 0010 1110

Ahora, ponemos los bits juntos para formar el nmero binario, entonces 72AD2EH es
11100101010110100101110B en binario.

Mencione antes que puedes considerar a la memoria de la computadora como una larga secuencia de bits.
Sin embargo como puedes ver, las cadenas de bits se pueden convertir fcilmente a dgitos en
hexadecimal (y viceversa). Entonces es ms correcto decir que la memoria de la computadora puede ser
considerada como una secuencia de dgitos hex.



2.7 Conversin de Hexadecimal a Decimal.

Debes aprender a convertir entre decimal y hex y de hex a decimal, porque la gente maneja decimal
pero la computadora almacena la informacin en hex.
13
Para convertir de hex a decimal, necesitas recordar la posicin de cada dgito. Por ejemplo, considera el
nmero decimal 50786. Este tiene el valor:

5x10000 + 0x1000 + 7x100 + 8x10 + 6

5x10
4
+ 0x10
3
+ 7x10
2
+ 8x10
1
+ 6x10
0


Si quieres encontrar el valor decimal de un nmero en hexadecimal, puedes hacer lo mismo que acabas de
ver pero usando potencias de 16, por ejemplo el nmero AD65H expresando en potencias de 16 es:

Ax16
3
+ Dx16
2
+ 6x16
1
+ 5x16
0


Recordando los valores de los dgitos en hexadecimal expresados con letras podemos sustituir lo anterior
por:

10x16
3
+ 13x16
2
+ 6x16 + 5 = 10x4096 + 13x256 + 6x16 + 5 = 44389

En general, el procedimiento para convertir de hex a decimal es como sigue:

1. Separe cada dgito hexadecimal y coloque de derecha a izquierda la potencia de 16 adecuada
empezando desde cero.

2. Sustituya los dgitos A, B, C, D, E, F por los valores en decimal apropiados.

3. Haga las operaciones correspondientes.



2.8 Conversin de Decimal a Hex.

Para convertir de decimal a hexadecimal, debes dividir el nmero decimal entre 16 repetidamente.
Los residuos te darn los dgitos hexadecimales, leyndolos de derecha a izquierda. Por ejemplo convierta
14855 de decimal a hex:

Cociente Residuo
14855 / 16 928 7
928 / 16 58 0
58 / 16 3 10
3 / 16 0 3

Ahora se escriben todos los residuos de abajo hacia arriba de izquierda a derecha, sustituyendo los
valores de 10, 11, 12..etc., por A, B, C..etc.

14855 = 3A07H

Este es el procedimiento general para convertir de decimal a hex:

1. Divida el nmero decimal entre 16 repetidamente hasta que el cociente sea 0.

2. Para obtener los dgitos en hexadecimal, escriba abajo los residuos, de derecha a izquierda.

3. Si cualquiera de los residuos es 10, 11, 12, 13, 14 15, cmbielos por A, B, C, D, E F
14
respectivamente.






2.9 Conversin de Binario a Decimal.

Existen dos maneras de convertir un nmero binario en decimal. La primera es convertir el nmero
binario a hex y luego el nmero en hex a decimal. Como ejemplo, convirtamos 10110011B a decimal.
Primero convertiremos a hex separando los bits en grupos de 4:

1011 0011

Bajo cada grupo, escribimos el equivalente nmero hexadecimal:

1011 0011
B 3

Entonces, 10110011B es igual a B3H en hex. Ahora expresemos B3H como la suma de los dgitos
multiplicndolo por la potencia de 16 apropiada (recuerde cambiar la B por 11):

11x16 + 3

Evaluando lo anterior obtenemos el resultado en decimal, 179.

El segundo mtodo para convertir de binario a decimal es hacer lo anterior directamente como lo hicimos
para el hexadecimal. Expresemos el nmero binario como la suma de los dgitos multiplicando por las
potencias de 2 apropiadas. As para evaluar la expresin 10110011B tenemos:

1x2
7
+ 0x2
6
+ 1x2
5
+ 1x2
4
+ 0x2
3
+ 0x2
2
+ 1x2
1
+ 1x2
0


o lo que es lo mismo:

1x128 +0x64 + 1x32 + 1x16 + 0x8 + 0x4 + 1x2 + 1 = 179.



2.10 Conversin de Decimal a Binario.

Existen dos formas de convertir de decimal a binario. Primero, conviertes el nmero decimal a hex y
despus a binario. Por ejemplo suponga que quiere convertir 23406 a binario. Para convertirlo a hex,
dividimos repetidamente entre 16:

Cociente Residuo
23406 / 16 1462 14
1462 / 16 91 6
91 / 16 5 11
5 / 16 0 5 = 5B6EH

15
Para convertir el nmero hexadecimal 5B6EH separamos cada dgito hex y encontramos su equivalente
en binario:

5 B 6 E
0101 1011 0110 1110 = 101101101101110B

La segunda forma para convertir de decimal a binario es usar el mismo mtodo de divisin para convertir
a hexadecimal, slo debemos dividir repetidamente entre 2 en lugar de entre 16. Con este mtodo
los residuos son escritos de abajo hacia arriba y de izquierda a derecha, dndonos el nmero binario
directo:

Cociente Residuo
23406 / 2 11703 0
11703 / 2 5851 1
5851 / 2 2925 1
2925 / 2 1462 1
1462 / 2 731 0
731 / 2 365 1
365 / 2 182 1
182 / 2 91 0
91 / 2 45 1
45 / 2 22 1
22 / 2 11 0
11 / 2 5 1
5 / 2 2 1
2 / 2 1 0
1 / 2 0 1 = 101101101101110B



2.11 Sumando en Hexadecimal.

Algunas veces necesitaras sumar o restar dos nmeros hexadecimales. Por supuesto puedes convertir
ambos nmeros de hex a decimal calcular el resultado y regresar la respuesta a hex. La figura 2-6
contiene la tabla de adicin hex.

Tratemos de sumar 28A70H ms 90B6H como ejemplo. Escribimos los nmeros como en una suma
normal:

28A70
+ 90B6


Sumamos cada columna de derecha a izquierda. Primero 0H + 6H = 6H

28A70
+ 90B6
6

A continuacin, 7H + BH es igual a 12H. Escribimos 2 bajo la segunda columna y tenemos un acarreo de
1.

16
1
28A70
+ 90B6
26

Ahora, AH + 0H + 1H es igual a BH. Escribimos B bajo la tercera columna.


28A70
+ 90B6
B26

Despus, 8H + 9H igual a 11H. Escribimos un 1 y acarreamos un 1.

1
28A70
+ 90B6
1B26

Finalmente, 2H + 1H es igual a 3.

28A70
+ 90B6
31B26

Tabla 2-6 Adicin en Hex

0 1 2 3 4 5 6 7 8 9 A B C D E F
0 0 1 2 3 4 5 6 7 8 9 A B C D E F
1 1 2 3 4 5 6 7 8 9 A B C D E F 10
2 2 3 4 5 6 7 8 9 A B C D E F 10 11
3 3 4 5 6 7 8 9 A B C D E F 10 11 12
4 4 5 6 7 8 9 A B C D E F 10 11 12 13
5 5 6 7 8 9 A B C D E F 10 11 12 13 14
6 6 7 8 9 A B C D E F 10 11 12 13 14 15
7 7 8 9 A B C D E F 10 11 12 13 14 15 16
8 8 9 A B C D E F 10 11 12 13 14 15 16 17
9 9 A B C D E F 10 11 12 13 14 15 16 17 18
A A B C D E F 10 11 12 13 14 15 16 17 18 19
B B C D E F 10 11 12 13 14 15 16 17 18 19 1A
C C D E F 10 11 12 13 14 15 16 17 18 19 1A 1B
D D E F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C
E E F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D
F F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E



2.12 Substraccin en Hex.

Para restar en hexadecimal necesitas la habilidad de encontrar la diferencia entre dos nmeros. La
figura 2-7 muestra la tabla de substraccin en hex.

17
Los nmeros a la izquierda representan el nmero ms grande. Los nmeros de arriba representan los
nmeros ms pequeos. Para hacer una resta, primero busque el rengln y luego la columna.
Por ejemplo cuanto ser FH - 8H = 7H

Para restar nmeros grandes, use la misma metodologa que para restar decimales. Por ejemplo reste
DB4H - 2A1H:


DB4
- 2A1
B13

Aqu hay un ejemplo ms complicado; suponga que quiere restar 74AH - 2EFH:

74A
- 2EF

Para empezar debe restar FH de AH -pero FH es ms grande que AH. Proceda justo como lo hara
normalmente. Adicione 1 a AH (borrow) para convertirlo en 1AH. Ahora calcule 1AH - FH lo cual es
igual a BH

74A
- 2EF
B

Ahora, necesita calcular 4H - EH - 1H (el borrow). De nuevo existe un prstamo; esta vez necesita
cambiar 4H a 14H. Calcule 14H - EH - 1H. El resultado es 5H bajo la segunda columna.

74A
- 2EF
5B

Finalmente, calcule 7H - 2H - 1H (el borrow). La respuesta es 4H.

74A
- 2EF
45B















18








Tabla 2-6 Tabla de substraccin en hex

0 1 2 3 4 5 6 7 8 9 A B C D E F
0 0
1 1 0
2 2 1 0
3 3 2 1 0
4 4 3 2 1 0
5 5 4 3 2 1 0
6 6 5 4 3 2 1 0
7 7 6 5 4 3 2 1 0
8 8 7 6 5 4 3 2 1 0
9 9 8 7 6 5 4 3 2 1 0
A A 9 8 7 6 5 4 3 2 1 0
B B A 9 8 7 6 5 4 3 2 1 0
C C B A 9 8 7 6 5 4 3 2 1 0
D D C B A 9 8 7 6 5 4 3 2 1 0
E E D C B A 9 8 7 6 5 4 3 2 1 0
F F E D C B A 9 8 7 6 5 4 3 2 1 0
10 10 F E D C B A 9 8 7 6 5 4 3 2 1
11 11 10 F E D C B A 9 8 7 6 5 4 3 2
12 12 11 10 F E D C B A 9 8 7 6 5 4 3
13 13 12 11 10 F E D C B A 9 8 7 6 5 4
14 14 13 12 11 10 F E D C B A 9 8 7 6 5
15 15 14 13 12 11 10 F E D C B A 9 8 7 6
16 16 15 14 13 12 11 10 F E D C B A 9 8 7
17 17 16 15 14 13 12 11 10 F E D C B A 9 8
18 18 17 16 15 14 13 12 11 10 F E D C B A 9
19 19 18 17 16 15 14 13 12 11 10 F E D C B A
1A 1A 19 18 17 16 15 14 13 12 11 10 F E D C B
1B 1B 1A 19 18 17 16 15 14 13 12 11 10 F E D C
1C 1C 1B 1A 19 18 17 16 15 14 13 12 11 10 F E D
1D 1D 1C 1B 1A 19 18 17 16 15 14 13 12 11 10 F E
1E 1E 1D 1C 1B 1A 19 18 17 16 15 14 13 12 11 10 F
1F 1F 1E 1D 1C 1B 1A 19 18 17 16 15 14 13 12 11 10




{____________o___________}




19









CAPITULO 3 LA ORGANIZACION DE LA MEMORIA

Como programador de lenguaje ensamblador, debes tener una idea firme de como est organizada la
memoria de la computadora. En este capitulo aprenders acerca de las unidades fundamentales de la
memoria y como se almacenan. Aprenders tambin dos conceptos importantes del lenguaje
ensamblador, los Registros y la Pila.


Nuevos Trminos.

Direccin. El nmero asignado a un byte, que indica su posicin en la memoria; el primer byte tiene una
direccin 0.

Parte baja de la Memoria. En la memoria, son aquellos bytes que estn cercanos al byte 0.

Parte alta de la Memoria. En la memoria, son aquellos bytes cercanos al byte con la direccin ms alta.

Bits ms significativos Bits de ms alto orden. Los bits de ms a la izquierda en un byte.

Bits menos significativos Bits de menor orden. Los bits ms a la derecha en un byte.

Limite. Una direccin que es un mltiplo de un nmero especifico.

Limite Word. Una direccin que es un mltiplo de 2.

Alineado (a un limite). Describe a un byte cuya direccin es un lmite especfico.

Limite Doubleword. Una direccin que es mltiplo de 4.

Limite Quadword. Una direccin que es mltiplo de 8.

Limite Paragraph. Una direccin que es un mltiplo de 16.

Memoria Primaria. Memoria con que el procesador puede trabajar directamente.

Memoria Secundaria. Memoria con que el procesador no puede trabajar directamente. La memoria
secundaria reside en los discos.

Read Only Memory ( ROM ). Memoria primaria que puede ser leda pero no cambiada.

Random Access Memory ( RAM ). Memoria primaria, tambin llamada de lectura-escritura, que puede
ser leda y modificada.

20
Registro. Uno de los 14 words de memoria lectura-escritura nter construida en el procesador.

Acumulador. Otro nombre del registro AX.

Registro Base. Otros nombres de los registros BX BP.

Registro Contador. Otro nombre del registro CX.

Registro de Datos. Otro nombre del registro DX.
Cargar ( Load ). Copiar un dato a un registro.

Almacenar ( Store ). Copiar datos del contenido de un registro.

Pila ( Stack ). Una estructura de datos que te permite almacenar y recuperar datos de manera last-in, first-
out, (el ltimo que entra es el primero en salir).

Vaca ( Empty ). Describe una pila que no contiene informacin.

Meter ( Push ). Almacenar un dato en la pila.

Sacar ( Pop ). Recuperar un dato de la pila.

Tope de la pila ( Top ). La locacin en la pila que contiene el ltimo campo del dato que fue metido.

Procedimiento, Funcin o Subrutina. Un modulo auto contenido, tambin llamado una funcin o una
subrutina, que es una parte de un programa grande.

Llamada a un procedimiento. Empezar a ejecutar un procedimiento.

Regreso de un procedimiento. Cuando un procedimiento se termina, para continuar ejecutando el
programa que lo llamo.

Direccin de regreso. La locacin a que un procedimiento regresa cuando este termina.



3.1 Direcciones de Memoria.

La memoria de la computadora esta organizada en bytes. Todos los bytes estn numerados
empezando desde 0. El nmero de un byte es llamado su direccin. Cuando el procesador necesita leer un
byte, este manda la direccin de la memoria, la memoria regresa entonces la informacin en ese byte al
procesador. Entonces cuando el procesador necesita escribir un byte, este manda dos seales a la
memoria: la direccin del byte y la informacin a ser escrita. La memoria copia la informacin al byte
especfico.

Los bytes cercanos al byte 0 se conocen como la parte baja de la memoria. Los bytes cercanos a la ms
alta direccin son llamados parte alta de la memoria. Piensa que los bytes estn acomodados en orden,
uno hasta arriba de los otros, con el byte de la direccin 0 hasta abajo.

Te puedes referir a un byte con su direccin. Cuando te refieras a una palabra (word), doble palabra
(doubleword), palabra cudruple (quadword), o prrafo (paragraph), puedes usar la direccin de su primer
byte. Por ejemplo, si dices que una palabra esta almacenada en las locaciones 10926H y 10927H, te
21
puedes referir a ellas como la doble palabra en 10926H. Se asume que el segundo byte est en la
direccin de ms arriba.



3.2 Como son almacenadas las Palabras ( words ).

Los viejos procesadores podan transferir de 1 a 2 bytes a la vez, pero los 386 y 486 pueden
transferir ms de 4 bytes a la vez.
Cuando los bytes son escritos a la memoria, estos son almacenados de manera recta. Sin embargo, cuando
las palabras son escritas a la memoria, los dos bytes de cada palabra son almacenados en orden inverso.
Aqu hay un ejemplo digamos que tu programa escribe una palabra que contiene 1234H en la direccin de
la memoria 500H. Los dos bytes de la palabra son almacenados en 500H y 501H. Podras esperar que la
informacin fuera almacenada como:

4FEH 4FFH 500H 501H 502H 503H


Sin embargo, estn actualmente almacenadas como:

4FEH 4FFH 500H 501H 502H 503H


De los detalles se encargan automticamente la memoria y el procesador. Cuando el procesador necesita
una palabra, sabe cambiar el orden de los bytes que recibe.

La nica vez que tienes que preocuparte acerca del orden de los bytes es cuando usas un debugger para
desplegar un rea de la memoria. En tales casos debes mantener en mente que las palabras estn
almacenadas con los bytes en orden inverso.

Si los datos estn almacenados como bytes esto si estn en el orden normal.



3.3 Como estn almacenados los Bits.

Un byte es la unidad ms pequea que puede ser almacenada o recuperada de la memoria. El nico
modo de trabajar con un bit es acceder al byte en el cual el bit esta contenido. Para hacer esto hay
instrucciones especiales que te permiten examinar y cambiar bits particulares.

En un byte, el orden de los bits es especialmente importante, por esta razn tenemos un modo estndar de
referirnos a cada bit, los bits estn numerados desde el 0 al 7, iniciando por la derecha. La figura 3-1
muestra un byte que contiene el cdigo ASCII de la letra D.


Figura 3-1


7 6 5 4 3 2 1 0
22



Los bits de ms a la izquierda son llamados los ms significativos y los de ms a la derecha son los menos
significativos. Cuando almacenas informacin todos los bits son importantes.


3.4 Limites.

En el capitulo 2 explique como los bits se agrupan en bytes, palabras, palabras dobles, palabras
cudruple y prrafos. Como sabemos la memoria de la computadora consiste de muchos bytes. La
direccin del primer byte es 0H, la del segundo 1H y as. Algunas veces los datos necesitan ser
almacenados de manera que empiecen en algn tipo de direccin particular, llamado un limite
(boundary). Un lmite es una direccin que es el mltiplo de un nmero especfico.

Todas las direcciones que tiene un lmite de 2 se dice que tiene lmite de una palabra. Dicho de otra
forma, empezando con la direccin 0H, cada segundo byte en la memoria tiene como limite una palabra.
Si el primer byte de algn dato esta en una direccin limite hexadecimal, podemos decir que el dato esta
alineado con el limite de la palabra (esto es, el dato inicia en el limite de la palabra). Por ejemplo, el dato
que inicia en la locacin 108A6H esta alineado con el limite de una palabra (acaba en par); los datos que
inician en 108A7H no estn alineados con el limite palabra.

Similarmente, cada cuatro bytes, empezando desde 0H, decimos que es el lmite de una palabra doble.
Los lmites de las palabras dobles son direcciones que finalizan en 0H, 4H, 8H, o CH. Para continuar con
la analoga los lmites de palabras cudruples son direcciones que finalizan en 0H o 8H; los lmites de un
prrafo terminan siempre en 0H. Ocasionalmente cierto tipo de datos deben de estar alineados a un lmite
particular. Algunas veces el ensamblador lo hace automticamente pero otras tendrs que hacerlo t
mismo.
Como referencia, la tabla 3-2 tiene los lmites de las direcciones de memoria.

Tabla 3-2 Lmites de alineacin

Limite Definicin La direccin finaliza en...
Word Cada 2 bytes 0H, 2H, 4H, 6H, 8H, AH, CH, EH
Doubleword Cada 4 bytes 0H, 4H, 8H, CH
Quadword Cada 8 bytes 0H, 8H
Paragraph Cada 16 bytes 0H



3.5 Memoria Primaria y Secundaria.

Generalmente cada computadora tiene dos tipos de memorias: memoria primaria y secundaria. Los
procesadores pueden trabajar directamente slo con la memoria primaria, la cual es la memoria que
es
almacenada en pequeos chips incluidos en los circuitos de la tarjeta en la computadora.

Una computadora personal utiliza dos tipos de memoria chip. Read-Only Memory (ROM), que puede ser
leda pero no puede ser cambiada. La ROM es usada para mantener datos importantes que estn definidos
para ella. Estos datos no desaparecen cuando la computadora se apaga.
23

Los chips Read-Write Memory, proveen memoria que puede ser leda y cambiada, estos chips son
usualmente llamados random-access memory (RAM).

La RAM es usada para mantener en la memoria primaria lo que usa la computadora. Cuando usas un
programa de computadora, debes preparar ciertas reas de la memoria para almacenar datos. Cuando
corres un programa, las instrucciones con sus propias reas de datos deben ser cargadas dentro de la
RAM por el sistema operativo.



La memoria secundaria reside en los discos. El procesador no puede acceder directamente a este tipo de
memoria. Antes de que los datos puedan ser usados, estos deben ser ledos a la memoria primaria. Cuando
trabajes con datos en discos debes leer la informacin a un rea de la memoria primaria que t apartas
cuando diseas tu programa. Similarmente, el procesador no puede escribir directamente a los discos,
debes transferir los datos de un rea de la memoria.

Por conveniencia, cuando use el trmino memoria significar memoria primaria.



3.6 Registros.

Debe parecer un poco lento el que el procesador trabaje slo con la memoria primaria, cada byte a
ser usado debe ser transferido y regresado. Sin embargo hay una pequea cantidad de memoria construida
dentro del procesador. Esta memoria consiste de 14 palabras de memoria read-write. Cada una de estas
palabras es llamada un registro y cada registro tiene su propio nombre y propsito.

La tabla 3-3 es una lista de los registros y sus abreviaciones. Como podemos ver los registros caen en tres
categoras: Registros generales, registros de desplazamiento y registros de segmento.

Tabla 3-3 Los registros.

Nombre Abreviacin Categora
Acumulador AX (AH, AL) Registro General
Registro Base BX (BH, BL) Registro General
Registro Contador CX (CH, CL) Registro General
Registro de Datos DX (DH, DL) Registro General
Apuntador Base BP Registro de Desplazamiento
Apuntador de Instruccin IP Registro de Desplazamiento
Apuntador de Pila SP Registro de Desplazamiento
ndice Destino DI Registro de Desplazamiento
ndice Fuente SI Registro de Desplazamiento
Registro de Segmento de Datos DS Registro de Segmento
Registro de Segmento Extra ES Registro de Segmento
Registro de Segmento de Pila SS Registro de Segmento
Registro de Segmento Cdigo CS Registro de Segmento
Registro de Banderas (ninguno) (ninguno)



3.7 Lo Registros Generales.
24

Existen cuatro registro generales: AX, BX, CX y DX. Estos registros ofrecen un almacenamiento
temporal muy conveniente para cualquier tipo de informacin. Ellos son usados especialmente para
aritmtica, debido a que los registros estn construidos dentro del procesador, las instrucciones que los
usan se ejecutan de manera ms rpida que las instrucciones que utilizan la memoria regular.
Puedes usar estos registros como desees. Sin embargo AX, BX y CX tambin tienen propsito especiales.

AX es el registro principal usado para instrucciones aritmticas (tambin puedes usar los otros registros
generales). AX puede ser usado para guardar el resultado de un clculo. Por esta razn algunas veces es
llamado acumulador.

BX (tambin BP) algunas veces es llamado registro base, debido a que pude ser usado para mantener una
direccin base.

CX es usado con ciertas instrucciones para ejecutar operaciones repetitivas. En tales casos, CX debe
contener el nmero de veces que quieres repetir una operacin. As CX, es considerado como el registro
contador.

DX es llamado registro de datos porque es usado para mantener datos para propsitos generales.

Cuando copias informacin al registro, Cargas datos dentro del registro. As se pueden almacenar datos.
Todos estos registros contienen 2 bytes (16 bits), puedes cargar y almacenar 2 bytes a la vez. Sin
embargo, a veces es necesario cargar y almacenar slo 1 byte a la vez. El procesador permite hacer esto
reconociendo nombres alternativos para estos registros. Estos nombres alternativos se refieren a una
mitad del registro.

Los nombres alternativos para el registro AX, son AH y AL. La H y L significan High y Low.
AH se refiere a la parte alta del registro AX; AL se refiere a la parte baja de ese registro. Puedes acceder
al registro completo usando AX, o la parte izquierda o derecha usando AH o AL.

De hecho, si decimos que AX contiene 1234H, AH contiene 12H, y AL contiene 34H. Si cargas 00H a
AH, AX contendr 0034H. Como se muestra en la siguiente figura:

AX AX

AH AL AH AL

Puedes tener el mismo acceso para los registros BX, CX y DX.



3.8 La Pila.

Una pila es una estructura de datos que te permite almacenar y recuperar informacin de manera
last-in, first-out. Casi todos los programas en ensamblador utilizan una pila, as que al principio de cada
programa debe tener algunas instrucciones para dar de alta a la pila.

25
Cuando tu programa inicia, la pila no tiene datos en ella, Nosotros podemos decir que la pila esta vaca.
Cuando usas la pila para almacenar un dato se dice que haces un push a la pila. Cuando recuperas
este dato, haces un pop fuera de la pila. Existen instrucciones especiales para hacerles push y pop a los
datos.

Cuando hace un pop de dato, este es removido de la pila. Como parte del pop puedes especificar a donde
va a ir el dato que sacaste. Por ejemplo podras hacer un pop al registro AX.

Piense que la pila es una pila de platos de una cafetera. Haces push a los platos uno a la vez para
colocarlos en la pila de platos, y cuando necesitas un plato haces un pop de un plato a la vez. El plato al
que le hiciste un pop siempre es el ltimo que colocaste en la pila. La locacin de almacenamiento que
contiene el ltimo campo con dato que fue puesto en la pila se conoce como el tope (top) de la pila.

La figura 3-3 muestra un ejemplo, que ilustra las operaciones de push y pop a la pila. El ejemplo inicia
con una pila vaca en la cual se hace un push al nmero 10 y 87, despus se le hace un pop al tope de
la pila


Para recuperar el 87, se le hace un nuevo push a la pila con un valor de 68, y despus dos pop para
recuperar los nmeros 68 y 10 respectivamente.

Tabla 3-3 Un ejemplo del uso de la pila

push push pop push pop pop
10 87 68


Cuando escribes un programa, debes instruir al ensamblador para apartar un espacio para la pila. Cada
entrada de la pila es de 1 palabra (2 bytes) y la pila puede tener una longitud de 64K bytes. As la pila
puede mantener 32K (32768) entradas. En otras palabras, puedes hacer un push a 32768 palabras de datos
a la pila.

Usualmente, no es necesario tener una pila tan grande. Sin embargo, puedes escoger el tamao que sea
ms adecuado. Como regla general si no estas seguro del espacio que necesitas, aparta 256 palabras
(200H bytes). Los programadores que trabajan con programas pequeos dejan slo 128 palabras (100H
bytes).



3. 9 Como es usada la Pila.

La pila esta diseada para mantener informacin temporalmente. Esto es especialmente importante
cuando estas trabajando con procedimientos. Muchos programas de tamao medio y grande estn
separados en mdulos auto contenidos llamados procedimientos. (En lenguajes de alto nivel estos se
conocen como funciones o subrutinas). Cuando un procedimiento invoca a otro procedimiento, decimos
que el primero llama al segundo. Cuando el segundo procedimiento termina, el programa regresa al
primer procedimiento en la siguiente instruccin despus de la llamada.

26
Como parte de la ejecucin de una instruccin de llamada, el procesador debe salvar la locacin dentro
del primer procedimiento en el cual continuar cuando el otro procedimiento termine. Esta
locacin es conocida como la direccin de regreso.

El procesador salva la direccin de regreso ponindola en la pila. Cuando el segundo procedimiento
termina, el procesador saca la direccin de regreso de la pila y contina con la ejecucin en esa locacin.
Debido a la estructura de la pila un procedimiento puede llamar a otros y esos otros a otros y siempre se
regresar a la locacin correcta.

Otro uso importante de la pila es salvar el contenido de los registros antes de llamar a un procedimiento.
Antes de que el procedimiento regrese los registros pueden ser restaurados sacando los viejos valores de
la pila, esto permite a los procedimientos hacer un uso libre de los registros.

La pila tambin puede pasar informacin de un procedimiento a otro. Un procedimiento puede poner sus
datos en la pila (parmetros) y entonces el segundo procedimiento acceda a los datos. Si es necesario, el
segundo procedimiento podra usar la pila para devolver datos tambin.

Un uso final de la pila es mantener resultados temporalmente sobre todo para operaciones complejas.
Cada mtodo a escoger varia dependiendo de la lgica de un programa especifico.


{____________o___________}






























27


















CAPITULO 4 TIPOS DE DIRECCIONAMIENTO

En este capitulo aprenders a apreciar ms la arquitectura de los procesadores de la familia Intel 86,
y tambin las varias maneras de referirse a las locaciones de memoria en un programa.
Este tpico, el direccionamiento es muy complejo, si eres un principiante te recomiendo leer este capitulo
ms de una vez. La primera vez lee todo como esta y trata de absorber tanto como puedas, no te
preocupes por comprender todo. Despus una vez que inicies a hacer tus primeros programas vuelve a
leerlo con calma.


Nuevos Trminos.

Direccin efectiva. Una direccin completa de 20 bits.

Direccin de Segmento. Un nmero de 20 bits que contiene el valor base desde el cual una direccin
efectiva es calculada.

Offset. Un nmero de 16 bits que es adicionado a una direccin de segmento para calcular una direccin
efectiva.

Segmento. Un rea de la memoria, con ms de 64 Kb de longitud, que contiene una parte del programa.

Registro de Segmentos. Un registro que contiene los 16 bits ms significativos de una direccin de
segmento; uno de los registros CS, SS, DS o ES.

Segmento de Cdigo. Un segmento que contiene las instrucciones mquina de un programa.

Segmento de Datos. Un segmento que contiene los datos usados por el programa.

Segmento Extra. Un segundo segmento que contiene datos usados por el programa.

Segmento de Pila. Un segmento que contiene a la pila que usa el programa.

Direccionamiento Directo. Una direccin en la cual es desplazamiento esta indicado directamente.
28

Direccionamiento Indirecto. Una direccin en la cual el desplazamiento esta especificado por el valor
de un registro.

ndice. Usado para calcular un offset adicionando un valor (llamado un desplazamiento) a una locacin
fija (llamada la direccin base).

Direccin Base. Una locacin fija que sirve como una base para calcular un offset.

Desplazamiento. Un valor que adicionado a la direccin base nos da un offset.

Registro ndice. Un registro que contiene un desplazamiento; uno de los registros DI o SI.






4.1 El esquema bsico de Direccionamiento en la PC.

Las instrucciones mquina trabajan con direcciones de hasta 16 bits. Esta es una limitante en el
modo real que DOS usa. As, las posibles direcciones son desde 0000H hasta FFFFH
(0000000000000000B a 1111111111111111B). Esto da como resultado 10000H (64K) direcciones
diferentes. Es otras palabras, usando un esquema de este tipo, el procesador slo tiene hasta 64K de
memoria disponible.

Pero 64K no es mucha memoria, si tuviramos que construir programas con slo 64K estaramos
severamente limitados, As que es imperativo que el procesador pueda accesar ms memoria.

La solucin es ingeniosa, pero algo complicada. Es importante que comprendas este esquema, as que lee
la siguiente seccin con cuidado.

Vamos a hacer una analoga. Suponga que tiene un robot con un brazo mecnico que puede mover y que
tiene un largo de 64 pulgadas. Si el robot esta en un cuarto fijo en un lugar, el brazo slo puede alcanzar
los objetos que estn a 64 pulgadas de distancia mxima. Sin embargo si el robot se pudiera mover por el
cuarto, el brazo podra alcanzar cualquier objeto. Si un objeto no esta dentro de las 64 pulgadas del brazo
lo nico que tiene que hacer el robot es moverse ms cerca.
En otras palabras, piense que si el brazo del robot tiene una distancia 64 pulgadas, puede tomar cualquier
objeto en el cuarto estableciendo una base a 64 pulgadas del objeto.

El procesador de Intel tiene un esquema parecido. Si bien una direccin de 16 bits puede accesar slo
64K bytes, se puede usar una muy grande cantidad de memoria considerando la direccin de 16 bits como
la direccin base relativa. Para accesar otros 64 K diferentes, todo lo que hay que hacer es mover la base.

Dentro de un programa, la direccin consiste de dos partes: una direccin de segmento y un offset. La
direccin de segmento es un nmero de 20 bits que corresponde a la posicin base del robot. El
desplazamiento es un nmero de 16 bits que corresponde al brazo movible.

La direccin actual es llamada la direccin efectiva. Para calcular la direccin efectiva, todo lo que tienes
que hacer es sumar el offset al la direccin de segmento.

29
Aqu hay un ejemplo: Digamos que la direccin de segmento es 50000H y el offset es 62A3H. La
direccin efectiva es 50000H + 62A3H, lo cual es igual a 56A3H.
Ahora, si el segmento de direccin es 50000H y el desplazamiento puede tomar los valores desde 0000H
hasta FFFFH, la direccin efectiva varia desde 50000 hasta 5FFFFH. As, con un segmento de direccin
de 50000H, puedes accesar los 64K (10000H) bytes de memoria que empiezan en 50000H.

Suponga que quiere accesar algunos datos de la direccin 8726BH. Esta direccin no esta en el mismo
rango, as que necesitas cambiar de segmento con sus 64K que este entre 8726H. Por ejemplo, podras
cambiar la direccin de segmento a 80000H y usar un offset de 726BH.

Actualizando la direccin de segmento apropiadamente, puedes accesar cualquier byte en una memoria
grande. Asegurndote que el byte este dentro de los 64K del segmento de direccin.

El hardware calcula la direccin efectiva de modo que el resultado siempre es un nmero de 20 bits. As
la direccin efectiva puede tener un rango desde 00000H hasta FFFFFH. Esto da 100000H posibles
direcciones.

En otras palabras usando una combinacin de direccin de segmento y offsets, el procesador puede
direccionar ms de 100000H bytes de memoria. Esto es igual a 1024K bytes o 1 Megabyte, mucho mejor
que slo 64K.
Es importante comprender que diferentes combinaciones de direcciones de segmento y desplazamientos
puede dar la misma direccin efectiva. De hecho los pares de direcciones de segmentos y
desplazamientos en la tabla 4-1 dan la misma direccin especifica 8726BH.

Tabla 4-1 Direcciones de Segmento Offset Direccin efectiva
80000H + 726BH = 8726BH
87000H + 026BH = 8726BH
87260H + 000BH = 8726BH
85AD0H + 179BH = 8726BH

De los detalles se encargan automticamente el procesador y el ensamblador.



4.2 Segmentos y Registros de Segmento.

Para poder implementar el esquema de direcciones explicado en el punto anterior, el procesador
requiere que todos los programas sean divididos en segmentos. Un segmento es un rea de memoria de
ms de 64K., si necesitas disear un programa largo, debes dividirlo en piezas donde cada pieza quepa en
un segmento. Cuando escribes un programa, existen ciertas instrucciones del ensamblador que indican
donde empieza y termina cada segmento.

Cuando el programa se ejecuta, el procesador mantiene una direccin de segmento para cada segmento.
Estas direcciones son mantenidas para los registros CS, DS, ES y SS.

Un programa puede tener varios segmentos, pero slo cuatro pueden estar activos a la vez. Los cuatro
segmentos estn estandarizados; y se conocen como segmento de cdigo, segmento de datos, segmento
extra y segmento de pila. Todas las direcciones usadas para un segmento dado usan el registro de
segmento como base.

El segmento de cdigo es la parte del programa que contiene las instrucciones mquina actuales (algunas
veces llamadas cdigo). El registro CS contiene la direccin de segmento de ese segmento.
30

El segmento de datos es la parte del programa que contiene los datos. El segmento extra tambin puede
ser usado para almacenar datos, si es necesario. El registro DS contiene la direccin del segmento de
datos; el registro ES contiene la direccin de registro del segmento extra

El segmento de pila contiene a la pila, el registro SS, contiene la direccin del segmento de pila.

Todos los programas deben tener al menos un segmento de cdigo y un segmento de pila. Estrictamente
hablando, los segmentos de datos y extra son opcionales, pero la mayora de los programas tienen
tambin un segmento de datos.



4.3 Como son usados los Registros de Segmento.

Como sabes todas las direcciones tiene dos partes: la direccin de segmento y el offset. En un
programa escribes una direccin especificando las dos partes separadas por dos puntos. La primera parte
es el nombre del registro de Segmento.

Por ejemplo, digamos que quieres referirte a informacin en el segmento de datos. Si el desplazamiento
de la informacin es 6AH, puedes escribir la direccin como DS:6AH. Para referirte al segmento extra
con un desplazamiento de 1A5H, escribes ES:1A5H.

Cuando el programa se ejecuta el procesador adiciona el offset al contenido del registro de segmento para
obtener la direccin efectiva. As si la direccin es DS:6AH, el procesador adiciona 6AH al contenido de
DS.

Por supuesto, este esquema slo trabaja si cada registro de segmento tiene su propio valor. As es como
pasa: Antes de que un programa sea ejecutado, este debe ser copiado a la memoria, este proceso es
llamado carga, y es realizado por el sistema operativo, cuando un programa es cargado este se copia a un
rea de la memoria que este actualmente disponible. Este automticamente fija las direcciones que el
programa usar.

Cuando escribes un programa no sabes que direcciones tendr. De hecho cada vez que un programa corre,
los segmentos pueden ser cargados en locaciones diferentes. Sin embargo es importante que un registro
de segmento sea inicializado con un valor apropiado si el programa va a correr correctamente.

Como parte del proceso de carga, el sistema operativo inicializa los registros CS y SS para apuntar al
principio del cdigo y la pila, respectivamente. As, las instrucciones (el segmento de cdigo) y la pila
son accesados automticamente.

Debido a que no todos los programas tiene segmento de datos o segmento extra, el sistema operativo no
inicializa automticamente los registros DS y ES. Esto debes hacerlo t mismo, hasta que lo hagas, los
datos es esos segmentos no estarn accesibles. Afortunadamente, todas las inicializaciones requieren
pocas instrucciones estndar que colocas al inicio de cada programa.



4.4 El contenido del Registro de Segmento.

31
Como mencione antes, el registro de segmento contiene la direccin de un segmento. La direccin
de segmento debe tener al menos 20 bits, pero todos los registros tienen slo 16 bits. Como puede
contener un registro de 16 bits, 20 bits?

La solucin es asumir que el registro contiene slo los 16 bits ms significativos de la direccin y
asumimos que los otros 4 bits son todos ceros. En otras palabras, si cada direccin de segmento es de 5
dgitos hex (20 bits), un registro de segmento contiene slo los primeros 4 dgitos hex; el ltimo dgito
hex se considera como 0H.

Aqu hay un ejemplo: Digamos que el sistema operativo carga el segmento de cdigo en 217A0H y el
segmento de pila en 1F8A0H. El registro CS estar dado por el valor 217AH y el valor del registro SS es
1F8AH. En cada caso debes extender los valores por 0H (0000B) para obtener la verdadera direccin de
segmento.

Como puedes ver, asumiendo que todas las direcciones de 20 bits terminan en 0H, slo necesitas
almacenar los primeros 16 bits de cada uno. La carga de los segmentos es hecho por el ensamblador y el
sistema operativo y los segmentos siempre estarn alineados al limite de un prrafo.

La nica vez que necesitas preocuparte acerca de todo esto es cuando calculas una direccin efectiva.
Cuando lo hagas recuerda adicionar el valor extra 0H al valor del registro de segmento para obtener la
verdadera direccin de segmento.
Veamos como hacerlo. Digamos que estas usando un debugger y quieres examinar algunos datos en el
segmento de datos. El offset es 17A5H y el valor de DS es 20ABH. Primero escribe el valor del registro
de segmento:

20ABH

Despus adiciona 0H al valor para obtener la direccin de segmento verdadera.

20AB0H

Finalmente adiciona el offset a la direccin de segmento:

20AB0H
+17A5H
22255H

Puedes instruir al debugger para desplegar los datos en esa direccin.



4.5 Como es implementada la Pila.

La imagen de los platos en la cafetera es buena para aprender como trabaja el concepto de una pila,
pero su implementacin es un poco diferente, esto es debido a que no es posible mover todos los datos
hacia arriba o hacia abajo cada vez que metemos o sacamos un elemento. En su lugar, la pila es manejada
con un segmento con dos registros especiales.

El registro SS siempre contiene la direccin de segmento de la pila. El sistema operativo pone ese valor
cuando el programa se carga. Cuando el programa se ejecuta, el registro SS permanece sin
cambios (a menos que se use un registro de pila diferente).

32
El registro SP (apuntador de pila) contiene un offset que apunta al tope de la pila. Esto es, en cualquier
caso, la direccin efectiva del tope de la pila estar formada por los contenidos de los registros SS y SP.

La pila esta organizada como una lista con entradas de 16 bits (2 bytes). El registro SS apunta a la
direccin ms baja de la lista. La primera instruccin push coloca datos en la entrada con la direccin ms
alta, la siguiente instruccin push coloca datos en la entrada con la siguiente direccin ms alta, y as.
Todas las veces, el registro SP apuntar al ltimo dato que fue metido (el tope de la pila).

En otras palabras, la pila inicia desde la direccin ms alta y crece hacia abajo hasta su base. La figura 4-
1 muestra un diagrama de la pila que fue cargada en 10000H. La pila tiene una longitud de 200H (512
bytes).

En este ejemplo, dos campos son empujados a la pila, el campo nombrado data1 fue empujado primero,
en la locacin 101FEH. El campo nombrado data2 fue metido en segundo en 101FCH. Note que cada
dato ir quedando ms cerca de la base de la pila. Actualmente la direccin base o registro SS contiene
1000H y el registro SP contiene 01FCH.






Figura 4-1 La Pila


En general, esto es lo que pasa cuando un dato es introducido a la pila.

1. SP es decrementado en 2 para apuntar a la siguiente locacin libre.

2. El campo a ser metido es copiado al offset especificado por SP.

Esto pasa cuando un dato es sacado de la pila:

1. El campo al que SP apunta es copiado a la locacin apropiada.

2. SP es incrementado en 2 para apuntar a la siguiente entrada de la lista.

En el ejemplo anterior el registro SP esta inicializado a 200H. EL primer push decrementar SP a 01FEH
antes de almacenar el data1, si todos los campos en la pila son sacados y la pila esta vaca SP apuntar de
nuevo a 0200H.



4.6 Direccionamiento Directo.

33
Dentro de un programa puedes referirte a locaciones de memoria especficas. Para acceder esas
locaciones de memoria, el procesador necesita conocer la direccin del segmento y el offset. Puedes
escribir esta informacin especificando el nombre del segmento y un offset, separado por dos puntos.

Por ejemplo, para especificar la locacin en el segmento de datos que tiene un offset de 10AH, puedes
escribir

DS:10AH

Como es un poco problemtico referirte a los desplazamientos usando nmeros, el ensamblador te
permite usar nombres. Cuando creas el segmento de datos y el segmento extra, dejas un espacio para los
datos que usaras, as puedes asignarle nombres a esos campos de datos.

El ensamblador mantiene una tabla con cada nombre y su desplazamiento. Cuando usas una instruccin
refirindose a un nombre, el ensamblador lo substituye por su desplazamiento actual. As cuando te
refieres a un campo dato, se dice que usas un direccionamiento directo.
Por ejemplo, digamos que el nombre SUM tiene un desplazamiento de 10AH en el segmento de datos.
Puedes referirte a esa locacin como

DS:SUM


Lo bueno de esto, es que no tienes que rastrear su desplazamiento actual por ti mismo.

Muchas de las veces, puedes simplificar las cosas an ms. Cuando haces referencia a una locacin de
memoria, el procesador asume que est en el segmento de datos a menos que especifiques otra cosa. As
puedes referirte a la locacin slo como:

SUM

Tiene que especificar un registro de segmento si el dato no est en el segmento de datos. Por ejemplo, si
SUM estuviera en el segmento extra, debes hacer referencia a la locacin como:

ES:SUM



4.7 Direccionamiento Indirecto.

Algunas veces, quieres usar un desplazamiento que esta en un registro. Para hacer referencia a esa
locacin, debes especificar el nombre del registro encerrado entre parntesis cuadrados.

Por ejemplo, digamos que el registro SI contiene 1000H, si una instruccin contiene

SI

Se refiere al valor en SI, llamada 1000H. Sin embargo, si la instruccin contiene

[SI]

34
Este se refiere al dato en el offset 1000H. En otras palabras, cuando un registro esta encerrado entre
parntesis cuadrados, este representa al dato en el desplazamiento contenido en el registro, esto es
llamado direccionamiento indirecto.

Cualquiera de los registros SP, BP, BX, SI, y DI pueden ser usados para direccionamiento indirecto.
Muchas de las veces, no es necesario especificar un registro de segmento debido a que el procesador
asume uno.

Cuando usas SP o BP, el procesador asume que el desplazamiento se refiere al segmento de pila y usa el
registro de segmento SS. Cuando usas BX, SI, y DI, el procesador asume que te refieres al segmento de
datos y usa el registro de segmento DS. As no es necesario especificar el registro a menos que quieras
suprimir el default.

Por ejemplo, digamos que BX contiene el offset de datos del segmento extra, t puedes usar

ES:[BX]

Hay una excepcin importante a estas reglas. Cuando usas una instruccin que mueve strings, el
procesador asume que el registro DI contiene un desplazamiento al segmento extra.

Los defaults implcitos para los registros de segmentos se muestran en la tabla 4-2



Tabla 4-2 Registro Registro de segmento implcito
[SP] SS
[BP] SS
[BX] DS
[SI] DS
[DI] DS (ES con instrucciones para strings)



4.8 Direccionamiento Indexado.

Algunas estructuras de datos consisten de ms de una sola parte. Por ejemplo, un arreglo
unidimensional puede ser considerado como una lista de datos. Una tabla bidimensional puede
considerarse como renglones y columnas.

En todos los casos, los datos actuales estn almacenados como una secuencia de bytes, palabras, dobles
palabras, etc. Sin embargo, cuando usas esos datos, ayuda darles un orden. De hecho, cuando usas un
arreglo es conveniente pensar que el arreglo completo tiene un slo nombre y campos separados son los
elementos del arreglo.

Para hacer esto, tienes la facilidad de utilizar una indexacin. La indexacin permite hacer referencia a
campos relativos a una locacin fija. De hecho puedes accesar cada elemento del arreglo relativo por su
inicio. Esta locacin fija es llamada la direccin base.

Considere un arreglo de 100 elementos que existe en el segmento de datos como 100 bytes consecutivos.
Cada byte contiene un elemento. El nombre del arreglo es LIST. Estrictamente hablando, LIST es el
desplazamiento del primer byte. As puedes accesar el primer elemento del arreglo usando

35
LIST

Si quieres accesar otros elementos, el ensamblador te permite adicionar valores al nombre. Por ejemplo,
para accesar el siguiente elemento puedes especificar

LIST+1

El nmero que adicionas a la direccin base es llamada un desplazamiento, en el ltimo ejemplo, el
desplazamiento fue de 1. Puedes accesar cualquier elemento del arreglo usando el desplazamiento
apropiado. Aqu hay algunos ejemplos.

LIST+57
LIST+82
LIST+99

No hay un desplazamiento dado para el primer elemento del arreglo, dando un desplazamiento de 1
obtenemos el segundo elemento, y as. Si hay cien elementos, el rango de desplazamientos va desde 0 a
99. El desplazamiento mximo de n elementos es n-1. Otro modo de verlo es que empezamos a contar
desde cero. Por eso, LIST+57 nos da el elemento 58.

Por supuesto estos desplazamientos funcionan en arreglos consistentes de bytes. Considere un arreglo
llamado BIGLIST consistente de 100 palabras. Cada palabra ocupa 2 bytes, los desplazamientos relativos
a los elementos son como sigue:

Primer elemento BIGLIST
Segundo elemento BIGLIST+2
Tercer elemento BIGLIST+4
.
.
.
Ultimo elemento BIGLIST+198



4.9 Los Registros ndice.

Ocasionalmente, necesitas accesar los elementos de la estructura de datos adicionando un
desplazamiento constante a un offset, por ejemplo LIST+4. Sin embargo, es ms til usualmente
almacenar el desplazamiento en un registro. Los registros SI y DI son usados para este propsito y son
algunas veces referidos como el registro ndice.

Por ejemplo, considera el arreglo LIST consistente de 100 bytes. Decimos que el programa necesita una
referencia cada elemento en turno, desde el primero hasta el ltimo. Puedes variar el contenido de SI
desde 0 hasta 99 y usar.

LIST[SI]

Note dos cosas: primero, cuando usas un registro para mantener un desplazamiento, debes indicar al
ensamblador el nombre del registro entre parntesis cuadrados, igual a cuando usas un direccionamiento
indirecto.

36
Segundo, necesitas adicionar un + antes del nombre del registro. La expresin anterior significa el valor
de del registro SI adicionado al desplazamiento de LIST.

En el ejemplo anterior, puede indexar cualquier elemento de LIST actualizando SI al valor apropiado. De
hecho, para accesar todos los elementos del ltimo al primero, vara SI de 99 hasta 0; para accesar el
elemento 57, pon SI a 56.

Ahora considera el arreglo BIGLIST, el cual consiste de 100 palabras. Digamos que quieres indexarla
usando el registro DI.

BIGLIST[DI]

Cada elemento de BIGLIST es de 2 bytes de longitud, debes actualizar a DI de acuerdo al tamao. Por
ejemplo, para accesar todos los elementos del primero al ltimo, cambia a DI a 0, 2, 4, 6... 198. Para
accesar el elemento 57, pon DI a 112, para accesar el elemento n, pon DI a (n-1) x 2.

Si necesitas manejar palabras dobles, debes manejar el ndice en mltiplos de 4; con palabras cudruples,
mltiples de 8.

En lenguajes de alto nivel esto lo hacen por ti, en lenguaje ensamblador, debes hacer esto t mismo.





4.10 Los Registros Base: El registro BX.

En la seccin previa, los ejemplos usaban el nombre para almacenar la locacin como una direccin
base. Puedes tambin utilizar un registro para mantener una direccin base. BX es usada para este
propsito en el segmento de datos; BP es usada por la pila. Estos registros son algunas veces
mencionados como los registros base.

Por ejemplo, puedes indexar el arreglo LIST usando

LIST[DI]

Si pones el desplazamiento de LIST en BX, puedes usar

[BX][DI]

Como puedes ver, el registro base esta encerrado en parntesis cuadrados. (Note que el ltimo ejemplo
usa direccionamiento indirecto.)

Usando un registro para mantener la direccin base es til si quieres accesar ms de una estructura de
datos con la misma instruccin. Por ejemplo, puedes tener un programa que procese varios arreglos. Todo
lo que tienes que hacer es poner a BX al desplazamiento de cada arreglo en turno y entonces usar DI o SI
para mantener el desplazamiento.

Por ejemplo, digamos que tienes dos arreglos llamados LIST1 y LIST2. Para accesar al primer arreglo,
pon BX a LIST1; para accesar el segundo pon BX a LIST2.
Para estructuras ms complicadas, el ensamblador permite usar un nombre, una direccin base, y un
desplazamiento, por ejemplo:
37

TABLE[BX][SI]

El contenido de ambos registros es adicionado al desplazamiento del campo de datos. De hecho, si BX
mantiene un 20 y DI mantiene un 4, el ejemplo anterior tiene el valor

TABLE+24

La ventaja de esta doble indexacin es permitirte establecer una direccin base dentro de una estructura
de datos. Por ejemplo, digamos que TABLE es una tabla de bytes, almacenada rengln por rengln. Hay
30 renglones y cada rengln tiene 100 elementos; esto es, TABLE tiene 30 renglones y 100 columnas.

Puedes poner a BX apuntando a un rengln particular y usar DI o SI para indexar a travs de los
elementos de ese rengln. En este caso, cada rengln tiene 100 bytes. El primer rengln consiste del byte
0 al 99; el segundo rengln del byte 100 a 199; y as. Para accesar el elemento 57 del rengln 18,
ponemos BX a 1700 y SI a 56, y usamos

TABLE[BX][SI]

Esto podra ser lo mismo que

TABLE+1756

Si usas una estructura de datos que mantiene elementos ms grandes de un byte, puedes ajustar la
indexacin de acuerdo al tamao. Por ejemplo, si TABLE mantiene palabras en lugar de bytes, los
renglones empezaran en 0, 200, 400, etc.



4. 11 Los Registros Base: El registro BP.

Muchas veces, el direccionamiento en una pila es manejado con los registros SS y SP. SS mantiene
el registro de direccin y SP mantiene el offset del tope de la pila. Cuando usas una pila haciendo pushs
y pops, el procesador actualiza SP automticamente y te permite accesar la informacin en el tope de la
pila.

Sin embargo, algunas veces quieres accesar informacin dentro de la pila. En este caso, usas el registro
BP para mantener una direccin base en la pila.

Por ejemplo, digamos que tienes dos procedimientos llamados A y B. El procedimiento A pasa
informacin a B, y llama al procedimiento B. Si la cantidad de informacin es pequea, esta puede ser
pasada en uno o varios de los registros generales. Sin embargo si necesitas pasar ms informacin una
estrategia es que el procedimiento A empuje la informacin en la pila antes de llamar al procedimiento B.

As, tan pronto como el procedimiento B inicia, este puede obtener informacin para accesar la pila. Sin
embargo, el procedimiento B no puede hacer esto de manera directa. Ciertamente, el procedimiento B
puede empujar datos por si mismo. Esto hace difcil rastrear la locacin de la informacin que fue
empujada por el procedimiento A.

La solucin esta en el procedimiento B, tan pronto como toma el control, pude salvar el offset del tope de
la pila en BP. En otras palabras, la primera cosa que el procedimiento B debe hacer es copiar el contenido
38
de los registros SP o BP. Esto significa que no importa que tipo de informacin sea metida en la pila, los
datos del procedimiento A pueden ser accesados usando el contenido de BP como una direccin base.

Por ejemplo, digamos que el procedimiento A mete 10 palabras de informacin en la pila. Cuando el
procedimiento B inicie, la primera cosa que har es salvar el desplazamiento del tope de la pila copiando
su contenido al SP o al BP. Ahora el procedimiento B puede accesar la diez palabras, a su conveniencia,
desde SS:BP hasta SS:BP+18. (Recuerde que 10 palabras ocupan 20 bytes). Por ejemplo la segunda
palabra puede ser accesada como

SS:BP+2

En cualquier punto dentro del procedimiento B. Piense que esto se refiere a la palabra que esta dos bytes
ms all del tope de la pila cuando el procedimiento B empez.

Para hacer las cosas fciles, siempre que uses a BP como el registro base, el procesador asume que BP
contiene un offset en el segmento de pila y automticamente utiliza SS como el registro de segmento. En
el ejemplo anterior tambin podra usar

BP+2






4.12 Regla generales para especificar una direccin.

Cuando especificas una direccin directa, usas el nombre de campo dato y un registro base,
registro ndice, o desplazamiento constante opcional.

Aqu hay algunos ejemplos:

TABLE
TABLE[SI]
TABLE[DI]+8
TABLE[BX][SI]+8

Cuando especificas una direccin indirecta, puedes usar SP, BP, BX, SI o DI. Con BP o BX, puedes usar
SI DI como ndice. Con todos los direccionamientos indirectos, puedes usar un desplazamiento
opcional. Veamos algunos ejemplos.

[BP]
[SI]
[BX][DI]
[SI]+4
[BP][DI]+4

Con un direccionamiento directo o indirecto, no puedes usar ms de un registro base ni ms de un registro
ndice.

El ensamblador te permite especificar los valores indexados de varias maneras, sujetas a las siguientes
reglas:
39

- Los valores ndices pueden estar en cualquier orden

- Los nombres de registros deben ir entre parntesis cuadrados

- Puedes combinar nombres de registros y desplazamientos constantes en un conjunto de parntesis
cuadrados si los separas con +.

- Si pones un desplazamiento constante enfrente de un nombre de registro, no necesitas usar un +.

Aqu hay varias direcciones directas equivalentes que ilustran estas reglas.

TABLE[BX][SI]+8
TABLE[BX+SI+8]
TABLE[8+SI+BX]

Aqu hay varias direcciones indirectas equivalentes.

[BP][SI]+12
12[BP][SI]
12[BP+SI]




Obviamente, la mejor idea es tomar un patrn y utilizarlo. Te recomiendo los siguientes patrones. Para la
direccin directa, usa

nombre[base][indice]+constante

por ejemplo :

TABLE[BX][SI]+8

Para un direccionamiento indirecto, usa

[base][indice]+constante

por ejemplo :

[BP][DI]+8



4.13 Direccionamiento con el Segmento de Cdigo.

Un programa puede tener cuatro segmentos activos: el segmento de cdigo, el segmento de pila, el
segmento de datos, y el segmento extra. De estos cuatro, solo el segmento de cdigo no puede ser
modificado o explcitamente accesado mientras el programa es ejecutado. El segmento de cdigo no
puede ser accesado porque es el contenido de las instrucciones actuales del programa.

40
La direccin en el segmento de cdigo es hecha automticamente por el procesador con los registros CS e
IP. El registro CS contiene la direccin de segmento del segmento de cdigo. El registro IP contiene el
offset de la siguiente instruccin a ser ejecutada. Cuando cada instruccin se ejecuta, el registro IP es
actualizado apuntando a la siguiente instruccin en el programa.

Cuando el programa cambia la secuencia de instrucciones, el procesador actualiza el registro IP
apropiadamente. Por ejemplo, cuando un procedimiento llama a otro procedimiento, el desplazamiento
del otro procedimiento es colocado en IP. Si el segundo procedimiento esta en un segmento diferente, el
registro CS debe ser actualizado tambin. Esto tambin lo realiza el procesador cuando llama una
instruccin CALL.

El direccionamiento dentro de un segmento de cdigo es automtico, puedes ignorar los registros CS e IP
muchas de las veces. Sin embargo, son importantes cuando usas un debugger para probar un programa. Si
ejecutas un programa una instruccin a la vez, puedes examinar CS e IP para mantener el rastreo. Si algo
falla, puedes usar a CS e IP para ayudarte a determinar la direccin de la instruccin que causo el error.


{_____________o___________}








CAPITULO 5 LAS PARTES ATOMICAS DE UN PROGRAMA EN ENSAMBLADOR


Los programas en lenguaje ensamblador son ms complejos que los de alto nivel. Cada programa en
ensamblador tiene parte diferentes que debes comprender. En este capitulo aprenders las diversas partes
y las reglas para crearlas. Este material es bsico y debes dominarlo para escribir tus programas.


Nuevos Trminos

Programa Principal. Dentro de un programa, es el primer procedimiento a ejecutarse.

Estatuto. Una lnea de un programa en ensamblador.

Comentario. Todas las partes de un estatuto que son ignorados por el ensamblador; los comentarios son
usados para mantener informacin descriptiva.

Instruccin. Un estatuto que puede ser traducido a lenguaje mquina.

Directiva Pseudo-operacin. Un estatuto que da instrucciones al ensamblador.

Opcode. La parte de una instruccin o directiva que identifica una operacin especifica.

Operando. La parte de una instruccin o directiva que representa el valor sobre el cual la instruccin o
directiva acta.

41
Tabla de smbolos. Una tabla de nombres creada por el ensamblador para procesar un programa.

Referencia forward. En un programa, la aparicin de un nombre, que no ha sido definido an.

Nombre reservado. Una palabra a la cual el ensamblador asigna un significado especial; las palabras
reservadas no pueden ser usadas como nombres.



5.1 Como ve el programador un programa.

Como programador piensa que el programa tiene dos partes -instrucciones y datos. Las instrucciones
describen la lgica y los datos es el material sobre el que actan las instrucciones. Cuando veas un
programa puedes hacerte las siguientes preguntas Que hace este programa (instrucciones)? Con qu
trabaja el programa (datos)?

La parte de instrucciones de un programa consiste de uno o ms procedimientos (o subrutinas). El primer
procedimiento a ejecutar es llamado el programa principal. Un programa pequeo podra consistir solo
del programa principal y los datos. Un programa grande consiste de datos y de varios procedimientos.



5.2 Como ve el ensamblador un programa.

Cuando t ves un programa que consiste de instrucciones y datos, el ensamblador ve un programa
fuente consistente de una secuencia de estatutos, uno por lnea. El ensamblador lee esos estatutos (dos o
ms veces), y genera un programa en lenguaje mquina consistente de segmentos.

Este programa en lenguaje mquina debe conocer los requerimientos del procesador, estos requerimientos
son altamente tcnicos y detallados. Afortunadamente el ensamblador y el Linker se encargan de la
mayora de esos detalles.

Esto significa que, desde el punto de vista del programador el ensamblador es un conjunto de estatutos
que tiene oscuros significados de lo que hace un programa. Esto es el porque los programas en
ensamblador son ms difciles de comprende que los de alto nivel. T defensa contra esta confusin es
desarrollar bueno hbitos de programacin.

La conexin entre tu punto de vista del programa y el del ensamblador es que las instrucciones estn
contenidas en el segmento de cdigo. S tu programa tiene ms de un procedimiento, todos estos estarn
contenidos dentro del segmento de cdigo. La parte de datos estar contenida en los segmentos de pila,
datos y extra.



5.3 Como ve el programa el Linker.

El linker no ve el programa como una entidad conceptual o como una secuencia de estatutos. En su
lugar, el linker ve uno o ms archivos que contienen mdulos. El trabajo del linker es usar estos archivos
para crear un slo archivo que contenga un modulo ejecutable.

Por conveniencia, puedes mantener un conjunto de mdulos objeto en una coleccin llamada una librera.
El linker buscar la librera y extraer los mdulos objeto particulares que especifiques.
42



5.4 Que pasa durante el proceso de Ensamblamiento.

Piense que el ensamblador lee el programa lnea por lnea. Algunas lneas son instrucciones y otras
son requerimientos para definir datos.

El ensamblador crea el modulo objeto, byte por byte. Si una lnea en el programa fuente contiene una
instruccin, el ensamblador genera la instruccin mquina equivalente y lo adiciona al modulo objeto. Si
la lnea especifica un requerimiento de dato, el ensamblador adiciona el nmero apropiado de bytes (para
almacenar el dato) al modulo objeto. As, el orden de las instrucciones y las reas de datos en el modulo
objeto depende del orden en el cual el ensamblador encuentra las lneas del programa.



5.5 Comentarios.

Los programas en lenguaje ensamblador consisten de una secuencia de estatutos. Aqu hay tres tipos
de estatutos: comentarios, instrucciones y directivas.

Los comentarios son partes de estatutos que son ignorados por el ensamblador. Puedes usar los
comentarios para incluir descripciones, en el programa. Los comentarios son partes importantes del
programa ya que en posiciones claves de tu programa sirven como guas maestras del significado y
propsito del programa.

Hay varias maneras de incluir comentarios. La primera es que cualquier estatuto diferente del blancos que
este despus de un punto y coma es considerado un comentario e ignorado por el ensamblador.

; Este es un comentario

Segundo, puede adicionar un comentario al final de una instruccin o directiva marcando el comentario
con un punto y coma. La siguiente instruccin pone le valor 99 en el registro AX:

MOV AX,99 ; Aqu hay un comentario

En general la regla es esta: mientras procesa una lnea el ensamblador ignora todo lo que este despus de
un punto y coma. Hay una excepcin, ocasionalmente el programa pondr caracteres con comillas
simples o dobles. En estos casos, el punto y coma no define comentarios, como en el siguiente ejemplo.

Hola; adis
Hola; adis



5.6 Instrucciones y Directivas.

En general, una instruccin es un estatuto que pude ser traducido a lenguaje mquina. Una directiva
es un estatuto que le dice que hacer al ensamblador. Las directivas no pueden ser traducidas a lenguaje
mquina; sin embargo, son necesarias para que un programa se ensamble apropiadamente.

43
Consideremos algunas ejemplos que ilustran esta distincin. Veamos las siguientes dos instrucciones. La
primera adiciona el contenido del registro BX al contenido del registro AX. La segunda copia el
contenido de AX a la locacin de memoria llamada SUM.

ADD AX,BX
MOV SUM,AX

Lo que siguen son dos directivas. La primera le dice al ensamblador que aparte un byte de memoria y le
de el nombre SUM. La segunda le dice al ensamblador que empieza el segmento llamado CSEG.

SUM DB 1
CSEG SEGMENT

Existen muchas instrucciones y directivas en el ensamblador, y al principio es difcil diferenciarlas, sin
embargo si quieres aprender a diferenciarlas pregntate si generan una instruccin en lenguaje mquina o
si le dan una orden al ensamblador. (Por supuesto tambin puedes ver el manual).

La ventaja es que las directivas te dan un control sobre las cosas que estn pasando. Esto es
especialmente importante si escribes programas sofisticados. La desventaja es que cada directiva requiere
una lnea separada, la cual tiende a obscurecer el diseo lgico del programa.



5.7 El formato de los estatutos del lenguaje Ensamblador.

Las reglas del lenguaje ensamblador dependen del ensamblador que uses. Aqu hay algunas reglas
generales:
Cada lnea contiene solo un estatuto.

Un estatuto puede empezar donde sea en una lnea.

Puedes usar maysculas o minsculas como desees.

Las instrucciones y directivas tienen un formato ms estructurado. Cada uno de estos tipos de elementos
tiene tres partes: un nombre, un opcode y un operando(s). Las tres partes siempre deben estar en este
orden, y ellas deben estar separadas por lo menos con un espacio.
Aqu hay un ejemplo de un par de estatutos de un programa:

; actualizar el total
NEWSUM LABEL NEAR
MOV AX,TOTAL
ADD AX,SUBTOTAL
PUSH AX

Los programadores se refieren a un estatuto por su opcode. De hecho, en el ejemplo anterior, puedes decir
que el primer estatuto es la directiva LABEL y los otros estatutos son las instrucciones MOV, ADD y
PUSH.

Los ejemplos previos ilustran tres puntos importantes. Primero, para hacer las instrucciones entendibles,
usa maysculas.
Segundo, algunos estatutos contienen dos operandos como el estatuto

44
MOV AX,TOTAL

En tales casos debes separar los operandos con una coma.

Tercero, todas las instrucciones tendrn un opcode pero no todas tendrn un nombre y/o operandos.

Para mantener cada parte en su lugar, haz el hbito de separar esto por columnas. Empieza con los
nombres en la columna 1, los opcodes en la columna 9, y los operandos en la columna 17, si incluye
comentarios pon estos a partir de la comuna 41. Esto ayuda a estandarizar el programa. La figura 5-1
muestra una instruccin MOV con este formato:

Nombre Opcode Operando Comentario

SETUP MOV DX,OFFSET MESSAGE ;actualizar DX

col 1 col 9 col 17 col 41


5.8 Como usar los Nombres.

El nombre es la parte de una instruccin o directiva que comprende la direccin donde esta
localizada. Por ejemplo, considere la siguiente directiva, la cual le dice al ensamblador que inicia un
nuevo procedimiento:

GETDATA PROC

Esta directiva tiene un nombre GETDATA, y un opcode, PROC, pero no tiene ningn operando.
Como parte del proceso de ensamblamiento, el ensamblador mantiene una tabla de nombres llamada
tabla de smbolos. Cada vez que el ensamblador encuentra un nuevo nombre, lo adiciona a la tabla con la
direccin (el offset) en el cual apareci. Entonces cuando otras instrucciones se refieren a ese nombre, se
puede usar como una direccin con un operando. El ensamblador puede buscar el nombre en la tabla de
smbolos y sustituir la direccin.

Por ejemplo, una vez que GETDATA es establecida como la representacin de una direccin al principio
del procedimiento, una instruccin CALL puede llamar al procedimiento as:

CALL GETDATA

La instruccin tiene un opcode CALL y un operando GETDATA pero no tiene nombre.
Aqu hay otro ejemplo. La siguiente directiva le dice al ensamblador que aparte 5 palabras de memoria:

SUM DW 5 DUP(?)

Esta directiva tiene un nombre, SUM; un opcode, DW; y un operando 5 DUP(?). El nombre SUM
representa la direccin donde est la primera de las 5 palabras. As la siguiente instruccin copia el
contenido del registro AX a esta palabra:

MOV SUM, AX

Esta instruccin tiene un opcode MOV, y un operando SUM,AX; pero no tiene nombre.
45
SUM se refiere a la direccin de la primera de las 5 palabras, para referirte a la direccin de la segunda
palabra, puedes usar SUM+2. As si quieres copiar el contenido del registro AX al la segunda palabra
puedes usar:

MOV SUM+2,AX

Sin embargo que pasa si el ensamblador no encuentra an el estatuto de la definicin de un nombre. Por
ejemplo, que pasa si la instruccin anterior est antes de la directiva en la cual SUM es definida. Esta es
llamada una referencia forward. El ensamblador maneja la referencia forward dejando un espacio para la
direccin, la cual debe ser llenada despus.

Los programadores experimentados evitan el forward siempre que es posible, debido a que el
ensamblador no le es posible crear cdigo eficiente cuando encuentra una referencia forward. La mejor
forma de evitar esto es colocando los segmentos que define los datos antes del segmento que contiene las
instrucciones.


5.9 Las reglas para especificar Nombres.

Los nombres son smbolos que escoges para representar de una manera ms sencilla direcciones de
memoria en un programa. Debes crear un nombre de acuerdo a las siguientes reglas:

e Los nombres pueden usar letras, dgitos y los siguientes caracteres especiales:
? @ _ $

e El primer carcter no debe ser un dgito. Esto le permite al ensamblador distinguir entre nombres y
nmeros.

e No es buena idea usar el carcter @ al principio de un nombre. Los nombres que empiezan con @
tienen un propsito especial.
e Los nombre pueden ser tan largos como quieras; sin embargo, el ensamblador solo reconoce
los primeros 31 caracteres.

Aqu hay algunos ejemplos de nombres validos:

HELLO $MARKET A12345 LONG_NAME PART_3

Aqu hay algunos nombres invlidos:

LONG-NAME 3_PART

Como siempre la recomendacin es que escojas nombres concisos, pero que representen el uso prctico
de la variable o sus posibles valores.

Esta absolutamente prohibido, como en los lenguajes de alto nivel, que utilices nombre idnticos a las
instrucciones y directivas de ensamblador.


5.10 Reglas para especificar Nmeros.

46
Puedes utilizar nmeros en decimal, hexadecimal, y binario. Para especificar nmeros decimales
escrbelos con dgitos como siempre. Por ejemplo la siguiente instruccin carga el registro AX con el
valor decimal 855.

MOV AX,855

Para especificar un nmero en hexadecimal, use los dgitos hex del 0 al 9 y de la letra A-F. Debes
adicionar una H al final del nmero para especificar que es un hex, la siguiente instruccin carga el
registro AX con el valor hex 855H (2133 decimal).

MOV AX,855H

Si el nmero inicia con una letra de la A-F, debes poner un 0 antes del nmero, para que el ensamblador
no piense que es un nombre de direccin de memoria. Por ejemplo la siguiente instruccin carga el
registro AX con el valor FFH (255 decimal):

MOV AX,0FFH

Si usas

MOV AX,FFH

el ensamblador asumir que FFH es un nombre y ocurrir un error.

Para especificar un nmero binario, use solo los dgitos 1 y 0, y adicione una letra B al final del nmero.
Por ejemplo si quisiera cargar el registro AX con el valor binario 011010010110B (1686 decimal, 696H)

MOV AX,011010010110B


{_____________o___________}

CAPITULO 6 COMPRENDER UN PROGRAMA EN LENGUAJE ENSAMBLADOR


En este capitulo aprenders como construir un programa bsico en lenguaje ensamblador, usando un
programa de ejemplo aprenders cual es la funcin de cada parte y como se construye. Cuando termine
este captulo debes sentirte cmodo con un esqueleto que es comn para cualquier tipo de programa en
ensamblador.


Nuevos Trminos

Listado. Un reporte o impresin que el ensamblador genera cuando procesa un programa.

Punto de entrada. La direccin en la cual un procedimiento inicia su ejecucin.

Salvar (un registro). Almacenar un registro para recuperarlo despus.

Restaurar (un registro). Cambiar el valor de un registro por un valor anterior.

Side effect. Un cambio inadvertido en el ambiente de un programa.
47



6.1 Un programa Prototipo.

En este captulo el programa de la figura 6-1 es usado como prototipo de un programa de propsito
general en lenguaje ensamblador. Despus de que leas este captulo usa un editor para hacer tu propia
copia del programa prototipo. De este modo cuando veas como ensamblar y linkear un programa podrs
hacerlo con este.

Note que en la figura hay un nmero de lnea, este slo es utilizado como referencia, y no debe aparecer
en la copia que hagas con el editor. Cuando explique las diferentes instrucciones y directivas solo las
explicare ligeramente. Estas sern explicadas ms a fondo en otros captulos adelante.

Figura 6-1 Un programa prototipo

1 PAGE 58,132
2 ;------------------------------------------------------------------------------------
3 ; DISPLAY
4 ;
5 ; Proposito:
6 ; para desplegar un mensaje en la pantalla
7 ; -----------------------------------------------------------------------------------
8
9 ; Ajustar el titulo y el conjunto de instrucciones
10 TITLE DISPLAY - programa prototipo
11 .286
12
13 ;-------------------------------------------------------------- segmento STACK
14 SSEG SEGMENT STACK
15 DB 32 DUP(STACK---)
16 SSEG ENDS
17
18 ;--------------------------------------------------------------- segmento DATA
19 DSEG SEGMENT
20 MESSAGE DB Hola, como ests viejo?, 0DH, 0AH
21 L_MESSAGE EQU $-MESSAGE
22 DSEG ENDS
23
24 ;--------------------------------------------------------------- segmento CODE
25 CSEG SEGMENT CODE
26 ASSUME CS:CSEG, SS:SSEG; DS:DSEG
27
28 PAGE
29 ;----------------------------------------------------------------------------------
30 ; MAIN (programa principal)
31 ;
32 ; Proposito:
33 ; Desplegar un mensaje en la pantalla
34 ;
35 ; Entrada:
36 ; -- ninguna --
48
37 ;
38 ; Salida:
39 ; El mensaje es desplegado en la pantalla
40 ;
41 ; Procedimientos:
42 ; -- ninguno --
43 ;----------------------------------------------------------------------------------
44
45 ; Procedimiento: MAIN
46 MAIN PROC FAR
47
48 ; Salvar la direccion para poder regresar a DOS
49 PUSH DS
50 PUSH 0
51
52 ; Actualizar el registro de segmento
53 MOV AX,DSEG
54 MOV DS,AX
55
56 ; Desplegar el mensaje
57 MOV BX,0001H
58 LEA DX,MESSAGE
59 MOV CX,L_MESSAGE
60 MOV AH,40H
61 INT 21H
62
63 ; Regresar a DOS
64 RET
65
66 ; Fin de procedimiento: MAIN
67 MAIN ENDP
68
69 ; Fin de segmento de codigo
70 CSEG ENDS
71
72 ;--------------------------------------------------------------- Fin de programa
73 END MAIN



6.2 Como usar los comentarios bien.

Es importante que todo programa en ensamblador tenga un encabezado que explique brevemente el
propsito del programa y su nombre lnea 2-7. Ahora vea los comentarios en las lneas 29-43. Estos
muestran informacin general acerca del programa principal. Debes tener un conjunto de comentarios que
antecedan cada procedimiento de tu programa.

Puedes ver que despus del nombre del procedimiento (lnea 30), siguen cuatro encabezados estndar:

Propsito describe que es lo que hace el procedimiento. Este debe ser un comentario de dos lneas.

Entrada y Salida describen que necesita el procedimiento y que va a obtener como resultado.
49

Procedimientos nos indica cuales procedimientos llama el programa principal.

Ahora vea los comentarios que anteceden a cada bloque pequeo de instrucciones y directivas - lneas 9,
13, 18, 24, 45, 48, 52, 56, 63, 66, 69 y 72. Estos comentarios son de dos tipos. El primero de los
comentarios describe el principio o el fin de segmento o procedimiento. Este tipo de comentarios
consisten de simples anuncios.

El segundo tipo de comentarios -los cuales son bastantes en un programa - describen el propsito de los
estatutos que estn a continuacin. Por ejemplo, la lnea 56 dice Desplegar el mensaje. Note que no
dice Desplegar el mensaje Mensaje desplegado. Los mejores comentarios son directos: Hace esto
o aquello, en lugar de Hizo o va a hacer esto o aquello.

Puedes ayudarte a disear un procedimiento, empezando con una serie de estatutos, que te indiquen una
gua sobre lo que tiene que realizar el programa. Por ejemplo el diseo para este programa es

Salvar direcciones para poder regresar a DOS.

Actualizar los registros de segmento.

Desplegar el mensaje en la pantalla.

Regresar a DOS.

Una vez que terminas el diseo puedes transformar los estatutos en un par de lneas del lenguaje
ensamblador.

Evita como a la peste a aquellos programadores y programas de ensamblador que tienden a poner
comentarios a cada una de las instrucciones y directivas en el programa, (reserva este caso solo para
partes del programa demasiado oscuros o complicados), esto solo hace muy confuso el programa e indica
que ni el programador sabe exactamente que hace su programa, hay que ser breve pero conciso. Para
evitar esto aprende a disear tu programa usando metas iniciales como comentarios principales. Debes ser
capaz de comprender un programa completamente leyendo los comentarios en secuencia.

Siempre documenta tus programas como si fueran para otra persona que tuviera que comprenderlos sin
ayuda. Esto te permite desarrollar programas rpidos y de manera ms precisa, tambin te permite
recordar el propsito de tus programas viejos que no has visto por un tiempo.



6.3 Indicar el fin de un programa.

El ltimo estatuto en todo programa debe ser una directiva END. Esta directiva tiene dos propsitos:
indicar el fin de un programa, y decirle al ensamblador donde va a empezar a ejecutarse un programa.
En este caso, el operando de la directiva END es MAIN (lnea 73). Esto le dice al ensamblador que
cuando el programa sea cargado, la ejecucin debe empezar con el estatuto con el nombre MAIN (lnea
46).



6.4 Actualizando el listado.

50
El listado es un reporte, que se puede imprimir, que el ensamblador genera cuando procesa un
programa. El listado contiene cada estatuto en el programa con las instrucciones mquina
correspondientes al estatuto. Si el ensamblador encuentra un error en un estatuto, el listado contendr un
mensaje de error despus del estatuto. Al final del programa, el listado muestra informacin acerca de los
nombres que el programa usa.

Hay varias directivas que puedes usar para actualizar el listado. Una es la directiva PAGE (lnea 1 y 28) y
la directiva TITLE (lnea 10).

La directiva PAGE puede ejecutar dos funciones. Cuando es usada con operandos PAGE controla el
ancho y las pginas del listado. En la lnea 1 del programa prototipo

PAGE 58,132

La directiva PAGE pone una longitud de cada pgina de 58 lneas y un ancho en cada pgina de 132
caracteres. Esta directiva debe ir en la primera lnea del programa, antes de los comentarios
introductorios, para asegurarnos que imprimir los comentarios adecuadamente.

Cuando la directiva PAGE no tiene operandos, le dice al ensamblador que inicie una nueva pgina en el
listado.

La directiva TITLE (lnea 10) especifica un titulo a ser impreso cerca del tope de cada pgina. En este
caso, el titulo es DISPLAY - programa prototipo.



6.5 Especificar el Conjunto de Instrucciones.

Por default, el ensamblador puede reconocer slo las instrucciones 8086. Sin embargo puedes poner
una directiva especial al inicio del programa para decirle al ensamblador que planeas usar un procesador
diferente. El ensamblador te permite entonces usar todas las instrucciones que funcionan en ese
procesador.
Como explique en el capitulo 1, las instrucciones 8086 son todas las que necesitas muchas de las veces.
Sin embargo, existen un par de instrucciones que no son del 8086 que son muy convenientes de usar.
Estas instrucciones requieren por lo menos un procesador 286. (Especficamente me refiero a las
instrucciones PUSHA y POPA usadas en la pila).

Para decirle al ensamblador que quiero usar el conjunto de instrucciones 286 (en modo real, uso la
directiva .286 (lnea 11).

Puedes encontrar un par de instrucciones 286 extra que son tiles en un programa, por ejemplo en la lnea
50 meto un valor 0 en la pila. El procesador 8086 no acepta este tipo de instrucciones. El 8086 necesita
que primero le pases el valor a algn registro y de ah a la pila.

As si no tuviramos la directiva .286 no podras usar la instruccin

PUSH 0

Tendra que poner un cero en algn registro AX por ejemplo, y entonces meter el registro:

MOV AX,0
PUSH AX
51



6.6 Actualizar los Segmentos.

Muchos de tus programas tendrn un segmento de pila, un segmento de datos, y un segmento de
cdigo. Usualmente puedes ponerlos en ese orden. Algunas veces necesitaras usar el segmento extra, en
tal caso el segmento extra debe estar entre el segmento de datos y el segmento de cdigo.

La directiva SEGMENT marca el inicio de un segmento; la directiva ENDS marca el fin de un segmento.
Cada segmento debe tener un nombre. Por ejemplo, si el segmento es el de pila, la directiva SEGMENT
debe tener el operando STACK.

En el programa prototipo, el segmento de pila es actualizado en los estatutos de las lneas 14 y 16:

SSEG SEGMENT STACK
SSEG ENDS

El segmento de datos es actualizado en las lneas 19 y 22:

DSEG SEGMENT
DSEG ENDS

Y el segmento de cdigo es actualizado en las lneas 25 y 70:

CSEG SEGMENT CODE
CSEG ENDS

Si tienes un segmento extra, puedes definirlo con estatutos similares:

ESEG SEGMENT
ESEG ENDS
Puedes escoger cualquier nombre que quieras en lugar de SSEG, DSEG, CSEG y ESEG. Sin embargo
estos nombres creo que estn bien y dan la idea.

Cuando defines el segmento de cdigo, debes usar el operando CODE con la directiva SEGMENT. LA
razn es obscura y no esta documentada en el manual.

Note que he usado comentarios con una lnea de guiones (lneas 13, 18 y 24) para marcar el principio de
cada segmento. El segmento de cdigo consiste de instrucciones mquina que el ensamblador generar a
partir de las instrucciones fuente. Los segmentos de pila, datos y extra consisten de espacio de memoria
que el ensamblador apartar.

El espacio para el segmento de datos es requerido por la directiva DB en la lnea 20. Brevemente, DB
significa definir byte. Esta directiva le dice al ensamblado el nmero de bytes que tiene que apartar.
Adems de especificar los bytes tambin se pueden inicializar a un valor particular.
La directiva DB en la lnea 20:

MESSAGE DB Hola, como estas viejo?, 0DH, 0AH

le dice al ensamblador que aparte bytes, tantos como caracteres o valores estn especificados.
52
Los primeros 24 contienen los caracteres Hola, como estas viejo?. Los siguientes 2 bytes contienen los
valores hex DH y AH. Estos dos valores hex hacen que el cursor avance al principio de la siguiente lnea
despus de que el mensaje es desplegado. As la directiva DB aparta 26 bytes. Los detalles de la
definicin de espacio de memoria se explicaran en un capitulo posterior.

En resumen, el segmento de cdigo consiste a las instrucciones mquina que corresponden a las
instrucciones entre

CSEG SEGMENT CODE

y

CSEG ENDS

El segmento de datos consiste de las reas de memoria que sern reservadas por medio de directivas que
estn entre

DSEG SEGMENT

y

DSEG ENDS

Si necesitas un segmento extra, las directivas que reservan su rea de memoria estarn entre

ESEG SEGMENT

y

ESEG ENDS



Las directivas que reservan rea de memoria para la pila estn entre

SSEG SEGMENT STACK

y

SSEG ENDS



6.7 Apartar rea de memoria para la Pila.

El estatuto que aparta espacio de memoria para la pila es la directiva DB, en el programa prototipo,
esta en la lnea 15:

DB 32 DUP(STACK---)

53
Veamos esta instruccin ms al detalle. Supongamos que quieres reservar 256 bytes de memoria para la
pila. Existen varias maneras en las que puedes apartar tal rea de memoria. La ms simple es apartar los
256 bytes directamente con la directiva DB.

DB 256 DUP(?)

significa aparta 256 bytes. DUP significa duplicado. El signo de interrogacin significa que no es
necesario inicializar los valores de la pila a un valor especfico. Sin embargo, puede que quieras
inicializar cada uno de los 256 caracteres de la pila a un carcter particular. Cuando corres un programa
usando un debugger, puedes examinar la memoria del programa ejecutado. Si la pila contiene caracteres
reconocibles cuando el programa inicia, puedes encontrarlos o distinguirlos ms fcilmente.

Por ejemplo si quisieras apartar 256 bytes para la pila cuyo contenido sean puros asteriscos (*) . Los
haces con la siguiente directiva:

DB 256 DUP(*)

Sin embargo es probable que otras direcciones de memoria contengan tambin una buena cantidad de
asteriscos lo que en cierto punto seria un poco molesto de comprobar y segundo con una secuencia de
asteriscos no podramos reconocer rpidamente cuanta cantidad de la pila esta siendo ocupada por los
datos.

La siguiente directiva aparta 256 bytes y los inicializa a STACK---. Cada grupo de caracteres de
STACK--- requiere 8 bytes, as tienes una requisicin de 32 grupos para apartar 256 bytes (32 x 8 = 256).

DB 32 DUP (STACK---)

Si necesitas una pila ms grande o pequea, ajusta el estatuto DB como necesites. Por ejemplo, si quieres
una pila de 1024 bytes puedes usar:

DB 128 DUP(STACK---)

as 128 x 8 = 1024.


6.8 Direccionar los segmentos de Pila, Datos y Cdigo.

El ensamblador se encarga de casi todos los detalles involucrados con la generacin de las
direcciones apropiadas. Sin embargo, puedes ayudarle al ensamblador de dos maneras: Primero, debes
decirle al ensamblador que valores contendrn los registros de segmento cuando el programa se ejecute y
segundo, debes asegurarte que los registros de segmento contiene esos valores actualmente.

Para completar el primer requerimiento, usamos las directiva ASSUME. En el programa prototipo en la
lnea 26:

ASSUME CS:CSEG, SS:SSEG, DS:DSEG

Esto le dice al ensamblador que asuma qu cuando el programa se ejecute, el registro CS contendr la
direccin de CSEG; SS estar contenido en la direccin SSEG; y DS contendr la direccin de DSEG.
Basados en estos reconocimientos, el ensamblador generar los desplazamientos correctos para los
nombres de los segmentos varios. En otras palabras, cuando uses un nombre como parte de un operando,
54
el ensamblador reemplazar el nombre con el offset relativo correcto, para el registro de segmento
apropiado.

Afortunadamente no necesitas actualizar los registros CS y SS por ti mismo. Cuando DOS carga un
programa, este automticamente pone CS apuntando al primer byte del segmento de cdigo y SS
apuntando al primer byte de la pila. Sin embargo si necesitas actualizar los registros DS y ES. Esto
puedes hacerlo al principio del programa, antes de cualquier referencia a nombres usados en el segmento
de datos o extra.

Para actualizar el registro DS, todo lo que tienes que hacer es cargar la direccin del primer byte del
segmento de datos. Si llamaste a tu segmento de datos DSEG, usa la instruccin MOV para copiar el
valor de DSEG al registro DS. Sin embargo la instruccin MOV no permite copiar directamente una
locacin de memoria a un registro de segmento. En otras palabras no puedes usar

MOV DS,DSEG

Sin embargo, si puedes copiar DSEG a un registro general, digamos AX, y entonces de AX a DS. Esto
esta dado por las lneas 52 y 54 del programa prototipo:

; Actualizar el registro de segmento
MOV AX,DSEG
MOV DS,AX



6.9 Direccionar el Segmento Extra.

Existen dos maneras de usar un segmento extra. La primera, es usa el segmento extra como una
segunda rea de datos distinta del segmento de datos. En este caso, el segmento extra estar despus del
segmento de datos definido entre las lneas:

ESEG SEGMENT
ESEG ENDS

Como en el segmento de datos, las directivas del segmento extra para apartar memoria estarn entre los
estatutos anteriores.

en este caso la directiva ASSUME debe decirle al ensamblador que ES contendr la direccin del
segmento extra:

ASSUME CS:CSEG, SS:SSEG, DS:DSEG, ES:ESEG

Cuando actualizas el registro DS, tambin debes actualizar el registro ES. En otras palabras, reemplaza
las lneas 52 a la 54 del programa prototipo con lo siguiente:

; Actualizar los registros de segmento
MOV AX,DSEG
MOV DS,AX
MOV AX,ESEG
MOV ES,AX

55
La segunda manera de usar el segmento extra es hacer que ocupe el mismo espacio que el segmento de
datos. Esto te permite referenciar los campos de datos que estn en ambos segmentos (como una persona
que responde a dos nombres diferentes).

Esto es til con ciertas instrucciones: MOVS, MOVSB, y MOVSW, como explicare despus. Estas
instrucciones tiene dos operandos: uno debe estar en el segmento de datos y otro debe estar en el
segmento extra. Sobrelapar los dos segmentos de datos te permiten usar el mismo campo de dato en
ambos operandos.

Cuando actualizas el segmento de datos y extra para que sea la misma rea de memoria, use los estatutos
SEGMENT y ENDS para definir un rea de datos nica:

DSEG SEGMENT
DSEG ENDS

Y cambie el estatuto ASSUME por este:

ASSUME CS:CSEG, SS:SSEG, DS:DSEG, ES:DSEG

Note que DS y ES estn en DSEG. Esto le indica al ensamblador que ambos registros DS y ES apuntan al
mismo segmento DSEG.

Para actualizar los registros DS y ES, copie los valores de DSEG a ambos registros , reemplazando las
lneas 52-54 del programa prototipo por estas lneas:

; Actualizar los registros de segmento
MOV AX,DSEG
MOV DS,AX
MOV ES,AX



6.10 Actualizar el programa MAIN

Los programas estn divididos en uno o ms procedimientos. El procedimiento que empieza la
ejecucin del programa es llamado main.



El programa principal puede llamar a otros procedimientos, los cuales pueden llamar a otros, etc. Por
supuesto muchos programas pequeos consisten de un solo procedimiento principal.

La direccin en la cual un procedimiento comienza a ejecutarse es llamada el punto de entrada. El punto
de entrada del programa principal en donde el programa comienza. La directiva END en el programa
prototipo (lnea 73) tiene un operando MAIN, el punto de entrada de este programa es el nombre MAIN.
La primera instruccin que ser ejecutada actualmente ser el PUSH de la lnea 49.

Para poder ser ejecutado un procedimiento debe ser llamado por otro procedimiento, y el procedimiento
principal no es la excepcin; este debe ser llamado por un procedimiento DOS, tu programa principal es
slo otro procedimiento.

56
Las directivas SEGMENT y ENDS le dicen al ensamblador donde empieza y termina un segmento, las
directivas PROC y ENDP le dicen al ensamblador donde empieza y termina un procedimiento, en el
programa prototipo, el programa principal empieza en la lnea 46:

MAIN PROC FAR

y termina en la lnea 67:

MAIN ENDP

En la lnea 46, la directiva PROC tiene un operando FAR. Este le dice al ensamblador que el
procedimiento ser llamado desde otro segmento. (En este caso, el procedimiento principal ser llamado
por un procedimiento DOS, que definitivamente esta en otro segmento.)

La ltima instruccin de cualquier procedimiento debe ser la instruccin RET. Esta instruccin regresa al
procedimiento que hizo la llamada. En el caso del programa principal, la instruccin RET regresa al
sistema operativo DOS.

La instruccin RET espera la direccin de regreso que se encuentra en la pila. Recuerda que una
direccin consiste de un desplazamiento y una direccin de segmento. El offset debe estar en el tope de la
pila, la direccin de segmento debe ser lo segundo en la pila.

Cuando DOS encuentra y carga un programa, el registro DS contiene el registro de direccin al cual el
programa volver cuando termine. Esta direccin es exacta slo necesita un offset de 0.
Una de tus responsabilidades es que el programa principal meta la direccin de regreso a la pila. Esto es
mejor hacerlo al principio de cada programa antes de cambiar el contenido del registro DS. En el
programa prototipo esta en la lnea 48-50:

; salvar la direccin de regreso a DOS
PUSH DS
PUSH 0

La direccin de segmento es metida primero, seguida de un desplazamiento 0. Como los valores estn en
Last-in, first-out, el desplazamiento ser recuperado primero, seguido por la direccin de segmento. Esto
es lo que la instruccin RET necesita y lo hace automticamente sin que tengas que intervenir.

Si colocas datos en la pila en el transcurso de tu programa, debes asegurarte de sacarlos antes de que una
instruccin RET se ejecute. En otras palabras debes asegurarte que la instruccin RET encuentre los
valores apropiados en la pila.

6.11 Los Estatutos que hacen el trabajo.

Donde estn las instrucciones que despliegan el mensaje? En el programa prototipo estn en las
lneas 56-61:

; Desplegar el mensaje
MOV BX,0001H
LEA DX,MESSAGE
MOV CX,L_MESSAGE
MOV AH,40H
INT 21H

57
Para escribir un programa diferente, slo tienes que reemplazar estas lneas por instrucciones diferentes y
reemplazar el segmento de datos por nuevos datos. La mejor forma de empezar un programa nuevo es
modificar el programa prototipo.



6.12 Actualizar un programa para llamar procedimientos.

El programa prototipo de la figura 6-1 tiene un slo procedimiento, el programa principal, sin
embargo frecuentemente disearas programas que tengan varios procedimientos.
Actualizar un programa para adicionarle algunos procedimientos es fcil. Slo sigue estas guas:

Todos los procedimientos deben estar dentro del segmento de cdigo.

Use las directivas PROC y ENDP para indicarle al ensamblador donde empieza y acaba el
procedimiento.

La figura 6-2 muestra una gua de un programa que tiene varios procedimientos. Note que los tres
procedimientos son llamados MAIN, PROC1 y PROC2. Dentro de un procedimiento, usas la instruccin
CALL para llamar a otro procedimiento. Por ejemplo, si quisieras llamar al procedimiento PROC1 de la
siguiente manera:

CALL PROC1

Para regresar al procedimiento que hizo la llamada, usa

RET

La instruccin CALL automticamente empuja la direccin de regreso en la pila, en preparacin para la
instruccin RET

Figura 6-2 Patrn de un programa que llama procedimientos

comentarios introductorios

SSEG SEGMENT STACK
-Segmento de la pila-
SSEG ENDS


DSEG SEGMENT
-Segmento de datos-
DSEG ENDS

ESEG SEGMENT
-Segmento extra-
ESEG ENDS

CSEG SEGMENT CODE

MAIN PROC FAR
-Programa principal-
58
MAIN ENDP

PROC1 PROC
-Procedimiento 1-
PROC1 ENDP

PROC2 PROC
-Procedimiento 2-
PROC2 ENDP

CSEG ENDS

END MAIN



6.13 El prototipo de un Procedimiento.

Excepto por el programa principal, todos los procedimientos son llamados dentro del programa.
Estas llamadas a los procedimientos tienen una estructura similar a la del programa principal. La figura 6-
3 contiene un prototipo de un procedimiento.

Figura 6-3 Prototipo de un procedimiento.

1 PAGE
2 ;-----------------------------------------------------------------------------------------
3 ; DISPM1
4 ;
5 ; Proposito:
6 ; Desplegar el primero de dos mensajes
7 ;
8 ; Entrada:
9 ; -ninguna-
10 ;
11 ; Salida:
12 ; El mensaje se despliega en pantalla
13 ;
14 ; Procedimientos:
15 ; -ninguno-
16 ;-----------------------------------------------------------------------------------------
17
18 ; inicio del procedimiento: DISPM1
19 DISPM1 PROC
20
21 ; salvar los registros
22 PUSHA
23
24 ; despliega el primer mensaje
25 MOV BX,0001H
26 LEA DX,MSG1
27 MOV CX,L_MSG1
28 MOV AH,40H
59
29 INT 21H
30
31 ; restaurar registros
32 POPA
33
34 ; regresar al procedimiento principal
35 RET
36
37 ; fin del procedimiento: DISPM1
38 DISPM1 ENDP



6.14 La estructura de un Procedimiento.

Demos un vistazo al procedimiento en la figura 6-5. Note que el procedimiento empieza con la
directiva pgina sin operandos.

Las lneas 2 a la 16 son comentarios similares al programa main, incluyendo el nombre, propsito,
entrada de datos, salida, etc. El procedimiento esta definido por las directivas PROC y ENDP (lneas 19 y
38). El procedimiento regresa usando una instruccin RET (lnea 35).



6.15 Salvar y restaurar los registros.

La diferencia ms notable entre el procedimiento y el programa principal, son las instrucciones para
salvar y restaurar registros (lneas 21-22 y 31-32). Salvar un registro significa recordar cual era su valor.
Restaurar los registros significa copiar los valores recuperados de regreso a los registros.

Cada llamada a un procedimiento obliga a este a dejar los registros tal y como estaban despus de que
este termina. La idea es que un procedimiento no debe cambiar el ambiente. Esto es importante. Cuando
un procedimiento inadvertidamente cambia algo del ambiente, tal como el valor de un registro, lo
llamamos un cambio side effect. Debes aprender a disear programas para minimizar los side effects, que
pueden causar errores obscuros y perplejos.

La mejor manera de salvar los registros es poner sus valores en la pila. Esto es hecho por la instruccin
PUSHA (push all) en la lnea 22. Esta instruccin salva todos los registros exceptuando los registros de
segmento. La instruccin POPA (pop all) restaura los registros (lnea 32). Salvar y restaurar registros
tiene dos propsitos fundamentales. Primero evita el riesgo que una llamada a un procedimiento cause un
side effect cambiando accidentalmente el valor de algn registro, y segundo, permite a los procedimientos
utilizar los registros de manera libre ya que estos son restaurados antes de regresar del procedimiento.



6. 16 Un prototipo para un programa que llama procedimientos.

La figura 6-4 contiene un prototipo de un programa que llama procedimientos. Este programa de
ejemplo, DISPLAY manda dos mensajes a la pantalla. Para hacer esto, DISPLAY llama a dos
procedimientos: DISPM1, para desplegar el primer mensaje y DISPM2, para desplegar el segundo, este
programa es un prototipo; normalmente no debes separar en procedimientos algo tan sencillo como
desplegar mensajes.
60

Figura 6-4 Un programa prototipo para llamar procedimientos

PAGE 58,132
;------------------------------------------------------------------------------------
; DISPLAY2
;
; Proposito:
; para desplegar dos mensajes en la pantalla
; -----------------------------------------------------------------------------------

; Ajustar el titulo y el conjunto de instrucciones
TITLE DISPLAY2 - programa prototipo con procedimientos
.286

;-------------------------------------------------------------- segmento STACK
SSEG SEGMENT STACK
DB 32 DUP(STACK---)
SSEG ENDS

;--------------------------------------------------------------- segmento DATA
DSEG SEGMENT
MSG1 DB Este es el mensaje 1, 0DH, 0AH
L_MSG1 EQU $-MSG1
MSG2 DB Este es el mensaje 2, 0DH, 0AH
L_MSG2 EQU $-MSG2
DSEG ENDS

;--------------------------------------------------------------- segmento CODE
CSEG SEGMENT CODE
ASSUME CS:CSEG, SS:SSEG; DS:DSEG

PAGE
;----------------------------------------------------------------------------------
; MAIN (programa principal)
;
; Proposito:
; Desplegar dos mensajes en la pantalla
;
; Entrada:
; -- ninguna --
;
; Salida:
; Los mensajes son desplegados en la pantalla
;
; Procedimientos:
; DISPM1 -- despliega el primer mensaje
; DISPM2 -- despliega el segundo mensaje
;----------------------------------------------------------------------------------

; Procedimiento: MAIN
MAIN PROC FAR
61

; Salvar la direccion para poder regresar a DOS
PUSH DS
PUSH 0

; Actualizar el registro de segmento
MOV AX,DSEG
MOV DS,AX

; Desplegar los mensajes
CALL DISPM1
CALL DISPM2

; Regresar a DOS
RET

; Fin de procedimiento: MAIN
MAIN ENDP

PAGE
;-----------------------------------------------------------------------------------------
; DISPM1
;
; Propsito:
; Desplegar el primero de dos mensajes
;
; Entrada:
; -ninguna-
;
; Salida:
; El mensaje se despliega en pantalla
;
; Procedimientos:
; -ninguno-
;-----------------------------------------------------------------------------------------

; inicio del procedimiento: DISPM1
DISPM1 PROC

; salvar los registros
PUSHA

; despliega el primer mensaje
MOV BX,0001H
LEA DX,MSG1
MOV CX,L_MSG1
MOV AH,40H
INT 21H

; restaurar registros
POPA
; regresar al procedimiento principal
62
RET

; fin del procedimiento: DISPM1
DISPM1 ENDP

PAGE
;-----------------------------------------------------------------------------------------
; DISPM2
;
; Proposito:
; Desplegar el segundo de dos mensajes
;
; Entrada:
; -ninguna-
;
; Salida:
; El mensaje se despliega en pantalla
;
; Procedimientos:
; -ninguno-
;-----------------------------------------------------------------------------------------

; inicio del procedimiento: DISPM2
DISPM2 PROC

; salvar los registros
PUSHA

; despliega el segundo mensaje
MOV BX,0001H
LEA DX,MSG2
MOV CX,L_MSG2
MOV AH,40H
INT 21H

; restaurar registros
POPA

; regresar al procedimiento principal
RET

; fin del procedimiento: DISPM2
DISPM2 ENDP


; Fin de segmento de cdigo
CSEG ENDS

;--------------------------------------------------------------- Fin de programa
END MAIN

{_____________o___________}
63
CAPITULO 7 PROCESAR UN PROGRAMA EN ENSAMBLADOR

En este capitulo aprenders como convertir un programa fuente en un programa ejecutable,
explicare el uso del ensamblador y el linker, el programa de referencias cruzadas y como leer la salida de
estos programas.


Nuevos Trminos

Listado. Un registro del proceso del ensamblador que muestra cada estatuto del programa fuente adems
de otra informacin importante.

Referencia cruzada. Un reporte que muestra cada nombre del programa con el nmero de lneas en
donde el nombre aparece.

Librera. Un archivo que contiene una coleccin de mdulos objeto que pueden ser unidos al programa.
Mapa. Un reporte generado por el linker del proceso de un modulo objeto.

Desensamblar. Reconstruir una instruccin d lenguaje ensamblador de una instruccin en lenguaje
mquina. Tambin referido como unassembling.

Operando inmediato. Un operando que est en un valor actual.

Instruccin inmediata. Una instruccin que contiene un operando inmediato.

Relocalizable. Describe una direccin que no ha sido completamente determinada hasta que el programa
ha sido cargado.



7.1 Procesar y Correr un programa.

Una vez que creas un programa fuente con un editor, debes ensamblarlo y linkearlo para crear un
programa ejecutable. El ensamblador que vamos a utilizar MASM 5.0 de Microsoft IBM, este proceso
necesita ejecutar por lo menos dos programas, el ensamblador y el encadenador o linker, paso por paso.



7.2 Los archivos usados por el Ensamblador.

Los ensambladores usan ciertos archivos para ejecutar su trabajo, y cada tipo de archivo tiene una
extensin nica. La entrada del ensamblador es el programa fuente, que debe estar almacenado en un
archivo con la extensin ASM. Por ejemplo, el programa fuente llamado DISPLAY podra estar en un
archivo llamado DISPLAY.ASM.

La salida del ensamblador son tres archivos. El primero es el modulo objeto, la traduccin actual del
programa fuente en lenguaje mquina.

El segundo archivo es el listado. Este es un registro del proceso del ensamblador que muestra cada
estatuto del programa fuente con otra informacin importante.

64
El tercer archivo contiene informacin que puede ser usada para crear una referencia cruzada. Esta es una
lista de todos los nombres que el programa define con el nmero de lneas en donde aparece en el
programa.

A menos que especifiques otra cosa, siempre producir el modulo objeto. Puedes no generar el listado o
las referencias cruzadas cuando ensambles.

Por convencin, el ensamblador usa extensiones estndar para estos archivos : OBJ para los mdulos
objeto y LST para los listados. As un programa fuente llamado DISPLAY.ASM podra generar un
modulo objeto llamado DISPLAY.OBJ y un listado llamado DISPLAY.LST.

La extensin para el archivo de referencias cruzadas depende del ensamblador que uses MASM 5.0 de
Microsoft IBM usa la extensin CRF. La tabla 7-1 muestra los archivos de extensin. La figura 7-1
muestra las extensiones de entrada y salida del ensamblador.

Tabla 7-1 Extensin Significado
ASM Programa Fuente
OBJ Modulo Objeto
LST Listado
CRF referencia Cruzada

Figura 7-1




7.3 Ensamblar un programa usando el Ensamblador Microsoft IBM.

Para ensamblar un programa usando el ensamblador Microsoft IBM, use el comando MASM.
Despus del nombre del comando escriba el nombre del archivo que quieres usar como programa fuente,
objeto modulo, listado e informacin de referencia cruzada.

Por ejemplo, digamos que quieres ensamblar un programa fuente llamado DISPLAY .ASM. De la
instruccin :

MASM DISPLAY,DISPLAY,DISPLAY,DISPLAY

El ensamblador asumir que quieres usar las extensiones convencionales de archivos. En este saco el
modulo objeto ser DISPLAY.OBJ, el listado ser DISPLAY.LST, y la referencia cruzada se llamar
DISPLAY.CRF. En otras palabras, el comando anterior es lo mismo que :

MASM DISPLAY.ASM,DISPLAY.OBJ,DISPLAY.LST,DISPLAY.CRF

Por omisin, MASM crea el modulo objeto, pero no los otros archivos. Para usar el default, simplemente
quite el nombre del archivo que no quiera crear. Sin embargo a veces es necesario poner las comas :
65
Por ejemplo, para obtener el modulo objeto, sin listado, con informacin de referencia cruzada, teclea
esto :

MASM DISPLAY,,,DISPLAY
Si terminas el comando el comando con un punto y coma, el ensamblador usar los defaults de cualquier
nombre que omitas. Por ejemplo si tecleas

MASM DISPLAY,DISPLAY,DISPLAY;

obtendrs un modulo objeto, un listado, pero sin informacin de referencia cruzada. Muchas de las veces,
probablemente quieras usar este comando ms simple :

MASM DISPLAY;

Esto generar el modulo objeto, sin listado, y sin referencia cruzada.
Un programa no podr generar un archivo OBJ hasta que todos los errores de sintaxis que el ensamblador
detecte en el programa fuente sean corregidos. Si existe un error en el momento de ensamblar un
programa fuente el ensamblador marcar el tipo de error que encuentre, y en que lnea lo encontr. Si
existen errores en un programa se debe volver a editar el programa fuente corregir el error, salvar el
programa y tratar de ensamblarlo de nuevo.

Existen otro tipo de errores de menor grado llamados warnings (advertencias). Un programa que
contenga 0 errores y algunos warnings si puede generar un modulo objeto. Por lo general estas
advertencias se refieren a nombres declarados en el segmento de datos, que nunca son utilizados en el
segmento de cdigo u otros errores benignos que no afectan en mucho al programa, sin embargo lo mejor
es tratar de reducir los warnings a 0.



7.4 Los archivos usados por el Linker.

El linker o encadenador lee un modulo objeto generado por el ensamblador y produce un programa
ejecutable. El modulo objeto tiene una extensin OBJ y el programa ejecutable una extensin EXE.
El linker es un programa complejo que debe hacer muchas cosas, en particular, en linker puede combinar
ms de un modulo objeto en un slo programa ejecutable. Esto muchas veces te permite ensamblar partes
de un programa separado y unirlas dentro del proceso de encadenamiento.

El linker puede usar colecciones de mdulos objeto llamados libreras. Una librera es un archivo, con la
extensin LIB, que contiene una coleccin de modulo objeto. Si escribes un programa que llama a un
procedimiento que est en una librera, puedes especificar el nombre de la librera cuando inicies el
encadenamiento. El linker buscar la librera y extraer los modulo objeto necesarios. Esto permite
referenciar procedimientos estndar dentro del programa.

Como el ensamblador el linker puede producir reportes de su trabajo. Este reporte es llamado un MAPA.
Muchas de las veces no lo necesitas.

La tabla 7-1 muestra las extensiones usadas por el linker. La figura 7-2 muestra las entradas y salidas del
linker.


Tabla 7-1 Extensiones de archivos usados por el Linker
Extensin Significado
66
OBJ Modulo objeto
EXE Programa ejecutable
MAP Mapa
LIB Librera

Figura 7-2 Las entradas y salidas del Linker




7.5 Linkear con el programa Microsoft IBM.

Una vez que el programa ha sido ensamblado, debes encadenarlo usando el comando LINK. La
salida del linker es un programa ejecutable que puedes correr.

Teclea el comando seguido por el nombre de los archivos que quiere usar para el modulo objeto, el
programa ejecutable, el mapa, y la librera(s). Coloca una coma entre cada nombre.

Por ejemplo, digamos que quieres linkear un modulo objeto llamado DISPLAY.OBJ usando una librera
llamada MYLIB.LIB. Teclee:

LINK DISPLAY,DISPLAY,DISPLAY,MYLIB

El linker asume que quieres usar las extensiones convencionales de los archivos. En este caso, el
programa ejecutable ser DISPLAY.EXE, y el mapa ser DISPLAY.MAP. En otras palabras, el comando
anterior es lo mismo que:

LINK DISPLAY.OBJ,DISPLAY.EXE,DISPLAY.MAP,MYLIB.LIB

Por omisin, LINK crea un programa ejecutable sin el mapa y sin buscar libreras. Para usar el default,
simplemente deja slo el nombre del OBJ.

Por ejemplo, para usar DISPLAY.OBJ y una librera llamada MYLIB.LIB para generar un programa
ejecutable sin el mapa teclee:

LINK DISPLAY,,,MYLIB

Si terminas el comando con un punto y coma, el linker usa los defaults para cualquier nombre que omitas.
Por ejemplo, si tecleas

LINK DISPLAY,DISPLAY,DISPLAY;

generars un programa ejecutable con su mapa, pero sin libreras. Muchas de las veces querrs usar la
opcin ms simple posible:

LINK DISPLAY;
67

Esto genera un programa ejecutable sin mapa y sin libreras.


7.6 Ejecutar un Programa.

Una vez que el linker termina su labor puedes correr un programa de dos maneras diferentes. La
primera es invocar al programa ejecutable escribiendo su nombre en el smbolo del sistema del sistema
operativo. El segundo es bajo los auspicios de un debugger.

La ventaja de usar el debugger es que es fcil probar el programa. Puede ejecutar una instruccin a la vez
y desplegar los valores de los registros y las locaciones de memoria que desees. Hasta puedes cambiar los
valores de los registros y locaciones.

En orden de desplegar el programa, un debugger debe leer las instrucciones mquina y reconstruir las
instrucciones originales. Este proceso es llamado desensamblar o unassebling. Obviamente un debugger
no puede reconstruir los nombre que usas en el programa. Estos nombres son desplegados como las
direcciones actuales donde estn los datos.



7.7 Usar un Archivo Batch para procesar un Programa.

Para hacer tu vida ms fcil puedes usar un archivo Batch para procesar un programa en
ensamblador con el MASM y el LINK. La figura 7-5 muestra el archivo batch, llamado
ENSAMBLA.BAT.
Para usa ENSAMBLA.BAT, especifica el nombre del archivo del programa fuente como el primer
parmetro. ENSAMBLA.BAT ensambla, linkea y ejecuta el programa (si no hay errores). Si especificas
/D como el segundo parmetro, ENSAMBLA.BAT ejecuta el programa dentro de un debugger.
Por ejemplo, para procesar un programa llamado DISPLAY.ASM, teclea

ENSAMBLA DISPLAY

Si quieres ejecutar el programa bajo un debugger, teclea

ENSAMBLA DISPLAY /D

Si el archivo DISPLAY.ASM no existe, ENSAMBLA.BAT despliega el siguiente mensaje:

*** Error: DISPLAY.asm -- no se encuentra el archivo

ENSAMBLA.BAT te permite usar /D como segundo parmetro. Por ejemplo si tecleas ENSAMBLA
DISPLAY /P. El programa despliega el siguiente error:

*** Error: Parmetro ilegal: /P

Si el ensamblador o el linker encuentran un nivel de error en alguna variable mayor o igual a 1 o si
detectan un error en el programa, ENSAMBLA.BAT se detiene inmediatamente.

Figura 7-5 Archivo batch para procesar un programa en ensamblador

:-----------------------------------------ENSAMBLA.BAT ---------------------------------------:
68
: Archivo batch para procesar un programa en ensamblador :
: Parametros: %1 -- nombre del archivo con el programa fuente :
: %2 -- /d correr el programa con un debugger :
:--------------------------------------------------------------------------------------------------------:

:--Apagar el echo y limpiar la pantalla
@ECHO OFF
CLS:

:--Asegurarse que el cdigo fuente existe
IF EXIST %1.ASM GOTO FOUND
ECHO *** Error: %1.asm -- no se encuentra el archivo
GOTO STOP

:--Ensamblar el programa:
:FOUND
MASM %1;

:--Si hay un error en el ensamblado detenerse
IF ERRORLEVEL 1 GOTO STOP

:--Linkear el programa
LINK %1;

:--Si hay un error en el encadenamiento detenerse
IF ERRORLEVEL 1 GOTO STOP

:--Si %2 es /D, ejecutar el programa con el debugger
:--Si %2 esta vacio, ejecutar el programa por si mismo
IF x%2 == x/D GOTO DEBUGGER
IF x%2 == x GOTO EXECUTE
ECHO *** Error: Parametro ilegal: %2
GOTO STOP
:DEBUGGER
DEBUG %1.EXE
GOTO STOP
:EXECUTE
%1

:--Terminar
:STOP



7.8 Desplegar el Listado.

Como sabemos el ensamblador puede generar un listado del proceso que lleva a cabo. En esta
seccin te mostrare como leer el listado y comprender la informacin valiosa que contiene. Primero
obtenga el listado, por ejemplo el listado del programa DISPLAY.ASM, o sea DISPLAY.LST e
imprmalo. El listado que obtuve aparece en la Figura 7-6.

Figura 7-6 Listado de DISPLAY.LST

Microsoft (R) Macro Assembler Version 5.10 6/28/97 09:50:21
DISPLAY - programa prototipo Page 1-1


69
1 PAGE 58,132
2 ;-------------------------------------------------------------------------
3 ; DISPLAY
4 ;
5 ; Proposito:
6 ; para desplegar un mensaje en la pantalla
7 ; ------------------------------------------------------------------------
8 ;
9 ; Ajustar el titulo y el conjunto de instrucciones
10 TITLE DISPLAY - programa prototipo
11 .286
12
13 ;--------------------------------------------------------- segmento STACK
14 0000 SSEG SEGMENT STACK
15 0000 0020[ DB 32 DUP("STACK---")
16 53 54 41 43 4B
17 2D 2D 2D
18 ]
19
20 0100 SSEG ENDS
21
22 ;---------------------------------------------------------- segmento DATA
23 0000 DSEG SEGMENT
24 0000 48 6F 6C 61 2C 20 MESSAGE DB "Hola, como estas viejo?", 0DH, 0AH
25 A8 63 6F 6D 6F 20
26 65 73 74 A0 73 20
27 76 69 65 6A 6F 3F
28 0D 0A
29 = 001A L_MESSAGE EQU $-MESSAGE
30 001A DSEG ENDS
31
32 ;---------------------------------------------------------- segmento CODE
33 0000 CSEG SEGMENT 'CODE'
34 ASSUME CS:CSEG, SS:SSEG; DS:DSEG
35

Microsoft (R) Macro Assembler Version 5.10 6/28/97 09:50:21
DISPLAY - programa prototipo Page 1-2


36 PAGE
37 ;-----------------------------------------------------------------------
38 ; MAIN (programa principal)
39 ;
40 ; Proposito:
41 ; Desplegar un mensaje en la pantalla
42 ;
43 ; Entrada:
44 ; -- ninguna --
45 ;
46 ; Salida:
47 ; El mensaje es desplegado en la pantalla
48 ;
49 ; Procedimientos:
50 ; -- ninguno --
51 ;----------------------------------------------------------------------
52
53 ; Procedimiento: MAIN
54 0000 MAIN PROC FAR
55
56 ; Salvar la direccion para poder regresar a DOS
57 0000 1E PUSH DS
58 0001 6A 00 PUSH 0
59
60 ; Actualizar el registro de segmento
61 0003 B8 ---- R MOV AX,DSEG
62 0006 8E D8 MOV DS,AX
63
64 ; Desplegar el mensaje
70
65 0008 BB 0001 MOV BX,0001H
66 000B 8D 16 0000 R LEA DX,MESSAGE
67 000F B9 001A MOV CX,L_MESSAGE
68 0012 B4 40 MOV AH,40H
69 0014 CD 21 INT 21H
70
71 ; Regresar a DOS
72 0016 CB RET
73
74 ; Fin de procedimiento: MAIN
75 0017 MAIN ENDP
76
77 ; Fin de segmento de codigo
78 0017 CSEG ENDS
79
80 ;------------------------------------------------------ Fin de programa
81 END MAIN

Microsoft (R) Macro Assembler Version 5.10 6/28/97 09:50:21
DISPLAY - programa prototipo Symbols-1


Segments and Groups:

N a m e Length Align Combine Class

CSEG . . . . . . . . . . . . . . 0017 PARA NONE 'CODE'
DSEG . . . . . . . . . . . . . . 001A PARA NONE
SSEG . . . . . . . . . . . . . . 0100 PARA STACK

Symbols:

N a m e Type Value Attr

L_MESSAGE . . . . . . . . . . . NUMBER 001A

MAIN . . . . . . . . . . . . . . F PROC 0000 CSEG Length = 0017
MESSAGE . . . . . . . . . . . . L BYTE 0000 DSEG

@CPU . . . . . . . . . . . . . . TEXT 1287
@FILENAME . . . . . . . . . . . TEXT display
@VERSION . . . . . . . . . . . . TEXT 510


73 Source Lines
73 Total Lines
12 Symbols

47436 + 179839 Bytes symbol space free

0 Warning Errors
0 Severe Errors



7.9 Lectura del listado: Introduccin.

Vamos a empezar con las primeras dos pginas del listado. El programa aparece en el lado derecho
de la pgina. A la izquierda del programa esta el lenguaje mquina y las reas de datos que son generadas
por el ensamblador.

Todos los nmeros estn traducidos a hex. Los primeros cuatro dgitos son el desplazamiento dentro del
segmento. A la derecha del offset estn los dgitos hexadecimales actuales que representan la instruccin
en lenguaje ensamblador en esa lnea. Por ejemplo, en la lnea 68 podemos ver que el ensamblador genero
la instruccin mquina B440H en el offset 0012H.
71

El ensamblador inicia cada nuevo segmento en un desplazamiento de 0000H. Tantos como bytes son
apartados, el ensamblador incrementa el offset., hasta un mximo de FFFFH. Esto nos da un segmento
mximo de 64 K bytes.



7.10 Lectura del listado: El segmento de Pila.

En la lnea 14 empieza el segmento de pila. Los 0000 a la izquierda muestran que el desplazamiento
inicia en 0000H. Ahora vea la lnea 15. Este es un estatuto DB que aparta 256 espacios para la pila.
Recuerde que los bytes estn representados por 8 caracteres STACK---, repetidos 32 veces. A la
izquierda podemos ver

0020 [ 53 54 41 43 4B 2D 2D 2D ]

El 0020 significa 20 hex (32 decimal). Esto significa que existen 8 nmeros hexadecimales que sern
repetidos 20 veces hex. Los ocho nmeros hex son la representacin ASCII de los caracteres STACK---
.
Ahora veamos la lnea 20, la ltima lnea del segmento de pila. El 0100 a la izquierda significa que el
desplazamiento es ahora 0100H (256 decimal). EL segmento de pila inicia con un desplazamiento de
0000H y termina en el offset 0100H.



7.11 Lectura del listado: El segmento de Datos.

El segmento de datos esta definido por las lneas 23 a la 30. En la lnea 23, el desplazamiento
empieza de nuevo en 0000H debido a que empez un nuevo segmento. La lnea 24 contiene la directiva
que aparta los bytes para guardar el mensaje. En las lneas 24 a la 28, podemos ver los valores actuales
para estos bytes: 48H, 6FH, 6C, etc. Estos son los valores ASCII de los caracteres del mensaje en la
directiva DB.

En la primera lnea, 48H es la H, esta en el offset 0000H; el segundo carcter 6FH (la letra o, esta en
el offset 0001H, etc. As en la lnea 29 el offset tiene un valor de 001AH.

En la lnea 29 la directiva EQU le dice al ensamblador que el smbolo L_MESSAGE tendr un valor
igual a la longitud del mensaje.



7.12 Lectura del listado: El segmento de Cdigo.

El segmento de cdigo inicia en la lnea 33. Note que el offset de nuevo se ha reseteado a 0000H
para iniciar un nuevo segmento. Como se van generando las instrucciones mquina, el offset se
incrementa - desde 0000H (lnea 57) a 0001H (lnea 58) a 0003H (lnea 61) a 0006H (lnea 62), etc. La
ltima instruccin que genera una instruccin mquina (lnea 72) deja un offset de 0016H.
En otras palabras la primera instruccin empieza en 0000H, la segunda inicia en 0001H, la tercera
comienza en 0003H, etc. La ultima instruccin empieza en 0016H. Si hubiera otra instruccin
comenzara en 0017H.

72
El ltimo byte usado en el segmento de cdigo esta en el offset 0016H. As el segmento de cdigo esta en
el rango 0000H (cero) hasta 0016H (22 decimal).

A la derecha de los desplazamientos, puedes ver las instrucciones en lenguaje mquina que se generaron.
Por ejemplo en la lnea 69, podemos ver que la instruccin que inicia en el desplazamiento 0014H (INT
21) esta traducida como CD21H.

El primer byte de cada instruccin mquina es un nmero de dos dgitos hex que representan el opcode.
Por ejemplo en la lnea 68, el opcode INT esta representado por CDH; el opcode RET en la lnea 72 esta
representado por CBH.

Algunas formas diferentes de un instruccin estn representadas por nmeros diferentes. Por ejemplo, la
instruccin PUSH en la lnea 57 empuja el valor de un registro. Este tipo de push esta representado por
1EH. La instruccin PUSH en la lnea 58 empuja un valor actual (0 en este caso). Este tipo de instruccin
PUSH se representa con el cdigo 6AH.

Muchas instrucciones tiene operandos. Puedes ver la traduccin del operando a la derecha de la
traduccin del opcode. Por ejemplo, ve la lnea 62. La instruccin mquina es 8ED8H. El 8EH representa
el opcode (MOV); el D8H representa el operando.

Como sabemos los operandos pueden ser registros, por ejemplo:

PUSH AX

o nombres de locaciones de memoria, por ejemplo:

PUSH TEST

o valores actuales, por ejemplo:

PUSH 5

Un operando que tiene un valor actual es llamado un operando inmediato; una instruccin que tiene un
operando inmediato es conocida como instruccin inmediata. Ve la instruccin inmediata en la lnea 58.
Esta instruccin empuja un valor 0 a la pila. La instruccin mquina es 6A00H. El 6AH representa el
opcode; el 00H representa el operando. As podemos comprender que los operando inmediatos son
ensamblados directamente con la instruccin mquina. Esto ocurre en la lnea 69, con el operando
inmediato 21H.

La ltima cosa que debes comprender acerca del segmento de cdigo es el modo en que estn
representadas las direcciones en hex.

Ve la lnea 66. Esta instruccin usa el desplazamiento de MESSAGE como un operando. Si checas el
segmento de datos, vers que el desplazamiento de MESSAGE es 0000H lnea 24.

As, podemos ver la traduccin a lenguaje mquina de la lnea 66 es 8D160000H.. El 8D16H representa
el opcode. El 0000H representa el segundo operando- en este caso la solicitud de un offset. Si el offset
fuera diferente, digamos 218AH, la instruccin mquina sera 8A16218AH.

Note que la direccin en la lnea 66 (0000H) tiene una R despus. La R significa relocalizable. Una
direccin es relocalizable si su valor no esta completamente determinado hasta que el programa es
cargado. Casi todas las direcciones son relocalizables.
73
Estas direcciones son llamadas relocalizables debido a que el programa que usa esa direcciones puede
cargarlas donde sea en la memoria, actualizando los registros de segmento adecuadamente.
Ahora vea la lnea 61. Note que el operando esta representado por ----. El ensamblador usa ---- para
indicar la direccin de segmento. Note que tambin es relocalizable.



7.13 Lectura del listado: La ltima Pgina.

Vea la ltima pgina del listado. Esta pgina contiene informacin acerca de los nombres definidos
en el programa. Primero vemos cada nombre de segmento seguido de informacin acerca del segmento.
De hecho, vemos que SSEG define un segmento de pila de longitud 0100H (256 decimales) que estn
alineados al limite del prrafo.

Seguido del nombre de segmentos, vemos otros nombres: MAIN, el cual es un procedimiento, y
L_MESSAGE y MESSAGE los cuales son smbolos. Estos nombres, los cuales representan direcciones
estn seguidos por informacin descriptiva: el tipo de campo, su valor y sus atributos.

Para MAIN, vemos que el tipo es F Proc, lo cual significa procedimiento far. Este es un procedimiento
que es llamado por otro segmento. Cuando un procedimiento es de tipo N Proc, este procedimiento es
llamado dentro de su segmento. El valor de un procedimiento es su direccin. Si un nombre representa
solo una direccin tendr una L.

La informacin de L_MESSAGE y MESSAGE son claras. L_MESSAGE es un nmero con un valor de
1AH. MESSAGE es la direccin del byte en la locacin 0000H en el segmento de datos.
Finalmente, el listado finaliza con un sumario de warnings y errores.


{_____________o___________}























74
CAPITULO 8 DEFINIR DATOS


El ensamblador traduce un programa generando un modulo objeto. El modulo objeto solo contiene
instrucciones mquina; tambin contiene espacio para mantener los datos que el programa usar. Dentro
de un programa, debes apartar locaciones de memoria para cada datos que vas a usar. Puedes hacer esto
con las directivas para definir datos que describen los campos de datos en el ensamblador. La directivas
definen bytes, palabras, palabras dobles y palabras cudruples, etc.


Nuevos Trminos

Directiva definir dato. Una de las varias directivas que definen campos de datos usados por un
programa; las directivas son DB, DW, DD, DQ, y DT.

Constante. Un campo dato cuyo valor no cambia cuando el programa se ejecuta.

Variable. Un campo de dato cuyo valor puede cambiar cuando el programa se ejecuta.

Notacin cientfica. Un modo de escribir nmeros muy grandes con una notacin pequea, generalmente
multiplicada por una potencia de 10.

Atributo. Una caracterstica particular de un campo dato (TYPE, LENGTH, SIZE, SEG y OFFSET) o
una etiqueta (TYPE, SEG, OFFSET).

Operador. Un smbolo usado durante el ensamblamiento para afectar el valor de un operando.
Etiqueta (Label). Un nombre definido con un atributo especifico.

Equate. Una definicin (usando la directiva EQU) que da a un smbolo un valor especifico durante el
ensamblamiento de un programa.



8.1 Constantes y Variables.

Existen dos tipos de datos que puedes usar en un programa: constantes y variables. La diferencia es
que las constantes retienen un solo valor que no puede cambiar en un programa y las variables tienen un
valor que si cambia.

Cuando defines una constante, debes especificar que su valor ser inicializado por el ensamblador.
Cuando defines una variable, debes especificar que su valor no ser inicializado.

Aqu hay dos ejemplos usando la directiva DB:

COSTO DB 100
TOTAL DB ?

Ambos ejemplos apartan un byte de memoria. El primer ejemplo define una constante llamada COSTO
que es inicializada con un valor de 100 decimal. El segundo ejemplo define una variable llamada
TOTAL. Cuando se especifica un ?, el ensamblador no inicializar el valor de TOTAL.

75
Cuando el ensamblador traduce estos ejemplos, aparta un byte de memoria a COSTO y otro byte a
TOTAL. El byte que contiene COSTO tendr un valor de 100 por otro lado TOTAL no tendr ningn
valor especifico. Mejor asegrate que contenga un valor cuando el programa inicie.

Es importante que entiendas que las variables y las constantes son entidades lgicas de programacin.
Escoges datos que sern constantes o variables basado en los requerimientos del diseo del programa. a
diferencia de otros lenguajes el ensamblador no sigue estas reglas. Yo puedo cambiar el valor de una
constante; y tambin puedo usar una variable que no ha sido inicializada an (aunque contenga basura).
As, para mantener la cosas coherentes, asegurmonos que cada campo de datos definido sea tratado
puramente como una variable o una constante. Cuando el ensamblador inicialice un campo dato, no lo
modifiques dentro del programa, cuando definas una variable, no hagas que el ensamblador la inicialice;
inicializala dentro del programa. Algunas veces es ms fcil inicializar una variable como una constante,
sin embargo est es un prctica pobre de programacin.

Por ejemplo la variable constante COSTO mantendr un valor de 100 a travs de todo el programa. Por el
contrario TOTAL puede tomar el valor que necesite cuando lo necesite.



8.2 Tipos de Datos.

Cuando defines los campos de datos, puede usar uno de varios bloques constructores. Por ejemplo,
podras una variable que consista de 200 palabras, o podras definir una constante que consista de 50
bytes, cada uno inicializado a 0. Existen varios bloques constructores que puedes usar, cada uno para
tamao diferente. Se muestran en la tabla 8-1.

Tabla 8-1 Bloque constructor Tamao (en bytes)
BYTE 1
WORD 2
DWORD 4
QWORD 8
TBYTE 10

Para definir un dato, primero debes decidir que tipo de datos vas a guardar: BYTE, WORD, DWORD,
QWORD, TBYTE. Muchas de las veces podrs usar bytes y palabras. Los bytes son usados para
nmeros pequeos o secuencias de caracteres. Las palabras son usadas para guardar nmeros grandes.
Las palabras dobles, palabras cudruples y 10-bytes (TBYTES) son usados en clculos hechos por el
coprocesador matemtico.

Las palabras y palabras dobles son usadas para guardar direcciones. Cuando trabajas con
desplazamientos, puedes guardarlos en una palabra. Cuando trabajas con direcciones completas, puedes
guardarlas en una palabra doble. La direccin de segmento en los 16 bits de ms a la izquierda de la
DWORD y el offset en los 16 bits de ms a la derecha.



8.3 Las Directivas para definir datos.

El siguiente par de secciones describen las directivas usadas para definir datos. Estas directivas son
DB, DW, DD, DQ y DT. Cada una de estas define un slo tipo de dato como se muestra en la tabla 8-2.


76
Tabla 8-2 Directiva Tipo Descripcin
DB BYTE byte
DW WORD palabra
DD DWORD palabra doble
DQ QWORD palabra cudruple
DT TBYTE 10 bytes

Para definir un dato, usa la directiva apropiada. Pon el nombre del campo dato seguido del tipo de
directiva. Si vas a definir una variable, pon el smbolo ? en la parte del operando; si defines una
constante, especifica su valor en el operando. Por ejemplo:

TOTAL DB ?
ZERO DW 0

El primer ejemplo define una variable consistente de un byte, el segundo define una constante de tipo
palabra con un valor de 0.

Algunas veces querrs definir una variable que consista de ms de un slo bloque constructor. Por
ejemplo si quisieras una lista de 5 bytes, puedes definir un campo dato que contenga cinco ? en el
operando separados por comas. Aqu hay un ejemplo que define una variable de cinco palabras dobles.

LISTA DD ?,?,?,?,?

Para definir una constante de ms de un bloque constructor especifica una lista de valores. Por ejemplo,
aqu hay un estatuto que define una constante llamada TABLA, consistente de una lista de 10 nmeros,
cada uno almacenado en un byte.

TABLA DB 50,100,25,75,99,104,23,45,101,87

Puedes especificar valores en decimal, hexadecimal y binario. Por ejemplo aqu hay un estatuto que
define una constante, llamada MIX consistente de tres palabras. La primera guarda 100 decimal, la
segundo F6AEH, y la tercera guarda 1001101B.

MIX DW 100,0F6AEH,1001101B

Puedes inicializar constantes para guardar caracteres. Simplemente pones los caracteres dentro de
comillas dobles o simples. Aqu hay dos ejemplos equivalente para la constante llamada STAR

STAR DB *
STAR DB *



8.4 Definir valores repetidos

Puedes obtener campos de datos que contengan un valor repetido ms de una vez. De hecho puedes
obtener una constante de 35 bytes, inicializada a puros -, o puedes obtener una variable consistente de
200 palabras.

Para hacer esto tienes que especificar el nmero de valores duplicados, con la palabra DUP seguida del
valor entre parntesis. Por ejemplo, para definir una constante llamada GUIONES de 35 bytes, donde
cada byte sea igual a -, usa
77
GUIONES DB 35 DUP(-)

Para definir una variable llamada WLISTA consistente de 200 palabras, usa:

WLISTA DW 200 DUP(?)

Debes poner uno o ms espacios entre el nmero de repeticiones y la palabra DUP por ejemplo lo
siguiente causa un error

WLISTA DW 200DUP(?)

Puedes crear constantes ms complejas combinando el DUP con otros valores. Por ejemplo la siguiente
directiva define una lista de palabras conteniendo los nmeros 1, 2, 3, (10 ceros), 99, 100.

WLISTA DW 1,2,3,10 DUP(0),99,100

Tambin puedes usar un DUP dentro de otro DUP. Por ejemplo, digamos que vamos a definir una tabla
de 100 nmeros cada uno de longitud word. Los nmeros consisten de la secuencia 0, 0, 0, 0, 0, 6, 7, 8, 9,
10 repetidos 10 veces:

WLISTA DW 10 DUP(5 DUP(0),6,7,8,9,10)



8.5 Referenciar campos de datos.

Cuando usas un nombre de un campo de dato dentro de una instruccin, el nombre se refiere al
offset del primer bloque constructor del campo de datos. Por ejemplo, esta directiva DB define una
variable llamada LISTA, consistente de tres bytes:

LISTA DB ?,?,?

Dentro de una instruccin, el nombre LISTA se refiere al offset del primer byte de la variable. Por
ejemplo, digamos que la variable inicia en un offset 120H del segmento de datos, la instruccin:

MOV AH,LISTA

es equivalente a la instruccin

MOV AH,DS:120H

En ambos casos, el efecto de la instruccin es mover el contenido del primer byte de LISTA al registro
AH.

Si quieres bloques subsecuentes del campo de datos, usa una direccin consistente de un valor adicionado
al nombre de la variable. Por ejemplo, para copiar el segundo byte de LIST al registro AH, use un
estatuto como

MOV AH,LIST+1

En general, puedes adicionar un valor al nombre de cualquier campo de datos de esta manera. Por
ejemplo, aqu hay una variable consistente de 500 bytes
78

BLISTA DB 500 DUP(?)

Puedes referirte al primer byte como BLISTA, al segundo como BLISTA+1, al 50 como BLISTA+49, al
188 como BLISTA+187, etc.

Considere la variable WLISTA con 500 palabras.

WLISTA DW 500 DUP(?)

Te puedes referir a la primer palabra como WLISTA, a la segunda como WLISTA+2, a la tercera como
WLISTA+4, etc.

Si tienes campos dato consistentes de bloques grandes, puedes referirte a ellos de manera anloga. Aqu
hay tres variables de tipo palabra doble, palabra cudruple y 10 bytes.

DLISTA DD 500 DUP(?)
QLISTA DQ 500 DUP(?)
TLISTA DT 500 DUP(?)

Por ejemplo, para referirte a la segunda palabra doble de DLISTA, usa DLISTA+4; para referirse a la
tercera palabra cudruple de QLISTA, use QLISTA+16; para referirte al grupo 13 de TLISTA usa
TLISTA+120.

Un modo conveniente de procesar todos los elementos de tales listas es usar un registro ndice. Por
ejemplo para procesar cada palabra doble, puedes usar el operando
DLISTA[DI]

Inicie DI con el valor 0 e incremente DI en 4. As DI tomar los valores 0, 4, 8, 16...

DLISTA[DI] toma los valores

DLISTA+0, DLISTA+4, DLISTA+8, DLISTA+16...



8.6 Usar la directiva DB con caracteres.

La directiva DB define campos dato para guardar bytes. Cada byte puede mantener un carcter o un
nmero. Puedes definir constantes que contengan un carcter, especificando el carcter dentro de comillas
dobles o simples. Si quieres definir ms de un carcter consecutivo, puede especificar una serie de
caracteres:

BIRD DB R,o,b,i,n

Para ahorrar espacio el ensamblador te permite especificar una secuencia de caracteres entre comillas
como un conjunto. Cada carcter es almacenado en un byte de la constante:

BIRD DB Robin

El ensamblador no te permite almacenar bytes que contengan comillas, a menos que utilices una comillas
diferentes para la expresin, por ejemplo:
79

SCOMILLA DB Dont forget to
DCOMILLA DB say Hello to the litte Nipper for me.

Ocasionalmente querrs usar un carcter que no tenga un smbolo asociado a el. En este caso especifica el
cdigo ASCII del carcter, en decimal o hex, sin comillas. Ejemplo:

MSG DB Hola, como estas viejo?, 0DH, 0AH

Tambin puedes combinar caracteres definidos por comillas y cdigo ASCII. Veamos un ejemplo. Vamos
a definir una constante similar a lo anterior, con la excepcin que adicionaremos al final un $. (Hay
ocasiones en que el smbolo de pesos es til como marcador de fin de lnea).
Puedes especificar el ltimo carcter como $ o en su cdigo ASCII 24H (36 decimal). Aqu estn los
estatutos equivalentes:

MESSAGE DB Hola, como estas viejo?, 0DH, 0AH, $
MESSAGE DB Hola, como estas viejo?, 0DH, 0AH, 24H
MESSAGE DB Hola, como estas viejo?, 0DH, 0AH, 36



8.7 Usar la Directiva DB con nmeros.

Sabemos que cuando quieres almacenar nmeros puedes usar bytes, usualmente de dos maneras
aritmticas. Nmeros con signo o sin signo.

Si usas nmeros sin signo, estarn en el rango 0 a 255; si usas nmeros con signo, estarn entre -128 a
127. Estos rangos representan los valores ms pequeo y ms grandes que puedes almacenar en un byte (
8 bits). Si quieres usar nmeros que estn ms all de esos valores, debes usar unidades de
almacenamiento ms grandes (palabras, palabras dobles, etc.) Cuando especificas nmeros puedes usar
decimales, hex, o binarios. Slo asegrate que los nmeros no sean muy grandes o muy pequeos. La
informacin relevante esta reunida en la tabla 8-3

Veamos un par de ejemplos. El primero muestra una constante que esta inicializada con una secuencia de
nmeros sin signo

URIGHT DB 0,34,0FFH,47,1001101B

Aqu hay una constante que es inicializada con una secuencia de nmeros con signo.

SRIGHT DB 0, -34, 127, -128, -80H, -100010B

Aqu hay dos estatutos que pueden causar errores. el primero usa nmeros sin signo que ocupan mucho
espacio; el segundo usa nmeros con signo que usan mucho espacio tambin.

UWRONG DB 256,123H,101010101010B
WRONG DB -3333, 999, -0FFFH, -111110000011111B

(Podras preguntar Como le hace el procesador para saber si estoy usando nmeros con signo o sin
signo?. en algunos casos esto no importa, en otros es t responsabilidad, usar instrucciones diferentes
para cada tipo.)

80
Tabla 8-3 Tipo de nmero Rango permitido
sin signo 0 a 255
con signo -128 a 127



8.8 Usar la directiva DW con caracteres.

La directiva DW define campos datos del tamao de una palabra. Cada palabra puede mantener dos
caracteres, un nmero o un offset.

Por ejemplo el siguiente estatuto define una constante llamada DOSCAR a un valor de 13:

DOSCAR DW 13

En este caso, el byte izquierdo de DOSCAR esta puesto al valor del cdigo ASCII 1, el byte derecho esta
puesto al valor del cdigo ASCII de 3. As DOSCAR contiene 3133H.

Si especificas un slo carcter, el ensamblador pone el lado izquierdo a 00H y el lado derecho al valor
del cdigo ASCII del carcter. Por ejemplo el estatuto

UNCAR DW 1

Pone la constante UNCAR a 0031H.
No puedes usar la directiva DW para definir una constante consistente de una secuencia de caracteres. Por
ejemplo obtendrs un error si tratas de definir palabras como

WCARAC DW 12345



8.9 Usar la Directiva DW con nmeros.

Como los bytes, las palabras pueden guardar nmeros con signo y sin signo. La diferencia principal
es la longitud la palabra puede guardar valores ms grandes que el byte.. Los rangos de ambos tipos se
muestran en la tabla 8-4.

Veamos un par de ejemplos. El primero muestra una constante que esta inicializada con una secuencia de
nmeros sin signo

URIGHT DW 0,34999,0FFAEH,47,101101001101B

Aqu hay una constante que es inicializada con una secuencia de nmeros con signo.

RIGHT DW 0, -31999, -800H, 32767, -128, -100010001000B

Aqu hay dos estatutos que pueden causar errores. el primero usa nmeros sin signo que ocupan mucho
espacio; el segundo usa nmeros con signo que usan mucho espacio tambin.

UWRONG DW 65536,0FFFABH,101010101010101010101010B
WRONG DW -876543, 99999, -0FFFFFH, -1111100000111110000B

81
Tabla 8-4 Tipo de nmero Rango permitido
sin signo 0 a 65535
con signo -32768 a 32767



8.10 Usar la Directiva DW con offsets.

Una palabra que contiene 16 bits puede contener un offset. Esto es til cuando necesitas trabajar con
direcciones. Tpicamente esta podra ser una direccin de un campo dato o un procedimiento. Para
inicializar una palabra con un offset, especifica el nombre del offset del campo dato que quieras. Por
ejemplo aqu hay estatutos que definen campos dato. El primero es una variable llamada LISTA,
consistente de 100 bytes, el segundo es una constante llamada LOFFSET que contiene el desplazamiento
del primer byte a LISTA.

LISTA DB 100 DUP(?)
LOFFSET DW LISTA

Tambin puedes especificar el nombre de un procedimiento. Por ejemplo, si DISPLAY es el nombre de
un procedimiento, puedes usar

OFFSET DW DISPLAY

Por supuesto el offset es relativo al inicio del segmento en el cual aparece. (Los campos dato estarn en el
segmento de datos o extra; los procedimientos estarn en el segmento de cdigo).



8.11 Usar la Directiva DD con caracteres.

La Directiva DD define campos de datos del tamao de un palabra doble. Cada doble palabra puede
almacenar dos caracteres o un nmero o una direccin completa. El ensamblador te permite definir una
doble palabra que tenga uno o dos caracteres. Los caracteres definidos estarn al inicio de la primer
palabra. Los otros bytes sern 0.
Por ejemplo en estatuto

UNCAR DD A

aparta una doble palabra que contiene 41000000H. El estatuto

DOSCAR DD AB

Apartar una doble palabra que contiene 41420000H.
No puedes especificar ms de dos caracteres. Por ejemplo la siguiente instruccin causar un error:

BADCHAR DB ABC






82
8.12 Usar la directiva DD con nmeros.

Las palabras dobles son usadas para guardar nmeros. Desafortunadamente, sin mucha
programacin extra, el procesador slo puede trabajar con bytes y words. Sin embargo un coprocesador
matemtico puede trabajar con nmeros ms grandes.

Primero las dobles palabras pueden guardar nmeros en el rango -2147483648 a 2147483647. Segundo
las palabras dobles pueden guardar un nmero llamado de punto flotante.

Cuando usas palabras dobles, puedes almacenar nmeros positivos y negativos en punto flotante en el
rango aproximado de 10
-38
a 10
38
.

La tabla 8-5 muestra el rango de nmeros que puedes almacenar en una palabra doble.

Tabla 8-5 Tipo de nmero Rango permitido
con signo -2147483648 a 2147483647
punto flotante positivos y negativos: 10
-38
a 10
38


El ensamblador considera los nmeros de notacin cientfica como los nmeros de punto flotante.
Aqu hay un par de ejemplos. El primero muestra una constante que es inicializada a una secuencia de
nmeros con signo

SRIGHT DD 0,83,123456789,0F5BCDH,11110000111100001111B

Aqu hay una constante incializada a una secuencia de nmeros en punto flotante

FRIGHT DD 0,2.178,-3.141592,3.12E10,56.1E-12,1E-10

Aqu hay dos estatutos que pueden causar un error. El primero utiliza nmeros con signo que usan mucho
espacio; el segundo usa punto flotante fuera de rango:

SWRONG DD 12345678901,-999999999999
FWRONG DD 1.23E100,1E-100

en el ltimo ejemplo, el segundo nmero es muy pequeo; 1x10 -100. En lugar de desplegar un mensaje
de error, el ensamblador tratar este nmero como 0.



8.13 Usar la Directiva DD con direccionamiento.

Como explique en el capitulo 4, una direccin completa consiste de una direccin de segmento y un
offset. Una palabra doble tiene suficiente espacio (32 bits) para guardar una direccin completa. Esto es
til cuando necesitas usar una direccin de un dato o un procedimiento, si necesitas slo el offset puedes
guardarlo en la palabra.

Para inicializar un doble palabra con una direccin completa, especifica el nombre del campo cuyo offset
necesitas. Por ejemplo, aqu hay dos estatutos que definen dos campos de datos. El primero es la variable
llamada LISTA que consiste de 100 bytes, la segunda es una constante llamada LDIREC que contiene el
segmento y el offset del primer byte de LISTA.

LISTA DB 100 DUP(?)
83
LDIREC DD LISTA

Tambin puedes especificar el nombre de un procedimiento. Por ejemplo, si DISPLAY es un
procedimiento, podras usar

DDIREC DD DISPLAY

NOTA: El ensamblador pone el offset en la izquierda de la palabra doble y el segmento de direccin a la
derecha.



8.14 Usar la directiva DQ.

La directiva DQ define una palabra cudruple, y puede guardar un nmero o uno o dos caracteres.
En la prctica las palabras cudruples son usadas para guardar nmero del coprocesador matemtico. Una
palabra cudruple puede almacenar nmeros con signo o de punto flotante. Esto lo muestra la tabla 8-6.

Tabla 8-6 Tipo de nmero Rango permitido
con signo -922337203685477808 a 922337203685477807
punto flotante positivos y negativos: 10
-308
a 10
308




8.15 Usar la directiva DT.

La directiva DT define datos que constan de 10 bytes. Para este tipo de datos se aplican las mismas
reglas que para las palabras dobles y cudruples. La directiva DT es usada normalmente para guardar
datos del coprocesador matemtico.

Un grupo de 10 bytes puede guardar dos tipos de nmeros: punto flotante y el decimal empacado. La
tabla 8-7 muestra el rango que puede almacenar cada grupo de valores

Tabla 8-7 Tipo de nmero Rango permitido
punto flotante positivos y negativos: 10
-4932
a 10
4932

decimal empacado -999999999999999999 a 999999999999999999



8.16 Direccionar campos sin nombre.

No tienes que asignar un nombre a cada campo que definas, puedes referirte a cualquier locacin
dando la direccin relativa a un nombre previo. Por ejemplo, considere la siguiente definicin de datos:

TABLA DB 1,2,3,4,5
DB ?,?
DB 8,9,10

Este estatuto define una tabla de 10 bytes. Los primeros cinco bytes y los ltimos tres estn inicializados
a valores especficos. Los bytes 6 y 7 estn definidos como variables. Esta combinacin de definiciones
es til cuando tienes campos con parte variable y constante.

84
Lo importante es que el ensamblador aparta espacio para datos en el mismo orden en que los encuentra.
Ya sea que puedo referirme a los bytes separados de la tabla como TABLA, TABLA+1, TABLA+2, etc.
Tambin puedes referirte a bytes subsecuentes de la misma manera, aunque no estn declarados en la
misma lnea.

Por ejemplo puedes referirte a los bytes 6 y 7 como TABLA+5 y TABLA+6, y puedes referirte a los
siguientes bytes como TABLA+7, TABLA+8 y TABLA+9. En la prctica tambin podras usar una
expresin como esta

TABLA[SI]

Para referirte a los bytes de la tabla.

Debes tener cuidado en mantener las referencias adecuadas. En el caso anterior, debes tener cuidado de
que el valor de SI no exceda a 9. Si lo hace tu programa puede hacer referencia a bytes equivocados. Por
ejemplo si SI tiene un valor de 100, la expresin

TABLE[SI]

har referencia a un byte que esta 100 bytes ms all de tabla, sin importar si est en otro segmento.



8.17 Atributos.

Un atributo describe una caracterstica particular de un dato. Cada dato puede tener cinco diferentes
atributos, mostrados en la tabla 8-8. Aparte de los datos, la nica entidad que tambin tiene atributos son
las etiquetas, que sern vistas despus. Una etiqueta tiene tres atributos.


Tabla 8-8 Los cinco atributos de un campo dato.

TYPE
LENGTH
SIZE
SEG
OFFSET

Cada atributo describe una caracterstica de un dato. El atributo TYPE es el nmero de bytes reservados
para cada bloque constructor en el campo del dato. Por ejemplo, si el campo dato consiste de bytes, su
tipo es 1; si el campo dato consiste de palabras, su tipo es 2; si el campo dato consiste de palabras
cudruples su tipo es 8, etc.

El atributo LENGTH es el nmero total de bloques constructores de que consta el campo dato. Por
ejemplo, una variable que consiste de 200 palabras tiene una longitud de 200; una constante de 50 bytes
tiene una longitud de 50.

El atributo SIZE es el nmero total de bytes reservados para el campo de datos. Por ejemplo, una variable
que consiste de 200 palabras tiene un tamao de 400 bytes; una constante que consta de 50 bytes tiene un
tamao de 50 bytes.

85
Tambin puedes obtener el tamao de un campo multiplicando el tipo por la longitud (TYPE x
LENGTH).
Los ltimos dos atributos de un campo dato son SEG y OFFSET. El atributo SEG es la direccin de inicio
de segmento en el cual el dato est situado. Como los datos usualmente estn en el segmento de datos o
extra, el atributo SEG tiene la misma direccin que los registros DS o ES. El atributo OFFSET es la
direccin del primer byte del campo de datos.

Los atributos SEG y OFFSET juntos describen la direccin completa de un dato. Estos atributos son
tiles cuando quieres usar la direccin de un dato, en lugar de su valor.

Aqu hay algunos ejemplos de definiciones de datos, con la descripcin de algunos de sus atributos.

TEMP DW 200 DUP(?)
CEROS DB 50 DUP(0)
VALOR DQ ?

El primer ejemplo define una variable llamada TEMP que consiste de 200 palabras. TEMP tiene un tipo
2, una longitud de 200, y un tamao de 400.

El segundo ejemplo define una constante llamada CEROS que consiste de 50 bytes inicializados todos a
0. CEROS tiene un tipo de 1, una longitud de 50, y un tamao de 50.

El tercer ejemplo define una variable llamada VALOR consistente de una palabra cudruple. VALOR
tiene un tipo de 8, una longitud de 1 y un tamao de 8.



8.18 Operadores que usan los atributos: TYPE, LENGTH, SIZE, SEG Y OFFSET.

Un operador es un smbolo usado en el ensamblamiento para afectar el valor de un operando. Como
las directivas, los operadores son reconocidos por el ensamblador, y no corresponden a lenguaje mquina.
El ensamblador ofrece varios tipos de operadores. En este captulo describir los ms tiles aplicables a
los campos de datos.

Existen cinco operadores que te permiten hacer referencia a los atributos de un campo de datos.

TYPE LENGTH SIZE SEG OFFSET

Para usar estos operadores en un operando, coloca el operador antes del nombre del campo dato. El
ensamblador evaluara la expresin y substituir su valor a la instruccin mquina generada.

Aqu hay algunos ejemplos. Digamos que LISTA es una secuencia de palabras definidos como:

LISTA DW 100 DUP(?)

considere la instruccin

MOV AX,TYPE LISTA

El ensamblador substituir la expresin TYPE LISTA, en esta caso, el nmero 2. As la instruccin
mquina tendr el mismo efecto que

86
MOV AX,2

La instruccin

MOV AX, LENGTH LISTA

es lo mismo que

MOV AX,100

y la instruccin

MOV AX,SIZE LISTA

es lo mismo que

MOV AX,200

Para copiar el desplazamiento de LISTA use esto

MOV AX,OFFSET LISTA

Los operadores de atributos hacen los programas ms fciles de comprender. Por ejemplo la instruccin

MOV AX,LENGTH LISTA

es ms significativa que

MOV AX,100

Los operadores son ms efectivos cundo modificas tus programas. Si por alguna causa aumentaras la
longitud de LISTA de 100 a 250, no tendras que cambiar ningn estatuto que hiciera referencia a la
longitud de la lista con el uso del operador LENGTH.



8.19 Operadores Aritmticos.

Existen varios operadores que pueden usarse para hacer aritmtica simple con las expresiones de
operandos. Estos operadores estn en la tabla 8-9.

Aqu hay algunos ejemplos:

MOV AX,TABLA+10
MOV AX,TABLA+2*(100+66)
TABLA DB 2*1024 DUP(?)
CONTA1 DB 97/10
CONTA2 DB 97 MOD 10

Tabla 8-9 Operadores aritmticos
Operador Significado
+ adicin
87
- resta
* multiplicacin
/ divisin
MOD divisin modular

Es importante que comprendas que los operadores aritmticos son usado slo para especificar clculos
que sern traducidos por el ensamblador. Estos operadores no ejecutan clculos matemticos cuando el
programa corre.

Los operadores aritmticos, como los atributos, hacen los programas ms fciles de comprender. Por
ejemplo, digamos que quieres definir una variable llamada BUFFER, que tenga 12 Kb. 12K es igual a
12,288. As si usas

BUFFER DB 12288 DUP(?)

el significado del nmero es obscuro. Si usas

BUFFER DB 12*1024 DUP(?)

la definicin habla por si misma.

Puedes usar los operadores aritmticos con los operadores de atributos. Por ejemplo aqu hay definiciones
de dos variables. LISTA y GLISTA. GLISTA est definida del doble del tamao de LISTA.

LIST DB 56 DUP(?)
BLISTA DB 2*(SIZE LISTA) DUP(?)



8.20 El operador PTR (pointer).

Cuando haces referencia a un campo de dato, el ensamblador checa el tipo y se asegura que est de
acuerdo con lo que estas tratando de hacer. Por ejemplo digamos que una instruccin copia el valor de la
variable llamada VALOR al registro AH.

MOV AH,VALOR

Si AH tiene un tamao de 8 bits. VALOR debe ser del mismo tamao.

Si VALOR consiste de bytes todo est bien. Sin embargo si VALOR, consiste de un tipo bloque
constructor ms grande (digamos palabra o palabras dobles), el ensamblador encontrar un error. El
mensaje de error ser parecido a:

Operand types must match
Illegal size for item

Muchas de la veces el error es tuyo. Sin embargo, ocasionalmente quieras suprimir esta condicin del
ensamblador. Por ejemplo, digamos que defines TOTAL como una variable consistente de una palabra:

TOTAL DW ?

88
Normalmente, tratas a TOTAL como una palabra. Por ejemplo, puedes copiar el contenido de TOTAL a
un registro de 16 bytes (AX por decir algo).

MOV AX,TOTAL

Sin embargo, puedes accesar los dos bytes de TOTAL, separadamente. Para hacer esto, usa el operador
PTR para decirle al ensamblador que suprima el default del tipo para esa instruccin. Especifica el tipo
que desees despus de PTR, y despus el nombre del campo dato.

El nombre PTR significa apuntador; el operador PTR le dice al ensamblador que pretenda que el
operando es de un tipo particular de dato. Los posibles tipos que puedes usar con el operador PTR estn
en la tabla 8-10.


Tabla 8-10 Tipo Significado
BYTE byte
WORD palabra
DWORD palabra doble
QWORD palabra cudruple
TBYTE grupo de 10 bytes

Aqu hay dos ejemplos:

MOV BH,BYTE PTR TOTAL
MOV CH,BYTE PTR TOTAL+1

La primera instruccin le dice al ensamblador que permita copiar el byte en la locacin TOTAL dentro
del registro BH. La segunda instruccin copia el siguiente byte en el registro CH. Normalmente, no
puedes copiar parte de una variable de 16 bits a un registro de 8 bits. Por ejemplo, si TOTAL es un
palabra, la siguiente instruccin causa un error.

MOV BH,TOTAL

Aqu hay otro ejemplo. Digamos que defines una variable llamada PAR consistente de dos bytes:

PAR DB ?,?

Si quieres copiar los dos bytes de PAR al registro AX, normalmente el ensamblador no te permite copiar
lo siguiente:

MOV AX,PAR

Ahora, si usas el operador PTR suprime el tipo de PAR

MOV AX,WORD PTR PAR

Antes de usar el operador PTR, hay una cosa importante que debes entender. En el captulo 3 mencione
que el ensamblador y el procesador almacenaban los dos bytes de una palabra en orden inverso. DE
hecho si consideramos las siguientes definiciones:

X DB AB
Y DW AB
89

La constante X consiste de dos bytes. El cdigo ASCII de A es 41H y el de B es 42H, as X est
inicializada a 4142H. La constante Y consiste de una palabra, as que los bytes estn en orden inverso, Y
est inicializada como 4241H.

Normalmente, esto no representa problemas. El procesador sabe cuando guardo los valores en orden
inverso. Sin embargo, cuando usas el operador PTR para suprimir el tipo de un campo, el procesador trata
a los datos como si fueran del nuevo tipo. Si accesas la palabra como bytes separados estos estarn en
orden inverso.

Similarmente, cuando accesas 2 bytes como si fueran una palabra el procesador los invierte. La solucin
es usar el operador PTR con cuidado. Algunas veces puedes obtener lo que quieres de maneras diferentes.
Por ejemplo, si realmente quieres copiar los dos bytes de PAR a AX, debes usar instrucciones separadas
para copiar el primer byte en AH y el segundo en AL.

MOV AH,PAR
MOV AL,PAR+1



8.21 La Directiva LABEL.

La directiva LABEL te permite definir nombres con atributos especficos. El formato es

nombre LABEL tipo

El nombre no ocupa espacio en lenguaje mquina del programa. En su lugar, permite hacer referencia de
un modo alternativo a una locacin particular de tu programa. Un nombre definido de este modo es una
etiqueta (LABEL).

Aqu hay un ejemplo:

BNAME LABEL BYTE
WNAME DW 100 DUP(?)

El primer estatuto define una etiqueta BNAME que apunta a un campo dato consistente de bytes. El
segundo estatuto define un campo dato WNAME consistente de palabras.

Como la directiva LABEL no ocupa espacio en lenguaje mquina en el programa, BNAME y WNAME
tiene el mismo desplazamiento. As puedes usar el nombre BNAME para accesar el campo dato como
bytes y ,el nombre WNAME para accesar el campo dato como palabras. Esto es como si el campo dato
tuviera dos nombres.

De hecho, para copiar el contenido de la segunda palabra de WNAME al registro AX, usa

MOV AX,WNAME+2

Sin embargo, si quisieras copiar la primera mitad de esa palabra (1 byte) al registro AH, no puedes usar

MOV AH,WNAME+2

90
debido a que el ensamblador no te permite referenciar bytes dentro de campos dato que consistan de
palabras, debes usar el nombre alterno:
MOV AH,BNAME+2

Esto es muy similar al apuntador PTR para suprimir el tipo:

MOV AH,BYTE PTR WNAME+2

Cuando defines una etiqueta, puedes usar cualquiera de los tipos BYTE, WORD, DWORD, QWORD o
TBYTE. Tambin puedes usar la directiva LABEL para definir etiquetas dentro del segmento de cdigo.
El programa puede usar estas etiquetas para saltar de una instruccin a otra.



8.22 La Directiva EQU (igual a).

La directiva EQU permite definir smbolos que tiene un valor especifico mientras el programa es
ensamblado. El formato es

nombre EQU expresin

Por ejemplo, la siguiente directiva le dice al ensamblador que considere el smbolo K equivalente a 1024:

K EQU 1024

Un igual es til cuando se tiene un programa que usa el mismo valor repetidamente. Puedes usar un igual
para asignar el valor al smbolo que ser tomado as en todo el programa
Por ejemplo, digamos que defines varios campos de datos con valores que son mltiplos de 1K (1024):

CAMPO1 DB 1024 DUP(?)
CAMPO2 DB 2*1024 DUP(?)
CAMPO3 DB 3*1024 DUP(?)

Si defines al smbolo K como lo hicimos antes, puedes usar

CAMPO1 DB K DUP(?)
CAMPO2 DB 2*K DUP(?)
CAMPO3 DB 3*K DUP(?)

Es importante que entiendas que los iguales no generan cdigo mquina, slo son abreviaciones que el
ensamblador tomar en cuenta cuando haga su trabajo.
Los iguale son particularmente tiles cuando tienes estatutos que dependen de valores fundamentales.
Usando iguales, puedes representar los valores de manera simblica. Si estos valores necesitan cambiarse,
lo haces y reensamblas el programa.

Por ejemplo, considere el siguiente igual, el cual pone LSIZE como igual a 100:

LSIZE EQU 100

Dentro del programa puede haber varios estatutos que dependan de ese valor, por ejemplo

WNAME DB LZISE DUP(?)
91
WLISTA DB LSIZE DUP(?)
MOV AX,LSIZE
MOV BX,LSIZE

Cuando ensamblas el programa el ensamblador substituye todos los valores del igual por el valor
respectivo. Sin embargo si decides que el valor nuevo de LSIZE es 200 slo tienes que cambiar el igual y
reensamblar el programa sin cambiar ninguna otra lnea de cdigo.



8.23 Reglas para usar EQUATES.

El nombre de un EQU debe ser nico y no debe ser una palabra reservada. La expresin puede ser
un nmero sin signo entre 0 y 65,535. Puedes usar operadores aritmticos y de atributos, y tambin
puedes especificar el nmero decimal, hex o binario. El binario es usado particularmente para especificar
patrones de bits. Aqu hay algunos ejemplos:

MAX_VAL EQU 157
K EQU 1024
TEN_K EQU 10*K
ESTO EQU 1000011110100110B
HEXVAL EQU 0AF3H
LTIPO EQU TYPE LISTA

Debes asegurarte que el ensamblador comprenda cualquiera de los nombres que usas. Esto es, en un
ejemplo use 10*K, el nombre K debe estar definido antes. Similarmente LISTA debe estar ya
especificado antes de hacer mencin de el, o en otro caso ocurrir un error.

Algunos ensambladores te permiten especificar valores no numricos para guardar secuencias de
caracteres. Sin embargo checa la documentacin del ensamblador para ver si esto se permite. Por ejemplo
podras poner un estatuto como el siguiente:

MESSAGE EQU Hola, como estas viejo?
SALIDA DB MESSAGE

Si necesitas instrucciones igual dentro de tu programa ponlas al comienzo del programa en una seccin
separada, para facilitar su lectura.

Algunos iguales pueden aparecer en el segmento de datos. Estos se explican en la siguiente seccin.



8.24 El contador de locaciones: La directiva $ y la directiva ORG.

El ensamblador mantiene un valor llamado el contador de locaciones que contiene el offset de la
siguiente locacin disponible. Cuando el ensamblador empieza a procesar el programa, el contador de
locacin est en 0. Cada vez que el ensamblador aparta espacio de memoria, para datos o instrucciones, el
valor del contador de locaciones se incrementa.

Veamos un ejemplo. El ensamblador est procesando un programa y el contador de locaciones est en 0.
El ensamblador encuentra la directiva

92
DB 32 DUP(STACK---)

y aparta 100H bytes de almacenamiento. El contador de locaciones tiene el valor 100H.

Dentro del programa, puedes hacer referencia al valor actual del contador de locaciones usando el
smbolo $, por ejemplo, si defines el igual

CURRENT EQU $

El ensamblador definir a CURRENT con el valor del contador de locaciones en el momento en que el
igual se procese.

El carcter $ es usualmente utilizado para encontrar la longitud de una secuencia de caracteres. Por
ejemplo, el siguiente estatuto define un campo dato llamado MSG y uno igual nombrado L_MSG, MSG
contiene una secuencia de caracteres; L_MSG contiene la longitud de MSG.

MSG DB Hola
L_MSG EQU $-MSG

En este ejemplo, la expresin $-MSG representa el valor actual del contador de locacin menos el offset
de MSG -en otras palabras la longitud de MSG.

Esta tcnica es til debido a que permite cambiar la cadena sin cambiar el igual. Tambin hace
innecesario que tengas que definir los caracteres contados como

L_MSG EQU 5

Si cambias a MSG, su longitud es automticamente recomputada.

Tambin puedes poner el valor del contador de locaciones a un valor exacto usando la directiva ORG
(origen). El formato es

ORG valor

Existe slo un uso comn para esta directiva: instruir al ensamblador para que empiece con un contador
de locaciones mayor que 0. Esto es importante cuando usas archivos COM. En tales casos, la siguiente
directiva es usada al inicio del programa:

ORG 100H

Esto le dice al ensamblador que inicie a ensamblar con un desplazamiento de 100H.

E principio puedes usar la directiva ORG para propsitos ms exticos. Por ejemplo, dejar un hueco de
diez bytes a la mitad del programa usando

ORG $+10

Sin embargo estas situaciones son raras.



8.25 Un ejemplo del uso de iguales.
93

El programa de la figura 8-1 ilustra como y donde se pueden usar los iguales.
Figura 8-1 Un programa que usa iguales

PAGE 58,132
;------------------------------------------------------------------------------------
; EQUATES
;
; Proposito:
; un ejemplo de un programa que usa iguales
; -----------------------------------------------------------------------------------

; Ajustar el titulo y el conjunto de instrucciones
TITLE EQUATES -programa que usa iguales
.286

;-------------------------------------------------------------- segmento STACK
SSEG SEGMENT STACK
DB 32 DUP(STACK---)
SSEG ENDS

;--------------------------------------------------------------- EQUATES
CR EQU ODH ; Cdigo ASCII del retorno de carro
LF EQU 0AH ; Cdigo ASCII de nueva lnea
DISPLAY EQU 0001H ; Manejador de archivo para el mensaje

;--------------------------------------------------------------- segmento DATA
DSEG SEGMENT
MSG DB Hola, como ests viejo?, CR, LF
L_MSG EQU $-MSG
DSEG ENDS

;--------------------------------------------------------------- segmento CODE
CSEG SEGMENT CODE
ASSUME CS:CSEG, SS:SSEG; DS:DSEG
PAGE
;----------------------------------------------------------------------------------
; MAIN (programa principal)
;
; Proposito:
; Desplegar un mensaje en la pantalla
;
; Entrada:
; -- ninguna --
;
; Salida:
; El mensaje es desplegado en la pantalla
;
; Procedimientos:
; -- ninguno --
;----------------------------------------------------------------------------------

; Procedimiento: MAIN
MAIN PROC FAR
; Salvar la direccion para poder regresar a DOS
PUSH DS
PUSH 0

; Actualizar el registro de segmento
MOV AX,DSEG
MOV DS,AX

94
; Desplegar el mensaje
MOV BX,DISPLAY
LEA DX,MSG
MOV CX,L_MSG
MOV AH,40H
INT 21H

; Regresar a DOS
RET

; Fin de procedimiento: MAIN
MAIN ENDP

; Fin de segmento de codigo
CSEG ENDS

;--------------------------------------------------------------- Fin de programa
END MAIN


{_____________o___________}


































95



CAPITULO 9 LAS INSTRUCCIONES GENERALES


En este captulo aprenders cuales son las instrucciones ms generales del ensamblador. Estas
instrucciones copian datos entre los registros, las locaciones de memoria y la pila. Tambin conocers la
instruccin ms extraa de todas. La instruccin que no hace nada.


Nuevos Trminos.

Fuente. Un operando al cual los datos sern copiados.

Destino. Un operando del cual son copiados los datos.

NOP. Un instruccin que no hace nada.



9.1 Operandos Fuente y Destino.

Como explique en el capitulo 5, un operando es la parte de una instruccin sobre el cual el
procesador acta. Por ejemplo, en la instruccin

PUSH AX

el operando es AX. Muchas instrucciones tienen dos operandos, separados con una coma, como en el
ejemplo:

MOV AX,TABLA

Algunas de estas instrucciones involucran la copia de datos de un operando a otro. En tales casos, los
datos que son copiados son llamados fuente, y el lugar a donde los datos son copiados es llamado destino.
Como regla el fuente permanece sin cambio y el destino cambia.

Con las instrucciones que requieren de especificar fuente y destino, el destino siempre va primero,
seguido por una coma, y despus el fuente. De hecho, en el ejemplo anterior, la fuente es TABLA y el
destino es AX. Aqu hay otro ejemplo:

ADD CX,DX

Esta instruccin adiciona el valor de la fuente DX al valor del destino CX. Slo el destino cambia de
valor.



9.2 Copiar informacin: MOV.

96
La instruccin MOV copia datos de un lugar a otro. (Piensa que en lugar de MOV la instruccin es
un copy). MOV es la ms importante de las instrucciones. Por ejemplo, de las 500 instrucciones en el
BIOS para un tipo particular de computadora el 34.6% (173) son instrucciones MOV.

El formato de la instruccin MOV es:

MOV destino,fuente

MOV copia los datos del operando de la derecha al operando de la izquierda, algo parecido a lo siguiente

MOV destino fuente

Los datos de la fuente no cambian, el destino puede ser un registro o una locacin de memoria (un campo
dato); el fuente puede ser un registro, una locacin de memoria o un valor inmediato.

Veamos algunos ejemplos de la instruccin MOV que copia valores inmediatos. La primera instruccin
copia un cero al registro AX, el segundo copia 200H al registro BP; el tercero copia el valor de 2*1024 a
un campo dato llamado TOTAL:

MOV AX,0
MOV BP,200H
MOV TOTAL,2*1024

Ahora, aqu hay algunas instrucciones que copian su valor a un registro. La primera instruccin copia el
valor de SI a BX; el segundo copia AX a ES; el tercero copia DS al campo dato SEGADDR:

MOV BX,SI
MOV ES,AX
MOV SEGADDR,DS

Finalmente, aqu hay instrucciones que copian el valor de una locacin de memoria. La primera
instruccin copia el valor de TOTAL al registro AX; el segundo copia el valor de LISTA[SI] a BH:

MOV AX,TOTAL
MOV BH,LISTA[SI]



9.3 Restricciones del uso del comando MOV.

Est seccin discute las restricciones de la instruccin MOV para copiar datos.
Primero, la longitud de la fuente debe ser igual que la longitud del destino. Por ejemplo, no puedes copiar
un byte a una palabra. La siguiente instruccin causa un error, cuando trata de copiar el registro AX (16
bits) al registro BL (8 bits):

MOV BL,DX

Similarmente, la siguiente instruccin no se permite a menos que SEGADDR sea una palabra y LISTA
consista de bytes:

MOV SEGADDR,DS
MOV BH,LISTA[SI]
97

La siguientes dos restricciones evitan que uses el registro IP como fuente o destino, y que uses el registro
CS como destino. Por ejemplo, la siguientes instrucciones causan un error:

MOV CS,8970H
MOV AX,IP

El porque de estas dos restricciones es la siguiente: Como explique en el capitulo 4, los registros IP y CS
son usados para rastrear el direccionamiento dentro del segmento de cdigo cuando el programa se
ejecuta. El registro CS contiene la direccin de segmento y la instruccin IP contiene el offset de la
siguiente instruccin a ejecutar.

Similarmente, todos los registros de segmentos contienen valores importantes que deben ser protegidos.
As, estas son las siguientes restricciones: No puedes copiar un valor inmediato a un registro de segmento
y no puedes copiar un registro de segmento a otro. Por ejemplo, no puedes usar los siguientes comandos:

MOV SS,1000H
MOV ES,DS

Existe una restriccin ms: No puedes copiar una direccin de segmento directamente a un registro de
segmento. Entonces al principio del programa no puedes direccionar el segmento de datos o extra
copindolo directamente la direccin de segmento para DS y ES. Debes copiar la direccin a un registro
general, tal como AX y entonces copiarlo a DS o ES. Veamos lo anterior:

MOV AX,DSEG
MOV DS,AX

La ltima restriccin del comando MOV es que no puedes copiar datos desde un campo dato (locacin de
memoria) a otro. Por ejemplo, si CAMPO1 y CAMPO2 son dos campos de datos, entonces no puedes
copiar la instruccin:

MOV CAMPO1,CAMPO2

Tienes dos opciones para copiar un campo de datos a otro. Si el dato es corto, puedes copiarlo usando un
registro como intermediario:

MOV AX,CAMPO1
MOV CAMPO2,AX

La otra alternativa ser usar las instrucciones MOVSB o MOVSW, las cuales sern explicadas en el
captulo 15. La figura 9-1 muestra un sumario de las restricciones de la instruccin MOV

Figura 9-1 Restricciones
+ El fuente y el destino debe ser de la misma longitud

No puedes copiar
+ De o hacia el registro IP
+ Hacia el registro CS
+ De un valor inmediato a un registro de segmento
+ De un registro de segmento a otro registro de segmento
+ De una direccin de segmento directamente a otro registro de segmento
+ De una locacin de memoria a otra
98





9.4 Intercambio de informacin: XCHG.

La instruccin XCHG intercambia informacin entre dos registros o entre un registro y un campo
dato. Aqu hay algunos ejemplos:

XCHG AX,BX
XCHG AX,SUM
XCHG BLISTA[SI]
XCHG CH,CL

EL primer ejemplo intercambia el contenido de AX y BX. El siguiente intercambia el contenido de AX
con el valor de un campo dato SUM. El tercer ejemplo intercambia los valores de BLISTA[SI] y DL. El
ltimo ejemplo intercambia CH y CL.

Existe solo dos restricciones para usar la instruccin XCHG. Primero ambos operandos deben ser de la
misma longitud, ya sea bytes o words. En el ejemplo anterior, SUM debe ser una palabra y BLISTA debe
consistir de bytes. Las siguientes instrucciones causan un error debido a sus diferencias de tipo.
(Asumiendo que WLISTA consta de palabras):

XCHG AX,BL
XCHG WLISTA[SI],DL

La segunda restriccin es que no puedes intercambiar el contenido de un segmento de registro. Por
ejemplo la siguiente instruccin causar un error

XCHG AX,ES

La instruccin XCHG no te permite intercambiar el contenido de dos campos dato. Por ejemplo si tienes
CAMPO1 y CAMPO2 ambos palabras, no puedes usar el comando:

XCHG CAMPO1,CAMPO2

Sin embargo hay varias maneras de lograr el mismo efecto. por ejemplo

MOV AX,CAMPO1
XCHG AX,CAMPO2
MOV CAMPO1,AX



9.5 Obtener un desplazamiento: LEA.

Como explique en el captulo 8, puedes obtener un desplazamiento de un campo dato usando el
operador OFFSET. Por ejemplo, para copiar el desplazamiento del campo dato TOTAL al registro AX,
use

MOV AX,OFFSET TOTAL
99

Sin embargo, este mtodo tiene una limitacin. El campo dato sobre el cual acta el OFFSET solo
funciona con el nombre; no funciona sobre un direccionamiento indexado como TOTAL[BX].

Obtener el direccionamiento de un campo dato es til cuando pasas direcciones de un procedimiento a
otro. Afortunadamente, hay una instruccin que puede hacer el trabajo: LEA (la cual significa cargar la
direccin efectiva). Cuando usas la instruccin LEA no necesitas usar el operador OFFSET. De hecho,
LEA obtiene automticamente el offset del segundo operando y se lo pasa al primero.

Por ejemplo, para copiar el offset de TOTAL[BX] a AX, use el comando:

LEA AX,TOTAL[BX]

Esta es la forma de usar la instruccin LEA: Digamos que necesitas que un procedimiento llamado
FIND_SUM sume una lista de nmeros almacenados en palabras y regrese la suma. El procedimiento
espera a AX apuntado a la lista y BX apuntado al lugar para almacenar la suma, si defines esto ltimo
como

LISTA DW 1,2,3,4,5,6,7,8,9,10
SUM DW ?

podras usar la siguiente instruccin para llamar al procedimiento

LEA AX,LISTA
LEA BX,SUM
CALL FIND_SUM



9.6 Obtener una direccin completa: LDS y LES.

Las instrucciones LDS y LES estn diseadas para un propsito particular: copiar una direccin
completa (offset y direccin de segmento) a un par de registros. LDS significa cargar el registro de
segmento de datos y LES significa cargar el registro del segmento extra.

La instruccin LDS tiene dos operandos un registro y la direccin de una palabra doble. La palabra doble
debe contener la direccin completa (esto es, los 16-bits del offset, seguidos de los 16-bits de la direccin
de segmento). LDS copia este offset y la direccin de segmento a dos registros; el offset se copia al
registro que especifiques y la direccin de segmento se copia al registro DS.

Por ejemplo, digamos que T_ADDR es una palabra doble que guarda la direccin completa de TABLA y
T_ADDR est definida dentro del segmento de datos como sigue:

TABLA DB 100 DUP(?)
T_ADDR DD TABLA

La instruccin

LDS DX,T_ADDR

Copia el offset de TABLA a DX y el segmento de direccin de TABLA a DS, como lo haran las
siguientes instrucciones:
100

LEA DX,
MOV DS,SEG TABLA

La instruccin LES es similar a LDS. La nica diferencia es que LES copia la direccin de segmento al
registro ES.

Podras preguntarte cuando es pertinente usar estas instrucciones. El uso ms comn es para preparar las
instrucciones MOVSB y MOVSW (que se explicarn en el captulo 15): Para usar estas instrucciones,
debes colocar primero cierto valor en los registros. En particular, debes poner ES y DI al segmento de
direccin y offset del campo dato.

Aqu hay un ejemplo de como puedes usar LES. Digamos que CAMPO y I_ADDR estn definidas en el
segmento de datos como

CAMPO DW 20 DUP(?)
I_ADDR DD CAMPO

La siguiente instruccin copia la direccin de segmento de CAMPO a ES y el offset de CAMPO a DI:

LES DI,I_ADDR



9.7 Copiar desde y hacia la Pila: PUSH y POP.

La instruccin PUSH copia informacin hacia la pila; la instruccin POP saca datos de la pila.
Ambos PUSH y POP ocupan un operando de 16-bits. Aqu hay algunos ejemplos:

PUSH AX
PUSH TABLA[BX]+24
PUSH TYPE LISTA
PUSH 1024
PUSH 0
POP DS
POP VALOR

La instruccin PUSH copia el operando al tope de la pila. La instruccin POP copia del tope de la pila a
un operando, despus de lo cual la siguiente entrada se convierte en la pila. Existen varios usos
importantes para el PUSH y el POP. Primero, los procedimientos pueden pasar informacin de regreso y
hacia otros procedimientos por medio de la pila.

Aqu est un ejemplo: Digamos que un procedimiento necesita llamar a otro llamado CALCULO.
CALCULO requiere cinco valores en orden para ejecutar algunos clculos. En el procedimiento que
llama, estos valores son llamados TOTAL; SUBTOTAL, IMP, DESC, y CAMPO. El programa que llama
podra meter esos valores en la pila y entonces hacer la llamada a CALCULO:

PUSH TOTAL
PUSH SUBTOTAL
PUSH IMP
PUSH DESC
PUSH CAMPO
101
CALL CALCULO

El procedimiento calculo podra extraer sus datos de entrada de la pila apropiadamente. (Estos detalles se
explican en el captulo 12).
El segundo uso importante del PUSH y el POP es usar la pila como rea de almacenamiento temporal.
Esto es til para almacenar resultados intermedios de clculos complejos o preservar los valores actuales
de los registros que de otra forma se perderan.

Por ejemplo, las siguientes instrucciones podran usarse para mover el contenido del CAMPO1 y el
CAMPO2. (La instruccin MOVSB se explica en el captulo 15).

; copiar el contenido del CAMPO1 al CAMPO2
LEA SI,CAMPO1
LEA DI,CAMPO2
MOV CX,LENGTH CAMPO1
CLD
REP MOVSB

Infortunadamente esta secuencia de instrucciones cambia los valores de SI, DI y CX. Y que si estos datos
contienen informacin importante que no debe perderse.
La solucin para preservar los valores de DI, SI y CX es meterlos a la pila, despus de que MOV y
MOVSB son ejecutadas.

; salvar el contenido de SI, DI, CX
PUSH SI
PUSH DI
PUSH CX
; copiar el contenido del CAMPO1 al CAMPO2
LEA SI,CAMPO1
LEA DI,CAMPO2
MOV CX,LENGTH CAMPO1
CLD
REP MOVSB
; restaurar los valores de los registros SI, DI, y CX
POP CX
POP DI
POP SI



9.8 Salvar todos los registros: PUSHA y POPA

Como puedes ver en el ltimo ejemplo de la seccin previa, algunas veces querrs salvar ms de un
registro. La instruccin PUSHA mete los valores de los siguientes registros a la pila, en el orden en que
aparecen:

AX CX DX BX SP BP SI DI

PUSHA significa push all. Como puedes ver, el nombre est raro porque slo salva 8 de los 14
registros. (Los otros registros rara vez necesitan ser salvados).

102
La instruccin POPA restaura los valores de los registros sacndolos de la pila. Siempre que uses un
POPA debes haber usado antes un PUSHA. Aqu hay un ejemplo de la seccin previa:

; copiar el contenido de CAMPO1 a CAMPO2
PUSHA
LEA SI,CAMPO1
LEA DI,CAMPO2
MOV CX,LENGTH CAMPO1
CLD
REP MOVSB
POPA

Es una buena prctica de programacin usar el PUSHA al inicio de cada procedimiento y POPA al final.
Esto asegura que la llamada al procedimiento no causo cambios al programa que llamo.

Por supuesto, si un registro va a ser usado para pasar un valor de regreso al procedimiento que llamo,
debes asegurarte que la actualizacin del registro est despus de la instruccin POPA. Veamos un
ejemplo

; actualizar los registros y regresar al programa que llamo
POPA
MOV AX,VALOR
RET

Si usas

MOV AX,VALOR
POPA
RET

El valor de VALOR ser sobrescrito por la instruccin POPA.

Como ltimo punto ya que el registro SP guarda el valor del tope de la pila debemos asegurarnos de no
modificar ese registro o estaremos en problemas.



9.9 Salvar el registro de Banderas: PUSHF y POPF

El registro de banderas es un registro especial el cual esta dividido en 16 bits donde cada bit es
tratado como una entidad separada. Estos bits tiene varios usos que sern discutidos en el captulo 10.

Por ahora, necesitas comprender que algunas instrucciones tienen un side-effect cambiando algunos de
estos bits. As es importante algunas veces que puedas salvar y restaurar el registro de banderas; POPF
saca los valores de la pila y restaura este registro.

Salvar el registro de banderas es til cuando quieres prevenir que ciertas instrucciones cambien esos bits.
Por ejemplo si adicionas el contenido de AX al contenido de BX usando la instruccin:

ADD BX,AX

103
La instruccin ADD modifica algunos de los bits del registro de banderas. si quieres proteger estos bits,
todo lo que necesitas hacer es salvar y restaurar ese registro.

PUSHF
ADD BX,AX
POPF

Similarmente, podras proteger el registro de banderas de las instrucciones de un procedimiento llamado
DISPLAY de est manera:

PUSHF
CALL DISPLAY
POPF



9.10 La instruccin que no hace nada: NOP

Por extrao que parezca, existe una instruccin que no hace nada llamada NOP. Esta instruccin
puede ser utilizada para sustituir cdigo errneo en un programa ejecutable, para esto solo tienes que
sustituir el cdigo hex de la parte del programa que falla por el cdigo hex de NOP (90H). Esto te permite
probar un programa sin la parte errnea para detectar si lo dems esta bien. Tambin se puede usar la
instruccin NOP para ajustar un segmento de cdigo al limite de un prrafo de manera exacta
completando con instrucciones NOP:


{_____________o___________}

























104







CAPITULO 10 CONTROL DEL FLUJO


El control de flujo es la descripcin del orden en el cual las instrucciones en un programa se
ejecutarn. En este captulo aprenders cuales son los estatutos que pueden definir patrones utilizados
comnmente en lenguajes de alto nivel, tales como ciclos, anidaciones y decisiones.
El captulo inicia con una discusin acerca de las herramientas necesarias (etiquetas y banderas), seguido
por las explicaciones de las instrucciones para el control del flujo.


Nuevos Trminos.

Control de flujo. Una descripcin del orden en el cual las instrucciones de un programa son ejecutadas.

Far. Describe una direccin que puede ser referenciada por otro segmento.

Near. Describe una direccin que puede ser referenciada slo dentro de su mismo segmento.

Flag. Un bit cuyo valor 0 1, es usado para indicar una condicin particular.

Status flag. Una de seis banderas que describen los resultados generados por ciertas instrucciones.

Control flag. Una de tres banderas usadas para controlar la operacin del procesador.

Complemento. El valor inverso de un bit; el complemento de 0 es 1, y el complemento de 1 es 0.

Salto (Jump). Una instruccin que le dice al procesador que contine la ejecucin en la direccin dada
por una bandera particular.

Conditional jump. Un salto que es ejecutado solo si una condicin especificada es cierta.

Unconditional jump. Un salto que siempre es ejecutado.

Loop. Una secuencia de instrucciones que es ejecutada repetidamente.



10.1 Etiquetas en un segmento de cdigo.

En el captulo 8 aprendiste algo sobre la directiva LABEL, la cual define etiquetas en un programa.
En el captulo 8 usamos esas etiquetas en los segmentos de datos y extra para darles nombres alternativos
a los campos de datos.

Tambin puedes usar las etiquetas para proveer marcas dentro del segmento de cdigo. Puedes controlar
la ejecucin de tu programa saltando de una etiqueta a otra.
105

Para definir una etiqueta, usa la directiva LABEL con el siguiente formato:

nombre LABEL tipo

Cuando nosotros definimos etiquetas para campos de datos usamos los tipos BYTE, WORD, DWORD,
QWORD y TBYTE,. Para las etiquetas en el segmento de cdigo vamos a usar los tipos NEAR y FAR,
los cuales explicar a continuacin. Aqu hay algunos ejemplos:

L1 LABEL NEAR
ENTRY LABEL FAR

El primer ejemplo define una etiqueta llamada L!, de tipo NEAR. La segunda define una etiqueta,
ENTRY de tipo FAR.

Una etiqueta dentro del segmento de cdigo marca una direccin. La etiqueta near marca una direccin
que puede ser referenciada slo dentro de su mismo segmento. Una etiqueta far marca una direccin que
puede ser referenciada desde otro segmento.

La mayora de las etiquetas son near. En otras palabras, los saltos son casi siempre hechos a locaciones en
el mismo segmento. Ciertamente es una buena tcnica de programacin practicar saltos slo en el mismo
segmento.

Las etiquetas far son poco comunes. Slo los programas grandes y complejos demandan ms de un
segmento de cdigo, y es raro que quieras saltar a una etiqueta que se encuentra en un segmento
diferente. An as las etiquetas far estn ah por si son necesarias.

El mejor modo de comprender la diferencia entre las etiquetas far y near es comprender como las maneja
el ensamblador. Mientras procesas un programa, el ensamblador construye una tabla para rastrear todas la
etiquetas. Esta tabla contiene cada nombre con sus direcciones y su tipo.

Para etiquetas near, el ensamblador usa una direccin consistente de un offset (1 palabra). Para etiquetas
far, el ensamblador usa una direccin completa - una direccin de segmento con su offset (2 palabras).;
esto es debido a que el procesador necesita la direccin de segmento y el offset para saltar a otro
segmento. Para saltar dentro del mismo segmento, el procesador necesita slo el desplazamiento.

S casi todas la etiquetas son near, el ensamblador te permite definir etiquetas near de manera abreviada
con este formato:

nombre:

Por ejemplo:

L1:
READ_MORE:

En otras palabras, el ensamblador trata al nombre que est antes de los dos puntos como una etiqueta. As,

L1:

es lo mismo que

106
L1 LABEL NEAR

Cuando usas una etiqueta en su forma abreviada, puedes poner una instruccin en la misma lnea. Por
ejemplo

TESTAX: CMP AX,0

Sin embargo, es mejor prctica de programacin dejar toda la lnea para la etiqueta

TESTAX:
CMP AX,0



10.2 El registro de Banderas.

En el captulo 3, menciones que el procesador tiene 14 registros. Nueve de ellos son tratados como
entidades de 16-bits: SI; DI, SP, BP, IP, CS, DS, ES y SS. Cuatro de estos registros pueden ser tratados
como entidades de 16 u 8 bits: AX (AH, AL), BX (BH, BL), CX (CH, CL) y DX (DH, DL).

El registro de banderas es diferente de todos los otros, estos 16 bits son considerados como entidades
separadas de un bit.

De los 16 bits en el registro de banderas, 6 son llamados banderas de estado, 3 son llamados banderas de
control, y 7 no son usados en el modo real.

Una bandera es un bit cuyo valor, 0 o 1, es usado para indicar una condicin particular. Las 6 banderas de
estado describen los resultados generados por ciertas instrucciones. Las 3 banderas de control controlan la
operacin del procesador.

Cada una de las banderas de estado y de control tienen un nombre y una abreviacin. Esto se muestra en
la tabla 10-1.

Tabla 10-1 Las banderas de estado y control
Banderas de Estado
Abreviacin Nombre
AF Bandera de Acarreo auxiliar
CF Bandera de Acarreo
OF Bandera de Sobreflujo
PF Bandera de Paridad
SF Bandera de Signo
ZF Bandera de Cero
Banderas de Control
DF Bandera de Direccin
IF Bandera de Interrupcin
TF Bandera de Trampa

Si cada bandera es un bit, debe tener siempre un valor 0 1. Cuando una bandera tiene un valor de 1, se
dice que la bandera est ACTIVA; cuando una bandera tiene un valor de 0 se dice que la bandera est
DESACTIVADA.

107
Para referencia, la figura 10-1 muestra la locacin de las banderas dentro del registro de banderas. Los
bits ms significativos estn a la izquierda. Los bits que no se usan son el 15, 5, 3 y 1. Los bits que son
usados slo en el modo protegido son 14, 13 y 12.



Figura 10-1 La locacin de las banderas




10.3 Las banderas de Estado.

La banderas de estado son modificadas por muchas instrucciones, muchas de las cuales afectan a
varias banderas. Hablando generalmente, las banderas de estado son usadas con operaciones aritmticas
en nmeros con signo. Algunos de los valores de las banderas tienen un uso extrao que rara vez
necesitaras. Las ms importantes son la siguientes:

Bandera de Cero. La bandera de cero (ZF) se activa para indicar que el resultado de una operacin
fue cero.

Bandera de Signo. La bandera de signo (SF) se activa para indicar que el resultado de una
operacin
es negativo.

Bandera de Sobreflujo. La bandera de sobreflujo (OF) es usada con nmeros con signo. OF es
activada para indicar que el resultado de una operacin es demasiado grande para guardarla en
el operando destino.

Bandera de Acarreo. La bandera de acarreo (CF) es usada con nmeros sin signo. CF es activada
para indicar que el resultado es demasiado grande para ser almacenado en el operando destino.
(El nombre bandera de acarreo se refiere al hecho de que si el resultado de una adicin es muy
grande el bit ms significativo del destino queda fuera).

Bandera de Acarreo auxiliar. La bandera de acarreo auxiliar (AF) es usada con aritmtica decimal.
AF esta activa despus de una adicin o substraccin si es necesario un ajuste.

Bandera de Paridad. La bandera de paridad (PF) est activa si el resultado de una instruccin
contiene un nmero par de unos. Si tiene un nmero impar de 1s la bandera est desactiva.

La bandera de acarreo tiene otro uso importante que debes comprender. Los programadores usan en sus
procedimientos la bandera CF para indicar una terminacin exitosa o errnea. Si un procedimiento
termina sin errores CF se desactiva a 0 antes de regresar; si hay un error, el procedimiento activa la
bandera CF.

108
De esta manera el procedimiento que llama puede examinar CF para saber si hubo un error.



10.4 Instrucciones que modifican las banderas de estado: STC, CLC y CMC.

Muchas de la veces no es necesario que modifiques los estados de las banderas, ya que son solo para
examinarse. Sin embargo, hay algunas veces cuando querrs modificar la bandera de acarreo (CF). Por
esta razn, el procesador reconoce tres instrucciones que modifican el valor de esta bandera. Como se
muestra a continuacin.

STC Activa la bandera de acarreo Pone CF a 1
CLC Limpia la bandera de acarreo Pone CF a 0
CMC Complementa la bandera de acarreo Invierte el valor de CF

Estas instrucciones tiene dos usos. Primero, puedes usar CF para indicar una condicin de error en un
procedimiento. Segundo, ciertas instrucciones de rotacin RCL y RCR (que se explicarn en el captulo
16)
usan CF como parte de sus operaciones.

Con respecto a las otras banderas de estado, no hay forma de cambiar su valor.



10.5 La banderas de Control.

Las banderas de estado modifican el comportamiento de las instrucciones que no han sido
ejecutadas.

- Bandera de Direccin. La bandera de direccin (DF) es usada por las instrucciones que trabajan
con
strings. Con las instrucciones de strings, puedes especificar las direcciones de inicio y la longitud
del string a ser procesado. Si DF esta en 0, el string es procesado hacia adelante; si DF est puesta
a 1, la cadena procesa hacia atrs.

- Bandera de Interrupcin. En casos inusuales, un programa puede controlar su ambiente, la
bandera
de interrupcin (IF) es usada para activar o desactivar las interrupciones. Si la bandera IF est
puesta, el procesador reconoce las interrupciones; si la bandera IF esta desactivada el procesador
ignora las interrupciones que viene de dispositivos externos (hasta que IF se activa).
Las interrupciones son explicadas al detalle en el captulo 17.

- Bandera de Trampa. La bandera de trampa (TF) permite a un programa poner al procesador en un
estado en el cual un procedimiento especial es llamado despus de que cada instruccin es
ejecutada.
Esto es usado por los debuggers para ejecutar un programa una instruccin a la vez y hacer una
pausa
entre instrucciones.
Si TF est en 1, el procesador llama al procedimiento especial despus de la ejecucin de cada
instruccin; si TF est en 0 el procesador opera normalmente


109

10.6 Instrucciones que modifican las banderas de Control: STD, CLD, STI y CLI.

Hay dos instrucciones que modifican la bandera de direccin (DF) y dos instrucciones que
modifican la bandera de interrupcin (IF):

STD Activa la bandera de direccin Pone DF a 1
CLD Desactiva la bandera de direccin Pone DF a 0
STI Activa la bandera de interrupcin Pone IF a 1
CLI Desactiva la bandera de interrupcin Pone IF a 0

Necesitas activar y desactivar DF cada vez que uses instrucciones con strings (Ver captulo 15).


10.7 Instrucciones de Saltos Condicionales.

Existen una multitud de instrucciones que pueden usar la influencia del control de flujo de un
programa. Muchas de estas instrucciones son saltos condicionales.

Normalmente, el procesador ejecuta instrucciones una despus de otra. Un salto es una instruccin que le
dice al procesador que contine la ejecucin en la direccin dada por una etiqueta particular. De hecho, el
control es transferido a la primera instruccin despus de la etiqueta. Por ejemplo, Digamos que un
programa contiene los estatutos.

L1:
MOV AX,0

Si el procesador ejecuta un salto a la etiqueta L1, el siguiente estatuto a ejecutar es la operacin MOV.

Un salto condicional es un salto que es ejecutado slo si la condicin especificada es cierta. Este es el
formato de un salto condicional:

Jxxx etiqueta

xxx es una abreviacin de un salto en particular. Si la condicin es cierta, el procesador continua la
ejecucin con el primer estatuto despus de la etiqueta. Si es falso, la ejecucin continua con la siguiente
instruccin en la secuencia.

Aqu hay un ejemplo:

; si CX no es igual a 0, entonces le paso un 10
JCXZ L1
MOV CX,10
L1:

La instruccin JCXZ salta a L1 si CX es igual a cero. Si el salto toma lugar la instruccin MOV nunca es
ejecutada. Si CX no es cero, la instruccin MOV se ejecuta.



10.8 Saltos condicionales que prueban banderas y registros.

110
Existen 10 saltos condicionales que dependen del valor de una bandera y un salto que depende del
valor de una registro (CX).

Todas las banderas de estado menos PF tienen dos saltos condicionales; uno que salta si la bandera est
activa y un que salta si la bandera est desactivada. Estas instrucciones estn en la tabla 10-2. Las
abreviaciones seguidas de J son usadas como siguen:

Abreviacin Significado
Z Bandera de Cero
S Bandera de Signo
O Bandera de Sobreflujo
C Bandera de Acarreo
P Bandera de Paridad
N No
Tabla 10-2 Salto condicionales con banderas
Opcode Significado
JZ Salta si ZF est puesta a 1
JNZ Salta si ZF est puesta a 0
JS Salta si SF est puesta a 1
JNS Salta si SF est puesta a 0
JO Salta si OF est puesta a 1
JNO Salta si OF est puesta a 0
JC Salta si CF est puesta a 1
JNC Salta si CF est puesta a 0
JP (JPE) Salta si PF est puesta a 1
JNP (JPO) Salta si PF est puesta a 0

Porque existe una instruccin para probar CX? Muchas instrucciones que repiten una instruccin varias
veces guardan el nmero de repeticiones en CX. As es til saber si el contador se pone a ceros.



10.9 Comparar dos nmeros: CMP.

Los saltos condicionales que viste en la seccin anterior examinan las banderas de estado (o CX)
directamente. Sin embargo, muchas de las veces necesitaras saltos condicionales basados en la
comparacin de dos nmeros.

Por ejemplo, supn que tienes que poner TOTAL a 0 siempre y cuando TOTAL sea menor que 0. O
comparar AX con MAXIMO, y ejecutar ciertas instrucciones si AX es mayor que MAXIMO.

Implementar saltos basados en dos valores numricos es un proceso de dos pasos. Primero comparas los
dos valores y despus ejecutas el salto incondicional basado en el resultado de la comparacin.

Para comparar dos valores, usa la instruccin CMP

CMP valor1,valor2

Aqu hay descripciones de varios tipos de comparaciones que puedes ejecutar. Cada descripcin est
seguida de un ejemplo:

Comparar dos registros:
111

CMP AX,BX

Compara un registro con un campo dato:

CMP AX,TOTAL

Compara un registro con un operando inmediato

CMP AX,0

Compara un campo dato con un registro:

CMP TOTAL,AX
Compara un campo dato con un operando inmediato

CMP TOTAL,0

No puedes comparar dos campos de datos directamente. Si necesitas comparar dos datos tienes que copiar
uno de ellos a algn registro. Existen dos restricciones: Primera, puedes comparar dos nmeros con signo
o sin signo pero no combinaciones. Segundo los operandos deben ser de la misma longitud.

Si quieres compara dos strings usa a instrucciones CMPSB y CMPSW, si quieres comparar patrones de
bits usa la instruccin TEST.



10.10 Saltos condicionales usados despus de comparaciones.

El procesador tiene dos conjuntos de saltos condicionales que puedes usar despus de una
comparacin. Lo conjuntos son similares; la nica diferencia es que un conjunto es para nmeros con
signo y el otro para nmeros sin signo.

Despus de una instruccin CMP, normalmente usas un salto condicional para probar el resultado de la
comparacin. Las tablas 10-5 y 10-6 muestran las instrucciones de saltos condicionales para los dos tipos
de nmeros. Las abreviaciones despus de J son las siguientes:

Abreviacin Significado
N No
E Igual
G Mayor que
L Menor que
B Debajo
A Encima

Tabla 10-5 Saltos condicionales para nmeros con signo
Opcode Significado
JL (JNGE) Salta si menor que (no mayor que o igual)
JG (JNLE) Salta si mayor que (no menor o igual)
JLE (JNL) Salta si menor o igual (no mayor que)
JGE (JNL) Salta si mayor o igual (no menor)
JE Salta si igual
112
JNE Salta si no igual

Tabla 10-6 Saltos condicionales para nmeros sin signo
Opcode Significado
JB (JNAE) Salta si debajo (no arriba o igual)
JA (JNBE) Salta si arriba (no debajo o igual)
JBE (JNA) Salta si debajo o igual (no arriba)
JAE (JNB) Salta si arriba o igual (no debajo)
JE Salta si igual
JNE Salta si no igual

Note que algunas instrucciones tienen opcodes similares. Puedes usar el que quieras.

Hay dos cosas importantes que comprender. Primera, el procesador checa banderas diferentes para
nmeros con signo y sin signo. As, la instruccin le dice al procesador cual tipo checar. Sin embargo los
dos conjuntos de instrucciones son lgicamente equivalentes.

La segunda cosa importante es que la relacin expresada por la instruccin se refiere a los dos operandos
previos en la instruccin CMP: As, una instruccin JGE asume que la instruccin previa fue la
comparacin entre dos nmeros con signo. JGE salta si el primer nmero que encontr fue mayor o igual
que el segundo.

Aqu hay algunos ejemplos que usan CMP con saltos condicionales. El primer ejemplo brinca algunas
instrucciones si una variable con signo llamada TOTAL es menor que 0:

CMP TOTAL,0
JL L1
--- instrucciones que se salta ---
L1:

Si quieres puedes usar JNGE en lugar de JL:

CMP TOTAL,0
JNGE L1
--- instrucciones que se salta ---
L1:

El siguiente ejemplo salta algunas instrucciones si la variable sin signo llamada SUM es menor que la
valor sin signo en AX:

CMP SUM,AX
JB L2
--- instrucciones que se salta ---
L2:

El tercer ejemplo salta si DI es mayor o igual a VALOR, asumimos que DI tiene un nmero con signo.

CMP DI,VALOR
JGE L3
--- instrucciones que se salta ---
L3:

113
El ltimo ejemplo salta si AH es mayor o igual a DH. Asumimos que DH y AH tiene nmeros sin signo:

CMP AH,DH
JAE L4
--- instrucciones que se salta ---
L4:



10.11 Una grfica de Referencia de todos los saltos condicionales.

La tabla 10-7 muestra todos los saltos condicionales, en orden alfabtico. A un lado de dada cdigo
estn los campos de las banderas y registros que originan el salto. Los programadores comnmente usan
las siguientes abreviaciones:

Abreviacin Significado
CF Bandera de acarreo
CX Contenido del registro CX
OF Bandera de sobreflujo
PF Bandera de paridad
SF Bandera de signo
ZF Bandera de cero

Tabla 10-7 Grfica de referencia de saltos condicionales
Opcode Campos de los registros bandera
JA (JNBE) CF=0 y ZF=0
JAE (JNB) CF=0
JB (JNAE) CF=1
JBE (JNA) CF=1 o ZF=1
JC CF=1
JCXZ CX=0
JE ZF=1
JG (JNLE) ZF=0 y SF=OF
JGE (JNL) SF=OF
JL (JNGE) SF=1 o =F=1 pero no ambas
JLE (JNG) ZF=1 o (SF=1 o OF=1 pero no ambas)
JNA (JBE) CF=1 o ZF=1
JNAE (JB) CF=1
JNB (JAE) CF=0
JNBE (JA) CF=0 y ZF=0
JNC CF=0
JNE ZF=0
JNG (JLE) ZF=1 o (SF=1 o OF=1 pero no ambas)
JNGE (JL) SF=1 o OF=1 pero no ambas
JNL (JGE) SF=OF
JNLE (JG) ZF=0 y SF=OF
JNO OF=0
JNP PF=0
JNS ZF=0
JNZ ZF=0
JO OF=1
JP PF=1
114
JPE PF=1
JPO PF=0
JS SF=1
JZ ZF=1



10.12 Salto incondicional: JMP.

Un salto incondicional es un salto que siempre se ejecuta; esto es, no depende de ninguna condicin
cierta o falsa. El patrn del comando JMP es:

JMP etiqueta

Aqu hay algunos ejemplos

JMP L1
JMP FINISH_DISPLAY
JMP TABLE(SI)

Una instruccin JMP es usada para dos propsitos: Primero, para saltar instrucciones que no deben ser
ejecutadas cuando ciertas condiciones permanecen; segundo, para saltar hacia atrs y formar un ciclo.



10.12 Reglas para usar direcciones en instrucciones de Salto.

Cuando usas un salto incondicional (JMP) puedes especificar cualquier direccin, ya sea dentro del
mismo segmento de cdigo (near) o en otro segmento (far). De preferencia evita saltar a otros segmentos.

La regla para los saltos condicionales es ms restrictiva. Un salto condicional slo puede saltar a una
etiqueta near; lo que es ms la etiqueta pude estar a un mximo de distancia de 127 bytes de la
instruccin. El porque de esto, es que el procesador fue diseado para que haga las traducciones de los
saltos con direcciones de un byte.



10.13 Guas para usar instrucciones de Salto.

Las instrucciones de salto son poderosas. Pueden transferir el control cuando sea y casi a donde sea.
Tal poder puede causar ms problemas de los que crees.

Este comportamiento nos obliga a usar instrucciones de salto slo cuando es necesario y de manera
disciplinada. Existen slo dos situaciones importantes en las cuales puedes usar saltos.

Primera, usa saltos slo para implementar una de las construcciones alternativas o repetitivas discutidas
en el siguiente captulo. Por ejemplo:

; if AX=0 then BX+=5, else CX+=10
CMP AX,0
JE L1
JNE L2
115
L1:
ADD BX,5
JMP L3
L2:
ADD CX,10
L3:

Segundo, cuando un programa detecta condiciones excepcionales, y tienes que hacer un salto inmediato a
un procedimiento especial o a una parte especial del programa actual.

Por ejemplo, un procedimiento que lee y procesa datos debe asegarse que los datos sean validos. Si no es
as el procedimiento podra ir a la seccin de manejo de erroresAqu hay un ajemplo que detecta tal
condicin de error cuando la bandera de acarreo est puesta:

JC INVALID_DATA

Aqu hay un consejo que te evitar algunos problemas: Nunca saltes hacia atrs condicional o
incondicionalmente con un sola excepcin : Los ciclos.



10.14 Repetir una secuencia: LOOP.

Un loop es una secuencia de instrucciones que se ejecutan repetidamente. El procesador tien un
grupo de instrucciones que hacen fcil implementar ciclos.

La primera instruccin es LOOP. Est crea un cilo a ser ejecutado un nmero especifico de veces. Por
ejemplo, digamos que necesitas una tabla de 100 nmeros, debes hacer un culo que se ejecute 100 veces.

El comando LOOP tiene el siguiente formato:

LOOP etiqueta

Como con los saltos condicionales la etiqueta debe estar entre los 127 bytes de instrucciones. Usualmente
este no es problema.

La instruccin LOOP usa el registro CX como un contador que mantiene el valor del nmero de
ejecuciones del ciclo. Debes iniciar cargando a CX con el nmero de veces que quieres ejecutar el ciclo.
Depues defines la etiqueta que identifica el ciclo, los estatutos del ciclo, y la uinstruccin LOOP como se
ve a continuacin.

MOV CX,nmero-de-veces
etiqueta:
-- estatutos dentro del ciclo ---
LOOP etiqueta

El coando LOOP resta 1 de CX. Entonces si CX no es igual a 0, LOOP salta a la etuqueta especificada.

Por ejemplo, aqu hay una rutina de un ciclo que se ejecuta 100 veces:

MOV CX,100
L1:
116
--- estatutos dentro del ciclo ---
LOOP L1

Aqu hay un ejemplo que adiciona 100 nmeros. El nmero es almacenado como palabras in la tabla
llamada TABLA, la cual est definida como sigue:

TABLE DW 100 DUP(?)

Los valore son dados por el programa. Veamos un cilo que sume 100 nmeros y deje la suma en AX.

; Pone en AX la suma de 100 nmeros que estn almacenados como palabra en TABLA
MOV AX,0
MOV SI,0
MOV CX,100
L1:
ADD AX,TABLA[SI]
ADD SI,2
LOOP L1


Este ejemplo usa tres registros AX, SI y CX. El contador trabaja como sigue: CX est inicializado a 100 y
los estatutos dentro del ciclo ejecutan la operacin de suma, El LOOP disminuye 1 de CX y examina el
resultado, com CX es igual a 99 (el cual es diferente de cero), LOOP salta a L1. As hasta que CX valga
0.

El indice trabaja como sigue: SI es inicializada a 0. Cada vez que entramos al ciclo, SI es incrementada en
2. As, SI va toamndo los valores 0,2,4, etc. El primer ADD usa SI como registro indice. As el segundo
operando es est instruccin toma el valor de TABLA+0, TABLA+2, TABLA+4, etc.

El acumlador trabaja como sigue: Ax es inicializada a 0. Cada vez que entramos al ciclo, un nuevo valor
es inicializado a AX, al final AX contiene el total de la suma.



10.15 Ciclos que hacen uso de comparaciones: LOOPE y LOOPNE.

Algunas veces es til usar ciclos que dependam del uso de una comparacin. Los comandos LOOPE
y LOOPNE proveen estos servicios. Como la instruccin LOOP, LOOPE y LOOPNE substren 1 de CX y
saltan si CX no es igual a 0. Sin embargo LOOPE y LOOPNE tambin imponen otra condicin. LOOPE
requiere que la comparacin previa encuentre que los dos operandos sean iguales; LOOPNE requiere que
los dos operandos sean diferentes.

De hecho, digamos que quieres buscar en una tabla de 100 nmeros y que encuentre el primero que tenga
un valor de -1, supongamos que TABLA es una tabla de 100 palabras que contienen nmeros con signo.
TABLA est definida como:

TABLA DW 100 DUP(?)

El nmero son puestos por el programa. Veamos como quedara el ciclo usando LOOPNE:

; Busca en una tabla el primer valor igual a -1
MOV SI,-2
117
MOV CX,100
L1:
ADD SI,2
CMP TABLE[SI],-1
LOOPNE L1

Este ejemplo usa dos registros CX y SI. El contador trabaja como sigue: CX vale 100 al inicio. Entionces
LOOPNE decrementa el valor de CX en 1 dejandolo como 99, (el cual es diferente de 0). Si los dos
operandos no son iguales LOOPNE salta a L1. El ciclo continua hasta que CX vale 0 una comparacin
de los operandos muestra que son iguales, (esto es que algn valor es igual a -1).

El indice trabaja como sigue: SI est inicializado a -2. Cada vez que entra al ciclo, SI es decrementado en
2. As va tmando los valores 0, 2, 4, etc.El comando CMP usa a SI como el registro indice. As el
segundo operando en est instruccin toma los valores TABLA+0, TABLA+2, TABLA+4, etc. Como
TABLA consiste de palabras, estos valores direccionan cada nmero en turno.

La razn de la inicializacin de SI a -2 en lugar de 0, el que el comando ADD debe estar antes del CMP,
si ADD estuviera entre el CMP y el LOOPNE, la suma prodra cambiar el valor de las banderas, es por
eso que la operacin CMP tiene que ser la ltima antes del LOOP.

Aqui hay un ejemplo de un LOOPE que busca en la misma tabla el primer nmero diferente de -1:

; Busaca en TABLA de 100 palabras el primer valor que sea diferente de -1
MOV SI,-2
MOV CX,100
L1:
ADD SI,2
CMP TABLA[SI],-1
LOOPE L1

Las tres instrucciones de ciclo estn sumarizadas en la tabla 10-8. Note que LOOPE y LOOPNE tiene
nombres alternos:

Tabla 10-8 Comandos de ciclo
Opcode Significado Campos del registro de banderas
LOOP Ciclo CX no es cero
LOOPE Ciclo si igual a 0 CX no es cero y ZF=1
LOOPNE Ciclo si no igual a 0 CX no es cero y ZF=0


{_____________o___________}











118











CAPITULO 11 IMPLEMENTAR CONTROLES DE FLUJO


En este captulo, aprenders como son usadas las herramientas de ensamblador para hacer control de
flujo: etiquetas, banderas, saltos condicionales e incondicionales y comandos loop. Es esta captulo
aprenders a usar esas herramientas para construir los flujos de control que necesitas para un programa..
Este captulo es especialmente importante debido a que cubre los patrones que usaras para representar la
lgica de los programas.


Nuevos Trminos

Secuencia. Una de las tres construcciones fundamentales de control de flujo; la ejecucin de un grupo de
instrucciones una despus de otra.

Alternacin. Una de las tres construcciones fundamentales de control de flujo; la ejecucin de uno de
varios grupos de secuencias, dependiendo del valor de una condicin especifica.

Repeticin. Una de las tres construcciones fundamentales de control de flujo; la ejecucin de una
secuencia de instrucciones una y otra vez, hasta mientras una condicin especifica sea verdad.



11.1 Secuencia, Alternacin y Repeticin.

En cada procedimiento, el control de flujo es expresado usando los tres constructores
fundamentales: secuencia, alternacin y repeticin. En un lenguaje de alto nivel estos constructores ya
estn definidos y listos para usarse. En lenguaje ensamblador tendrs que construirlos t mismo a partir
de operaciones bsicas.

La secuencia se refiere a ejecutar un nmero de estatutos uno despus de otro. La alternacin provee
opciones. Varias secuencias de instrucciones son especificadas, cuando el programa se ejecuta, una
eleccin es hecha para ejecutar una secuencia de instrucciones, basados en el valor de una o ms
condiciones especificas. La repeticin significa ejecutar una secuencia de instrucciones una y otra vez
hasta, o mientras, una condicin es satisfactoria.

Los constructores cuyo patrn veremos en las siguientes secciones son: case, case-else, if-then-else, if-
then, repeat-until, for-next y while-repeat.



119
11.2 El Constructor CASE.

CASE es un constructor del tipo alternativo. Es usado para seleccionar un curso de accin en una
situacin donde varios casos pueden surgir En un lenguaje de alto nivel el patrn del CASE sera:

CASE
cond1: secuencia1,
cond2: secuencia2,
cond3: secuencia3, ...

El constructor CASE es interpretado como sigue: La condicin es evaluada en orden, una por una.
Cuando la condicin es cierta la secuencia de instrucciones asociada se ejecuta, cada secuencia puede
consistir de ms de una instruccin. Si ninguna de las condiciones es cierta, nada se ejecuta.

Suponga que necesitamos implementar los siguiente:

CASE
OPCION=1 : Llamar a DISPLAY;
OPCION=2 : Llamar a GET_INPUT;
OPCION<0 : Adicionar TOTAL a AX

En lenguaje ensamblador, un constructor CASE es traducido como una secuencia de saltos condicionales
e incondicionales:

; case opcin=1: llama a DISPLAY,
; opcin=2: llama a GET_INPUT
; opcin<0: adiciona TOTAL a AX
CMP OPCION,1
JE L1
CMP OPCION,2
JE L2
CMP OPCION,0
JL L3
JMP L4
L1: ; opcin=1
CALL DISPLAY
JMP L4
L2: ; opcin=2
CALL GET_INPUT
JMP L4
L3: ; opcin<0
ADD AX,TOTAL
L4:

Para uso general, el siguiente listado es el patrn del constructor CASE. Este patrn implementa slo tres
comparaciones, pero puedes extenderlo al nmero de opciones que desees:

; case cond1: sec1,
; cond2: sec2,
; cond3: sec3
CMP (cond1)
Jcond1 L1
120
CMP (cond2)
Jcond2 L2
CMP (cond3)
Jcond3 L3
JMP L4
L1: ; cond1
--- (sec1) ---
JMP L4
L2: ; cond2
--- (sec2) ---
JMP L4
L3: ; cond3
--- (sec3) ---
L4:



11.3 El constructor CASE-ELSE.

CASE-ELSE es un constructor alternativo que es una variacin del case. La nica diferencia con
CASE-ELSE es que si ninguna de la alternativas normales del case es seleccionada la alternativa ELSE es
ejecutada.

En un lenguaje de alto nivel, el formato del case-else es:

CASE
cond1: sec1,
cond2: sec2,
cond3: sec3,
.
.
.
ELSE: sec-else

Aqu hay un ejemplo de un constructor CASE-ELSE:

CASE
OPCION=1 : Llamar a DISPLAY;
OPCION=2 : Lamar a GET_INPUT;
OPCION<0 : Adicionar TOTAL a AX;
ELSE : adicionar 1 a BAD_CHOICE

Aqu esta la traduccin:

; case opcin=1: llama a DISPLAY,
; opcin=2: llama a GET_INPUT
; opcin<0: adiciona TOTAL a AX
; else: adiciona 1 a BAD_CHOICE
CMP OPCION,1
JE L1
CMP OPCION,2
JE L2
121
CMP OPCION,0
JL L3
JMP L4
L1: ; opcin=1
CALL DISPLAY
JMP L5
L2: ; opcin=2
CALL GET_INPUT
JMP L5
L3: ; opcin<0
ADD AX,TOTAL
JMP L5
L4: ; else
ADD BAD_CHOICE,1
L5:

Para uso general, el siguiente listado es el patrn del constructor CASE. Este patrn implementa slo tres
comparaciones, pero puedes extenderlo al nmero de opciones que desees:

; case cond1: sec1,
; cond2: sec2,
; cond3: sec3
; else: else-sec
CMP (cond1)
Jcond1 L1
CMP (cond2)
Jcond2 L2
CMP (cond3)
Jcond3 L3
JMP L4
L1: ; cond1
--- (sec1) ---
JMP L5
L2: ; cond2
--- (sec2) ---
JMP L5
L3: ; cond3
--- (sec3) ---
L4: ; else
--- (else sec) ---

L5:



11.4 El constructor IF-THEN-ELSE.

IF-THEN-ELSE es un constructor que contiene una condicin y dos secuencias de instrucciones. Si
la condicin es cierta, la primer secuencia se ejecuta; de otra forma la segunda secuencia se ejecuta. en un
lenguaje de alto nivel, el formato del IF-THEN-ELSE sera:

IF cond THEN
122
sec1
ELSE
sec2

Aqu hay un ejemplo de IF-THEN-ELSE

IF OPCION>0 THEN
adiciona 1 a GOOD_CHOICE
ELSE
adiciona 1 a BAD_CHOICE
Aqu est la traduccin:

; if OPCION>0 adiciona 1 a GOOD_CHOICE
; else: adiciona 1 a BAD_CHOICE
CMP OPCION,0
JG L1
JMP L2
L1:
ADD GOOD_CHOICE,1
JMP L3
L2:
ADD BAD_CHOICE,1
JMP L3
L3:

Aqu est el patrn para uso general:

; if cond sec1,
; else sec2
CMP (cond)
Jcond L1
JMP L2
L1: ; then
--- (sec1) ---
JMP L3
L2: ; else
--- (sec2) ---
L3:



11.5 El constructor IF-THEN.

El constructor IF-THEN solo tiene una secuencia de instrucciones, y se ejecutan solo si la condicin
es cierta, su formato es:

IF cond THEN secuencia

Aqu hay un ejemplo de IF-THEN

IF OPCION<0 THEN
adiciona 1 a GOOD_CHOICE,
123
pon CHOICE a 0

Aqu est la traduccin a ensamblador

; if OPCION<0 then
; adiciona 1 a GOOD_CHOICE
; pon CHOICE a 0
CMP OPCION,0
JNL L1
ADD GOOD_CHOICE,1
MOV CHOICE,0
L1:

Para uso general aqu est el patrn:

; if cond then sec
CMP (cond)
JNcond L1
-- (sec) ---
L1:



11.6 El constructor REPEAT-UNTIL.

El REPEAT-UNTIL repite una secuencia de instrucciones hasta que una condicin se hace
verdadera. La condicin no se prueba hasta que la secuencia ha sido ejecutada por lo menos una vez. En
lenguaje de alto nivel el REPEAT-UNTIL sera:

REPEAT
sec
UNTIL cond

Aqu hay un ejemplo. Un programa necesita leer alguna entrada y asegurarse que es valida. El programa
llama a dos procedimientos: GET_INPUT para leer la entrada y TEST_INPUT para validarla. El
programa debe llamar a estos dos procedimientos hasta que la entrada sea valida

En algunos casos debes hacer una comparacin antes del salto condicional. TEST_INPUT dice si la
entrada es valida o invalida poniendo a AX en 0 o en 1, respectivamente.

; repeat
; lee la entrad,
; prueba la entrada; hasta que AX=0
L1:
CALL GET_INPUT
CALL TEST_INPUT
CMP AX,0
JNE L1

Para uso general aqu est el patrn:

; repetir secuencia hasta que la condicin sea cierta
124
L1:
--- sec ---
CMP cond
JNcond L1



11.6 El constructor FOR-NEXT usando LOOP

FOR-NEXT ejecuta una secuencia de instrucciones un nmero fijo de veces. Aqu hay un ejemplo
tomado del captulo 10 acerca del uso del LOOP. El programa suma 100 nmeros que estn almacenados
como palabras en una tabla llamada TABLA, y que est definida como sigue

TABLA DW 100 DUP(?)

Los valores ya estn en la tabla. El programa usa tres registros: AX para guardar el resultado, SI como un
ndice y CX para controlar el ciclo, la construccin FOR-NEXT sera:

inicializa AX a 0
inicializa SI a 0
inicializa CX a 100
FOR CX=100 a CX=1
suma TABLA[SI] a AX
incrementa SI en 2
NEXT

Aqu est la traduccin a ensamblador:

; Tener en AX la suma de los 100 nmeros que estn en TABLA
MOV AX,0
MOV SI,0
MOV CX,100
L1:
ADD AX,TABLA[SI]
ADD SI,2
LOOP L1

Para uso general este es el patrn

; repite una secuencia N veces
MOV CX,N
L1:
--- sec ---
LOOP L1



11.7 El constructor WHILE-REPEAT.

WHILE-REPEAT ejecuta una secuencia de instrucciones mientras que la condicin sea verdadera.
Si la prueba de la condicin originalmente es falsa no se entra ni siquiera una vez a este constructor.. En
lenguaje de alto nivel, el formato del WHILE-REPEAT sera:
125
126

WHILE cond REPEAT
secuencia

Aqu hay un ejemplo que llama a un procedimiento (PRINT_DATA) para mandar datos a la impresora. El
procedimiento se llama mientras la variable CONT sea mayor que 0.

WHILE CONT>0 REPEAT
llamar a PRINT_DATA
restarle 1 a CONT

Aqu est la traduccin:

; while CONT>0 repite
; mandar un dato a la impresora
; incrementar CONT en 1
L1:
CMP CONT,0
JNG L2
CALL PRINT_DATA
SUB CONT,1
JMP L1
L2:

Para uso general:

; while cond repite secuencia
L1:
CMP cond
JNcond L2
--- secuencia ---
JMP L1
L2:


{_____________o___________}