Anda di halaman 1dari 109

1

CAPITULO I INTRODUCCION

1.1 Por qu programar en Ensamblador?

En la programacin de computadoras existe un axioma:

Primero consigue que un programa trabaje bien y.... despus haz que trabaje ms rpido

y qu pasa si no puedo hacer que mi programa sea ms rpido?. Entonces slo queda una sola
solucin: codificarlo en lenguaje Ensamblador. Un programa escrito en lenguaje Ensamblador
requiere considerablemente menos memoria y tiempo de ejecucin que un programa escrito en
un lenguaje de alto nivel.
h
Sin embargo el lenguaje Ensamblador tiene una gran desventaja: es difcil de aprender por que
como el lenguaje C++ utiliza punteros o sea direcciones a memoria y adems requiere mucho
cdigo, que se traduce en realizar ms trabajo que el habitual en comparacin con los lenguajes de
alto nivel, y por tanto consume mayor tiempo de programacin.

Para los informticos la productividad siempre ha sido algo muy importante, los sistemas de
informacin tienen que desarrollarse en el menor tiempo posible, y esto ha ocasionado que los
lenguajes hayan evolucionado desde los lenguajes de mquina, pasando por el lenguaje
Ensamblador, seguir con los lenguajes de alto nivel, hasta llegar actualmente a los lenguajes
visuales y orientados a objetos, llamados de quinta generacin.

En los inicios de la computacin en las dcadas de los 50s y 60s, se empez programando en
lenguaje de mquina, es decir con 1s y 0s; se continu programando en lenguaje Ensamblador
que sustituy los nmeros binarios por nemnicos que son las instrucciones del Ensamblador, y en
esta bsqueda incensante de aumentar la productividad de los programadores, aparecen los
lenguajes de alto nivel y entre ellos el lenguaje C, que evolucion hasta llegar al C++, que ha
desplazado al Pascal, y en la actualidad se ha constituido en el lenguaje acadmico en las
universidades; es el lenguaje que ms rpido cambia, por eso lo han dotado de capacidades para
trabajar en el nivel ms bajo posible y tambin el ms alto, y sus diseadores han conseguido que
su cdigo sea muy rpido y eficiente; prcticamente ha desplazado en mucho al lenguaje
Ensamblador.

Hace poco muchos productos para mostrar su calidad se jactaban de decir hecho ntegramente en
lenguaje Ensamblador. Con la aparicin del lenguaje C++, podemos afirmar que casi todos los
sistemas operativos, protocolos de redes, utilitarios de los sistemas, compiladores de lenguajes,
etc., estn construidos utilizando el lenguaje C++.

Sin embargo, siempre existen mdulos que a pesar de estar hechos con C++, siguen siendo lentos.
Ah entra a tallar el lenguaje Ensamblador. Por eso, el binomio: C++ & Ensamblador resulta
insustituible, es la herramienta ms poderosa que existe para programar la computadora.

Debido a su cdigo eficiente, la mayora de libros de Ensamblador afirman que el lenguaje
Ensamblador se aprende por las siguientes razones:

1. Conocer en mayor profundidad el funcionamiento bsico de la mquina.
2. Ganar rapidez en la ejecucin de los programas.
2
3. Tener acceso a posibilidades de la mquina que son inaccesibles desde otros
lenguajes.
4. Entender mejor cmo funciona un lenguaje de alto nivel.
5. Utilizar las posibilidades de la mquina desde los propios lenguajes de alto nivel con
interface de estos lenguajes con el Ensamblador.

Sin embargo, para los informticos, existe otra razn muy poderosa para aprender a programar en
lenguaje Ensamblador: este lenguaje es formativo. Ningn lenguaje de programacin, con
excepcin del Ensamblador, muestra al programador, cmo trabaja internamente la computadora;
sta es una mquina esttica, que se convierte en una caja negra a la que se le ingresan datos
para obtener resultados. Cmo lo hace?. Como es una mquina que no se mueve,
aparentemente su funcionamiento es un misterio.

El Ensamblador es el nico lenguaje de programacin que no tiene libreras, y si no las tiene, no
queda otra salida: hay que construirlas; por que sin libreras, programar en Ensamblador es muy
tedioso, se requiere escribir mucho cdigo, y esto desanima a cualquiera en seguir programando
en este lenguaje. El esfuerzo de construir estas libreras es muy grande, y lo lograrn solamente
quienes lleguen a niveles avanzados de programacin en Ensamblador, cuya curva de aprendizaje
tiene una pendiente muy elevada.

La actividad de programar, cualquiera que sea el lenguaje elegido, en general es un arte. Sin
embargo, cuando se trata del ensamblador se convierte en un arte de maestros. Cuando se
llega a entender la filosofa de cmo trabaja el procesador internamente, este lenguaje de lo
complicado y difcil que parece a un comienzo se va transformando en sencillo, claro, puro y va
directo al grano. Es cmo encontrar las respuestas a las siguientes preguntas en forma consciente:

1. Cul es el objetivo?
2. Cmo logro el objetivo?
3. Cmo optimizo lo logrado?

Ponderemos un poco lo anterior siguiendo una lgica secuencial, en la que cada paso dependa del
anterior. Finalmente, de los tres pasos el ms difcil es el tercero, y ah, en algunos casos, es
donde entra en escena el lenguaje ensamblador.

1.1.1. COMPUTADORAS Y PROGRAMAS

LA COMPUTADORA UNA MAQUINA MARAVILLOSA?

El hombre moderno tiene la idea de que las mquinas le disminuyen una parte de su
trabajo. Esto es realmente cierto porque la generalidad de las mquinas tienen como
finalidad inmediata mover o transformar objetos fsicos. La utilizacin de las mquinas en
forma intensiva ha ocasionado un avance insospechado de nuestra civilizacin, por eso se
habla de la Era Industrial que corresponde a la etapa en que el hombre ha intensificado el
uso de las mquinas.

A partir del siglo XVIII, la revolucin industrial gener un cambio en los sistemas de
produccin, e introdujo un nuevo sistema de fabricacin mediante mquinas impulsadas por
una nueva fuerza: el vapor. Hasta entonces los artculos se haban fabricado a mano por
los artesanos en los talleres. De aquella revolucin surge el mundo industrial moderno y nace




3


una nueva clase: el obrero industrial, que trabaja en las fbricas bajo nuevas y difciles
condiciones.

Se inventaron mquinas de procedimientos mecnicos, surgieron nuevos mtodos de
produccin logrando as fabricar mayor cantidad de artculos a menor precio y con mayor
rapidez. Hoy da se hace esto automticamente casi sin la intervencin humana y lo que se
busca antes que nada es la calidad de lo que se produce.

En la dcada de los 50 el hombre inventa otro tipo de mquinas, que no realizan trabajo
fsico, pero tienen la capacidad de procesar informacin; estas mquinas han resultado
tan importantes que a la presente era se le llama Era de la Informacin. Estas mquinas
se llaman computadoras u ordenadores.

La computadora, como hemos puntualizado anteriormente, es una mquina que no realiza
ningn trabajo fsico, pero sin embargo ha contribuido a crear nuevos paradigmas en todo el
quehacer humano, desplazando el punto central de los recursos del capital hacia los recursos
humanos y de informacin.

Las computadoras han logrado conformar un nuevo paradigma en la situacin geopoltica del
mundo que a su vez ha generado un nuevo paradigma en el ambiente internacional de negocios.


Las computadoras y las redes de computadoras han logrado el ascenso de la nueva
empresa abierta e interconectada que constituye un nuevo paradigma organizacional.



1.2. EL HOMBRE Y LA COMPUTADORA SON MAQUINAS DE PROCESO
DE DATOS

Cada proceso de la informacin tiene como meta la transformacin de datos; esto es vlido
independientemente de que el proceso de la informacin sea manual a travs de una persona
competente o automtico cuando se utiliza una mquina.

Solamente existen dos mquinas que procesan la imformacin, el hombre y las mquinas que el
hombre ha inventado para procesar informacin.

Estos datos
Datos deben tener un
Datos valor especfico
de entrada de salida para el usuario

El procesamiento automtico de la informacin se efecta con la ayuda de las mquinas de
proceso de informacin. Un ejemplo muy difundido de una mquina de proceso de informacin
es la calculadora de bolsillo, donde los datos de entrada son dados a travs de un teclado y los
datos de salida son devueltos por medio de un sealizador de diodos emisores de luz o en forma
impresa. Las calculadoras de bolsillo disponen con frecuencia de dispositivos para almacenar
internamente una o ms constantes. Los datos de salida resultan, en este caso, de un proceso
en el que participan datos de entrada y datos almacenados internamente.


Hombre o
mquina


4


Al lado de las calculadoras de bolsillo existen muchos otros tipos de mquinas de proceso de
informacin. Como ejemplos tenemos:

la mquina Turing
la Learning Matrix
el Perceptron
la Computadora Analgica
el Analizador Diferencial Digital (Digital Differential Analyzer)
Un caso especial adicional es la Computadora digital u Ordenador, que en un concepto
ms amplio es designado como Sistema de Proceso de Datos.

Comparadas con otros tipos de mquinas de proceso de informacin, las computadoras digitales
son mucho ms eficientes. La parte predominante del proceso automtico de la informacin se
lleva a cabo hoy da por medio de las computadoras digitales.



1.3. DESDE EL PUNTO DE VISTA DE UN PROGRAMADOR QUE PUEDE
HACER UNA COMPUTADORA DIGITAL ?

A las computadoras se les asignan muchas propiedades poderosas y asombrosas. Lo nico que
hacen es recibir datos, llamados datos de entrada, y producen datos de salida que tienen mayor
valor que los datos de entrada. A partir de estos datos de salida el hombre moderno toma
decisiones que de alguna manera pueden contribuir al movimiento o a la modificacin de objetos
fsicos.

Sin embargo la computadora solamente trabaja con programas y el hombre es quien
hace estos programas. La computadora sin programas no es nada, sera un montn de
fierros intiles.

Y desde el punto de vista de un programador, todas las computadoras, sean ellas las ms
grandes o las ms pequeas, son simples colecciones de componentes electrnicos que tienen
siete capacidades bsicas:

Primera: Almacenar datos en un medio fsico, que llamaremos memoria principal

Segunda: Hacer aritmtica simple: suma, resta, multiplicacin y divisin

Tercera: Entrada y salida de datos; sin estos dos procesos estas mquinas no tendran
mucho uso no es cierto?.

Cuarta: Capacidad de programa almacenado; para ejecutar un programa tiene que
cargarse ntegramente en la memoria principal.

Quinta: Tomar decisiones simples, como consecuencia de comparar dos nmeros

Sexta: Persistencia de los datos, en un segundo medio fsico, llamado archivo o
memoria secundaria

Setima: Reutilizacin, concepto que explicaremos ms adelante





5


1.4. Porqu usamos las computadoras?

Desde que todas las computadoras solamente tienen estas siete capacidades bsicas, tan
elementales: capacidad de guardar datos en memoria, hacer aritmtica simple, tomar decisiones
triviales, almacenar un programa en memoria para correrlo, ejecutar entrada/salida de datos,
almacenar y acceder a grandes cantidades de datos en almacenamientos secundarios, y la
reutilizacin, entonces, si pensamos un poco, nos damos cuenta que tambin el hombre
tiene estas capacidades bsicas, resulta natural preguntarse lo siguiente:

Porqu usamos las computadoras?. La respuesta es la siguiente: Existen quizs tres buenas
razones para usar estas mquinas a pesar de sus limitadas capacidades:

1.-) LAS USAMOS POR SU VELOCIDAD

Las computadoras son capaces de hacer estas siete capacidades bsicas
(almacenar datos en memoria, aritmtica simple, tomar decisiones simples,
cargar programas en memoria, operaciones de entrada/salida, almacenar y
acceder a grandes cantidades de informacin y la reutilizacin) a tremendas
velocidades. Para apreciar esto digamos que el nmero de sumas que
ejecuta la computadora en un segundo, probablemente requerira a una
persona trabajando 40 horas semanales durante unos veinte aos.
Velocidades para hacer otros tipos de operaciones aritmticas y tomar
decisiones simples son comparables a la indicada para las sumas. Sin
embargo las operaciones de entrada/salida que envuelven movimientos de
componentes mecnicos de mquinas como las impresoras o los discos
duros resultan mucho ms lentas. En un sistema de computacin tpico con
una impresora de alta velocidad se pueden imprimir miles de lneas por
minuto y en una impresora conectada a una PC unos 300 caracteres por
segundo.

2.-) LAS USAMOS POR SU EXACTITUD Y CONFIABILIDAD

Las computadoras son exactas y confiables. Todo lo que hacen lo hacen a
gran velocidad y sin equivocarse. Como son mquinas fabricadas por los
hombres ocasionalmente pueden malograrse y tienen que ser reparadas.
Cuando en un proceso con la computadora se comete un error este siempre
se debe al hombre.

3.-) LAS USAMOS POR LA CAPACIDAD DEL HOMBRE DE
DESCOMPONER UN PROBLEMA GRANDE EN UN CONJUNTO DE
PEQUEOS PROBLEMAS

La razn ms importante de usar las computadoras est dada por el hecho
de que el hombre puede resolver muchos problemas utilizando programas
de computadora debido a su capacidad de enfrentar la complejidad no
resolviendo directamente los problemas difciles, sino por el contrario
solucionando equivalentemente un conjunto de pequeos problemas -uno
despus de otro-; con la aclaracin de que las soluciones a estos
pequeos problemas pueden ser obtenidos usando las limitadas
capacidades que poseen todas las computadoras.













I
N
H
E
R
E
N
T
E
S









A

L
A

M
A
Q
U
I
N
A













A
L

H
O
M
B
R
E


6
Desde que las computadoras pueden hacer todas estas cosas con exactitud y a altas
velocidades, la razn para utilizarlas es obvia.

Podemos resumir entonces que:



LA COMPUTADORA ES: EL HOMBRE ES:

Extremadamente rpida. Increblemente lento para manejar informacin.

Precisa, nunca se equivoca. Impreciso, es propenso a cometer errores.

Estpida, es una esclava repetidora. Brillante, porque tiene la facultad de crear, por eso
es el amo.




ADEMAS:

La computadora trabaja con datos. El hombre trabaja con informacin.

Cuando la computadora lee transfiere Cuando el hombre lee, adquiere informacin
datos de un medio electromagntico (disco, interpretando un conjunto de datos. La lectura
pantalla,etc.)a otro medio electromagntico es un fenmeno extraordinariamente complejo.
llamado memoria.

Cuando la computadora escribe transfiere Unicamente el hombre escribe plasmando un
datos de la memoria a otro medio pensamiento en un lenguaje.
electromagntico (disco, pantalla, etc.)

Ambos constituyen un binomio de una riqueza incalculable

El conocimiento es poder y la computadora es una mquina amplificadora de ese
poder, es una innovadora vital y fructfera. La computadora crea valor mediante la
transformacin del poder cerebral de los trabajadores del conocimiento, con poco
consumo de energa y materiales nuevos.



Estas siete capacidades bsicas, son tan importantes, que su entendimiento nos mostrar la
filosofa de cmo trabaja internamente una computadora digital, y el programador entienda cmo
opera la computadora internamente, por eso las estudiaremos con detenimiento en el siguiente
captulo; pero para su completo entendimiento tambin estudiaremos la herramienta que nos
ayudar a entender estas siete capacidades bsicas, nos referimos concretamente al programa
debug.exe, que aprenderemos a manejar ms adelante en el captulo II.

Analicemos una a una las siete capacidades bsicas de una computadora digital:






7


1.4.1. PRIMERA CAPACIDAD BASICA

Cada computadora tiene circuitos electrnicos que permiten almacenar y recuperar datos en su
memoria en forma directa, utilizando expresiones que se llaman instrucciones de asignacin.
Qu tipos de datos puede almacenar y recuperar?. Solamente datos numricos binarios,
compuestos de dgitos 1s y 0s. De ah el nombre de computadoras digitales

Si un programador quiere guardar la letra A en la memoria de la computadora, utiliza el nmero
binario 010000012 o su equivalente hexadecimal 4116, o tambin 41h la h significa que est en
el sistema hexadecimal y el nombre de una variable, que es un nombre que comienza con una
letra, por ejemplo X, y si recurre al lenguaje Cobol tiene que escribir: move A to X, en
lenguaje C: X = A;, en Object Pascal: X := A; y en Ensamblador:

mov X, 41h

que debemos leer almacena 41h en la direccin de la memoria a la que apunta X, o en forma
ms simple para no mencionar la memoria, almacena 41h en X, o mejor todava asigna 41h a
X o esta otra mueve 41h a X. En lenguaje de mquina, como veremos mas adelante, no se
pueden usar nombres de variables, y escribiremos: mov byte ptr [0000],41

En que parte de la memoria, se almacena el valor 41h que contiene X?. Para el programador de
un lenguaje de alto nivel como el COBOL o el C, eso no importa, el sistema operativo y el
compilador respectivo se encargan de verificar en que parte de la memoria almacena el resultado.
Pero en el lenguaje de nivel bajo como el Ensamblador el programador previamente tiene que
elegir en que parte de la memoria puede guardar el numero hexadecimal 4116

A expresiones del tipo mov X,41h, en las que a la izquierda de la coma aparece una variable,
que es un nombre que comienza con una letra, y a la derecha de la coma aparece un nmero, de
ahora en adelante las llamaremos instrucciones de asignacin.

1.4.2. SEGUNDA CAPACIDAD BASICA

Cada computadora tiene circuitos electrnicos que son diferentes a la memoria y que se
encuentran en la CPU, que se llaman registros y que sirven para hacer aritmtica. Qu clase
de aritmtica pueden hacer?. Las cuatro clases de operaciones aritmticas: + - * /. Esto es suma,
resta multiplicacin y divisin.

Adems de hacer operaciones aritmticas la computadora guarda en memoria los resultados
parciales y finales obtenidos con esas operaciones, y tal como lo hace el hombre, requiere
almacenar esos datos en un medio fsico para poder manipularlos. Por eso recurre a ciertos
recursos electrnicos llamados registros. Por ejemplo si queremos calcular la suma: 3 + 5,
utilizamos un medio registro de nombre al el registro ax contiene dos medios registros ah y al
y procedemos as:

mov al,3 ; al = 3
add al,5 ; al = al + 5

Si quiere calcular 8 3, escribimos:

mov al,8 ; al =8
sub al,3 ; al = al 3
8
Si quiere calcular 3 * 8, en este caso tiene que utilizar dos medios registros de nombres al y bl, y
escribimos:

mov al,3 ; al=3
mov bl,8 ; bl=8
mul bl ; ah:al = 3 * 8

la instruccin mul bl, siempre multiplica el valor que se guarda en al por el valor que existe en bl
y el resultado lo guarda en dos medios registros, par que designamos asi: ah:al.

Para dividir 10 entre 2, escribimos lo siguiente:

mov ah,0 ; ah=0
mov al,10 ; al=10
mov bl,2 ; bl=2
div bl ; al = 8/2=4

la instruccin div bl, siempre divide el valor que se guarda en ah:al por el valor que existe en bl
y el cociente se guarda en al, y el resto en ah.

1.4.3. TERCERA CAPACIDAD BASICA

Esta capacidad se llama capacidad de interface de entrada/salida y se ejecuta mediante
instrucciones de entrada/salida. Cada computadora tiene un medio de comunicarse con Ud. o
con la persona que la utiliza. De todas maneras, si nosotros no pudiramos introducir nmeros y
obtener resultados, estas mquinas no tendran mucho uso no es cierto?.

La forma ms comn de suministrar informacin a la computadora es por medio del teclado y los
datos de respuesta los visualizamos en la pantalla. El teclado sirve para leer los datos y poder
guardarlos en la memoria de la computadora. En forma opuesta la pantalla sirve para mostrar los
datos que se encuentran en la memoria de la computadora. Tanto el teclado como la pantalla
estn conectados a la computadora y se les denomina perifricos de entrada y salida.

Todos los lenguajes de programacin tienen una manera de leer datos de teclado y escribir datos
en la pantalla.

El lenguaje Ensamblador realiza las operaciones de entrada y salida utilizando llamadas a
interrupciones del sistema operativo. La ms conocida de estas es la interrupcin de nombre int
21h, que tiene varias funciones que vienen especificadas en el valor que tome el medio registro
ah. Por ejemplo si ah=1 la interrupcin 21h hace que la computadora lea de teclado un carcter
ASCII y lo almacene en el medio registro al, y si ah=2 la interrupcin 21h hace que la
computadora escriba en pantalla el carcter ASCII cuyo valor est en dl.

Veamos como se hace esto:

Si queremos leer el numero 4 de teclado y guardarlo en memoria, debemos utilizar el nombre de
una variable, por ejemplo x, que tiene que ser del mismo tamao que al. As escribiremos en
lenguaje Ensamblador:





9


mov ah,1 ; ah=1, funcin para leer un carcter de teclado
int 21h ; lee el nmero 4 y lo guarda en el medio registro al
mov x,al ; almacena el carcter 4 en la variable x en memoria

Si ejecutamos este cdigo, nosotros deberemos digitar la tecla con el nmero 4, el nmero 4 se
asigna a al y despus se mueve a x que est en memoria.

Si queremos escribir en pantalla el nmero 4, que ya tenemos almacenado en memoria en la
direccin a la que apunta la variable x, escribiremos este otro cdigo:

mov ah,2 ; se prepara para escribir un carcter en pantalla
mov dl,0Ah ; en dl el salto de lnea
int 21h ; salta de lnea
mov dl,x ; en dl el nmero 4
int 21h ; escribe 4 en pantalla
mov ah,4ch ; se prepara para terminar
int 21h ; termina el programa y pasa el control al sistema
; operativo DOS

y veremos que la computadora escribe en la pantalla el nmero 4.

1.4.4. CUARTA CAPACIDAD BASICA

Esta capacidad se llama capacidad de programa almacenado.

Qu es un programa de computadora digital?

Una computadora digital es una mquina que explora secuencialmente una informacin
almacenada en su memoria, llamada programa, y lo ejecuta siguiendo el principio de Von
Neumann. Por eso es que a las computadoras digitales tambin se les llama computadoras de
programa almacenado porque para ejecutar un programa tienen que cargarlo ntegramente en
la memoria antes de correrlo. Aclaremos este concepto: las computadoras o sistemas de proceso
de datos se caracterizan por el proceso digital de la informacin, as como por la diferenciacin
en instrucciones (programas) y datos de la informacin ambos representados digitalmente en la
memoria principal.

Todo programa tiene dos componentes o partes: El primer componente es el algoritmo y el
segundo componente son los datos. El profesor Niklaus Wirth --inventor del Pascal y Modula
2-- titul a uno de sus ms famosos libros: "Algoritmos + Estructuras de datos = Programas".
Pero... Qu es un algoritmo?. Contestamos: "Un algoritmo es un mtodo para resolver
un problema en un nmero finito de pasos". Cada paso de un algoritmo se llama sentencia
o instruccin.

Un ejemplo ilustrativo

El siguiente es un programa escrito en lenguaje de mquina mediante el programa
debug.exe que escribe en pantalla la palabra algoritmo


10


1693:100 mov dx, 109
1693:103 mov ah ,9
1693:105 int 21 algoritmo programa
1693:107 int 20
1693:109 db algoritmo$ datos

El algoritmo de este programa contiene 4 instrucciones, empieza en la instruccin: mov dx,109; y
termina con la instruccin int 20. La instruccin mov dx,109 se encuentra en la direccin
relativa 100, y la seudo instruccin: db algoritmo , se encuentra en la direccin relativa 109, y
declara los datos.

MEMORIA secuencias de 1s y 0s


Se carga en memoria



Programa en disco

Para comprobar el funcionamiento de este programa, que repetimos est escrito en lenguaje de
mquina, lenguaje que es muy semejante al Ensamblador, utilizaremos el programa debug.exe,
que est siempre accesible desde el DOS. Para ingresar a su ambiente de desarrollo, haga lo
siguiente: Pulse el boton inicio del windows, en el men emergente elija la opcin ejecutar, en la
ventana abrir digite cmd y acto seguido ingresar al modo DOS del Windows. Proceda a digitar
debug y pulsar la tecla enter, en ese momento aparece un guin , esto le indica que ya puede
empezar a trabajar con el debug.exe. Despus del guin digite la letra A y luego pulse la tecla
de entrada <ENTER>. La letra a representa al comando Ensamblador para poder ingresar
desde el teclado lineas de cdigo en lenguaje de mquina; y a continuacin digite el programa
anterior. Seguidamente para correr el programa, se digita el comando g (go), y usted ver
desplegarse en pantalla la palabra algoritmo y en la siguiente linea el mensaje Program
terminate normally, generado por el programa debug.exe.





Programa
Datos




11



El principio de Von Neumann

El cientifico hngaro-estadounidense John Von Neumann concibi la computadora digital,
como una mquina que cargaba en memoria un programa y lo ejecutaba instruccin por
instruccin. Segn el principio de Von Neumann, la ejecucin de cada instruccin comprenda
dos tiempos:

Leer la instruccin de memoria
que apunta el registro IP
Tiempo de instruccin
Decodificarla, esto es interpretar
qu significa cada instruccin
Instruccin
Ejecutar la instruccin
Tiempo de ejecucin
Guardar los resultados en memoria



El programa debug.exe, es una herramienta muy apropiada para verificar cmo funciona el
principio de Von Neumann, por que a diferencia del comando g (go), que ejecuta nuestro
programa a una velocidad tan grande que no nos permite verificar lo que pasa en cada
instruccin, por eso recurriremos al comando p (proceed), que nos permite ejecutar el
programa instruccin por intruccin, como describimos a continuacin.

Comencemos verificando que el programa que digitamos ms arriba est almacenado en la
memoria de la computadora. Para ello digitamos el comando u (unEnsamblador, esto es
desemsambla los 1s y 0s decodifica y muestra el codigo) y dar entrada y obtendr lo siguiente:



12
Observe cmo el procesador utilizando el comando u (unEnsamblador), permite verificar el
tiempo de instruccin del principio de Von Neuman, ya que decodifica pero sin ejecutar, todos
los 1s y 0s contenidos en la memoria y muestra el resultado de esta decodificacin como
instrucciones de lenguaje de mquina que figuran en la columna tres y cuatro de la figura
anterior. As mismo en la primera columna aparece la direccin de memoria donde se encuentra
almacenada cada instruccin y en la segunda columna el contenido de la memoria, interpretado
no en 1s y 0s si no en su equivalente hexadecimal. Las instrucciones de mquina que usted ve
en pantalla su alcance va ms alla de lo que es el programa que digitamos inicialmente y que
abarca, desde el desplazamiento 0100 hasta el 011C., seran las instrucciones que se
ejecutaran si se corre el programa con el comando G (Go). Por eso un programa en lenguaje
de mquina, obligatoriamente tiene que tener una instruccin int 20, para terminar el programa,
caso contrario seguira decodificandoejecutantando todos los 1s y 0s de la memoria.

1.4.5. QUINTA CAPACIDAD BASICA

Las computadoras tienen circuitos electrnicos que pueden tomar decisiones simples. La clase
de decisiones que pueden hacer los circuitos no es del tipo: "Quin ganar el partido de ftbol
que se juega esta noche?" o "Cul es la ciudad ms grande del Per?". Desafortunadamente
las computadoras slo pueden decidir la verdad o falsedad de la comparacin de dos nmeros,
uno de los cuales o los dos deben estar almacenados no en la memoria si no ms bien en uno
de los 13 registros, o tambin medios registros, que ya mencionamos anteriormente, que son
unos dispositivos que tienen las computadoras para almacenar datos numricos, tal como lo
hace en la memoria, y constituyen dispositivos auxiliares que son muy importantes. Por ejemplo
si los medios registros ch y cl, contienen nmeros, la computadora puede saber si cualquiera
de las siguientes afirmaciones es verdadera o falsa:

(1) ch < cl ( es el numero en ch menor que el numero en cl?)
(2) ch cl ( es el numero en ch menor o igual que el numero en cl?)
(3) ch > cl ( es el numero en ch mayor que el numero en cl?)
(4) ch cl ( es el numero en ch mayor o igual que el numero en cl?)
(5) ch cl ( es el numero en ch diferente que el numero en cl?)

Si queremos que cuando ch<cl sea verdad se escriba en pantalla el valor de ch, y que cuando
ch<cl sea falsa escriba en pantalla primero el calor de cl y despus el valor de ch, en castellano,
deberamos especificar lo siguiente:

Si ch < cl es verdad entonces escribe en pantalla cl
en caso contrario escribe en pantalla ch y cl

que traducido al lenguaje Ensamblador y para ch=3 y cl=5, se convierte en

mov ah,2
mov ch,5
mov cl,3
cmp ch, cl
jl salgo ; jl significa jump if less (salta si es menor)
mov dl,ch ; continua con
int 21h ; estas
mov dl,0Ah ; instrucciones
int 21h ; si es falso
salgo: mov dl,cl
int 21h




13


Como en este caso ch<cl es falsa, escribir en pantalla primero el ASCII 5 y a continuacin en
la siguiente lnea el ASCII 3. A estas instrucciones que permiten comparar dos nmeros se les
llama instrucciones de control o instrucciones de seleccin simple.

Para que ms nos sirven las comparaciones?. La respuesta es simple: para controlar la
ejecucin del programa; por ejemplo para lograr que un grupo de instrucciones se repita un
numero determinado de veces. Esto se estudiar ms adelante con todo detalle. Ya hemos
indicado que una vez que todas las instrucciones de programa han sido cargados en memoria, la
computadora empieza a ejecutar una instruccin cada vez, desde la primera hasta la ultima, que
debe ser una instruccin int 20. Para hacerlo la computadora tiene un dispositivo de
almacenamiento magntico, llamado registro IP, que est en la CPU, fuera de la memoria, cuyo
contenido indica la direccin de memoria donde est almacenada la instruccin que
proximamente se va a ejecutar. Cada vez que se ejecuta una instruccin, el valor de IP se
incrementa automticamente para apuntar a la siguiente instruccin a ejecutar.

Por ejemplo el siguiente programa ejecuta 299 instrucciones antes de terminar: (las instrucciones
mov ax,1 y int 20h, 1 vez, y las instrucciones add ax,1, cmp ax,100 y jl sigo, 99 veces cada
una)

mov ax,1
sigo: add ax,1
cmp ax,100 ; Compara ax con 100
jl sigo ; jump if less (si ax < 100 es verdad bifurca a sigo)
Int 20

1.4.6. SEXTA CAPACIDAD BASICA

Esta capacidad se llama persistencia de los datos. En la mayora de las aplicaciones la
capacidad de las computadoras de almacenar y acceder a grandes cantidades de informacin
desempea la parte dominante y se considera como su caracterstica principal; su capacidad de
contar o computar, es decir, calcular y realizar operaciones aritmticas, en muchos casos se ha
vuelto casi irrelevante.

Para lograr la persistencia se utiliza un dispositivo de almacenamiento secundario llamado
archivo y que no forma parte de la memoria.

Para entender esto mejor, hagamos una abstraccin de lo que acabamos de decir. Imaginemos
que un archivo es un rectngulo cuyo nombre es DATOS.DAT que est contenido en un
disco (ver la siguiente figura) y queremos almacenar el dato numrico 3 en el disco, para
utilizarlo posteriormente, entonces escribimos las siguientes instrucciones en lenguaje
Ensamblador:








14
X

.model small
.data
arch db 'a:\DATOS.DAT',0
Nhandle dw 0
dato db 33h
dato_leido db ?
.code
main proc
mov ax,@data ; lee direccin del segmento de datos
mov ds,ax ; guarda esta direccin en el registro ds
mov ah,3ch ; se prepara para crear el archivo
xor cx,cx ; cx=0, debe tener 0 bytes
lea dx,arch ; arch apunta a nombre a:DATOS.DAT
int 21h ; crea el archivo
mov ah,3dh ; se prepara para abrir el archivo
mov al,1 ; ah=1 significa para escritura
lea dx,arch ; arch apunta a nombre 'a:\DATOS.DAT'
int 21h ; abre el archivo y asigna ax un # (handle)
mov Nhandle,ax ; Nhandle = # (nmero asignado a arch)
mov ah,40h ; se prepara para escribir archivo con #andel en bx
mov bx,Nhandle ; identifica el archivo por su handle
mov cx,1 ; en cx el # de bytes a escribir, en este caso 1
lea dx,dato ; en dx la direccin de memoria donde esta el dato a escribir
int 21h ; escribe en el archivo, mueve el 3 de memoria a disco
mov ah,3eh ; se prepara para cerrar archivo con #handle en bx
mov bx,Nhandle ; identifica al archivo por su handle
int 21h ; cierra el archivo
mov ah,4ch ; se prepara para pasar control al DOS
int 21h ; termina y pasa el control al DOS
main endp
end main



Dato se mueve de memoria
a disco
programa MEMORIA

DATOS.DAT datos




Cuando se ejecuta las dos ultimas instrucciones: mov ah,4ch y int 21h, el programa termina y se
descarga de memoria, y por tanto el dato, que es el nmero 3, que estaba almacenado en
memoria se pierde y nunca ms lo podremos recuperar.

Pero si cargamos en memoria y luego ejecutamos el siguiente programa:
3
3




15


y

.model small
.data
arch db 'a:\DATOS.DAT',0
handle dw 0
dato db 33h
dato_leido db ?
.code
main proc
mov ax,@data ; lee direccion del segmento de datos
mov ds,ax ; guarda la dirrecion en ds

mov ah,3dh ; se prepara para abrir un archivo que apunta dx
mov al,0h ; al = 0 significa para lectura
lea dx,arch ; dx apunta a nombre 'a:\DATOS.DAT',
int 21h ; abre archivo y asigna en ax (# handle)
mov Nhandle,ax ; Nhandle = # handle
mov ah,3fh ; se prepara para leer archivo de #handle en bx
mov bx,Nhandle ; Identifica en bx el #handle
mov cx,1 ; bytes a leer 1
lea dx,dato_leido ; dx= direccin de memoria donde guardar dato que lee
int 21h ; lee archivo, mueve dato de disco a memoria

mov dl,dato_leido ; dl = dato leido de archivo
mov ah,2 ; se prepara para escribir ASCII dl en pantalla
int 21h ; escribe ASCII de dl en pantalla

mov ah,4ch ; se prepara para terminar
int 21h ; termina y pasa el control al DOS
main endp
end main


El resultado logrado sera que el dato numrico 3 que esta en el archivo A.\DATOS.DAT se lee
y se guarda en memoria en dato_leido, este se mueve a dl y luego se muestra en la pantalla de
la computadora, es decir que en esta forma hemos recuperado el valor del nmero 3, creado con
el primer programa y grabado en el archivo, que de otra forma se hubiera perdido para siempre.

MEMORIA
programa


DATOS.DAT
disco

dato se mueve de disco a memoria



3
3
16

1.4.7. SETIMA CAPACIDAD BASICA

Concepto de reutilizacin

La mayora de los programas se construyen a medida en vez de ensamblando componentes
existentes. Considere, como comparacin, la forma en que se disea y fabrica el hardware de
una computadora. El ingeniero de diseo construye un esquema sencillo de circuitera digital,
hace algn anlisis fundamental para asegurar que se realiza la funcin adecuada y va al
catalogo de ventas de los componentes digitales existentes. Cada circuito integrado tiene un
nmero de pieza, una funcin definida y validada, una interfaz bien definida y un conjunto
estndar de criterios de integracin. Despus de seleccionar cada componente, puede
ordenarse la compra.

Por desgracia los programadores no disponen del lujo descrito anteriormente. Con unas cuantas
excepciones, no existen catlogos para componentes de software. Es posible pedir software ya
hecho, pero solo como una unidad completa, no como componentes que pueden reensamblarse
en nuevos programas.

Aunque se ha escrito mucho sobre la reutilizacin del software, hasta el momento se han
conseguido pocos xitos tangibles, los ms importantes son: las bibliotecas de subprogramas
en la programacin tradicional, casi en desuso, y ahora ltimo, las bibliotecas de clases en la
programacin orientada a objetos y el reuso de cdigo binario de una aplicacin, que son piezas
reusables de cdigo que se llaman componentes, y la habilidad para usar componentes, para
intercomunicarse, se llama interoperatibilidad. Es decir las formas de reuso que existen son las
siguientes:

Programacin tradicional ( libreras estticas de mdulos objeto)

Reuso Programacin de cdigo fuente ( librerias de clases componentware)
Orientada a
Objetos de cdigo binario de una aplicacin ( componentes binarios dinamicos)

La reutilizacin que describiremos a continuacin, es la de bibliotecas de subprogramas,
utilizando un subprograma de nombre fsqrt, que obtiene la raiz cuadrada de un nmero

Un ejemplo concreto sobre la reutilizacin

La computadora como hemos dicho anteriormente solo puede hacer aritmtica simple: sumar,
restar, multiplicar y dividir.

Si nos encontramos con el problema de calcular la raz cuadrada de un nmero, cmo
resolvemos el problema?. Muy sencillo, recurrimos a la capacidad bsica de la computadora: la
reutilizacin.

El siguiente es un programa en lenguaje Ensamblador que calcula la raz cuadrada de cualquier
nmero ledo de teclado, digitado con formato flotante:






17




; Programas Ejem07B.asm y Ejem07BCap_Bas7Reutilizacin.asm
.model small
.386
.data
x dq ?
mensa1 db 'Ingrese un numero: $'
mensa2 db 'Raiz cuadrada : $'
.code
extrn crlf:near,lee_float:near,escribe_float:near
main proc
mov ax,@data
mov ds,ax
lea dx,mensa1
mov ah,9
int 21h
call lee_float
mov dword ptr x,eax
mov dword ptr x+4,edx
call crlf
lea dx,mensa2
mov ah,9
int 21h
finit
fld x
fsqrt ; obtiene la raiz cuadrada de x
fst x
mov eax,dword ptr x
mov edx, dword ptr x+4
call escribe_float
mov ah,1
int 21h
mov ah,4ch
int 21h
main endp
end main


La instruccin que utiliza la capacidad de reutilizacin es fsqrt;. Aqu el nombre de variable fsqrt,
es el nombre de una funcin que calcula la raz cuadrada de x. Lo que estamos haciendo es
simplemente reutilizar un programa que calcula la funcin fsqrt (raz_cuadrada en
aritmtica flotante), que ya fue escrito y probado anteriormente por otro programador. No
es necesario que nos desgastemos en escribir este programa, lo que tenemos que hacer es
reutilizarlo. Para que reinventar la rueda si ya existe?. Es lgico que podemos disear un
programa en Assembler u otro lenguaje para calcular la raiz cuadrada de un nmero flotante.

Podemos afirmar que programar en Ensamblador, utilizando las librerias estticas de objetos, es
un caso concreto de reutilizacin. Para programar en Ensamblador, usando estas libreras, hay
18
que conocer las instrucciones de mquina y las instrucciones de Ensamblador, saber cmo
declarar variables, construir expresiones, conocer las estructuras de control y adquirir los

conocimientos fundamentales de sus capacidades de controlar la ejecucin de ciclos de
repeticin. Consecuentemente, el conocimiento del lenguaje Ensamblador es de suma
importancia, ya que de lo contrario difcilmente podremos escribir nada de cdigo, y eso es lo que
pretendemos con este libro: empezar desde 0.















































19


CAPITULO II El entorno del programa Debug.exe

2.1 Introduccin.

Lo primero que tenemos que hacer, es aprender cules son los pasos para programar en
lenguaje de mquina, que es el lenguaje ms cercano a la computadora o sea del nivel ms bajo,
en relacin a todos los lenguajes de programacin que existen y que tambin se les llama
lenguajes artificiales y que son de alto nivel porque estn ms cerca de los lenguajes que
emplea el hombre, tales como el espaol, el ingls, etc. a los que se les denomina lenguajes
naturales. Empezaremos a familiarizamos con el entorno del debugger. Esto es, utilizaremos el
programa que se llama debug.exe, al que hemos hecho referencia en el primer captulo, pero de
forma muy superficial. Este programa nos servir para ensamblar y ejecutar nuestros primeros
programas. El nombre de debugger, proviene de bug que es un trmino muy utilizado en
ingls para describir una falla en la secuencia de instrucciones de un programa, que impide a
ste operar correctamente. Dicha falla puede ser desde un error sintctico hasta un error lgico.
Por lo tanto depurar es la accin de corregir dichas fallas, y es uno de los tantos usos que se le
da al debug.exe.

El debug.exe es una utilera que nos ayuda a realizar tres tareas:

Ver el contenido de las memorias RAM y ROM.
Ejecutar un programa, ya sea en su totalidad o de una en una instruccin.
Ensamblar y ejecutar programas sobre la marcha.

Usando el debug.exe podremos trabajar inmediatamente con las instrucciones de mquina sin
necesidad de conocer todos sus requerimientos formales, para as darse cuenta de su podero y
potencial.

2.1 Elementos iniciales del programa Debug.exe

Se puede iniciar debug.exe, en la siguiente forma:

1. Pulsar el botn Start (Inicio) del Windows. En el men emergente elija la opcin Run
(Ejecutar). En la ventana Open (Abrir) digitar debug.exe y pulsar botn OK
(Aceptar). En forma inmediata el Windows muestra en pantalla un guin () como
indicacin que se ha cargado en memoria el programa debug.exe

2. Para crear un archivo o examinar memoria, teclee debug sin especificar ningn nombre
de archivo: debug <enter>

3. Para modificar o depurar un programa (.COM o .EXE) o para modificar un archivo
cualquiera o por ejemplo, modificar el programa prueba.com, que se encuentra grabado
en un disquete, teclee debug con una especificacin de archivo, como

debug a:prueba.com. <enter>

El DOS carga a debug.exe en la memoria y muestra un guin () como indicacin de que l es
el programa almacenado en memoria.
20
A continuacin damos una descripcin de cada comando debug, en orden alfabtico, en los que
direccin es un nmero de una direccin en memoria.

A (direccin) los parntesis indican que el dato direccin es obligatorio

A significa Ensamblador (del Assembler en ingles). Se utiliza para ingresar cdigo fuente en
lenguaje de mquina que es muy cercano al lenguaje Ensamblador, pero que veremos tiene
muchas limitaciones, con respecto a este ltimo.

D (direccin)

D significa Dump en ingls vaciar o dumpear en castellano. Significa volcar el contenido de
una parte de la memoria, desplegando en pantalla, este contenido en notacin hexadecimal y/o
smbolos ASCII.

E (direccin)

E significa enter en ingles o ingresar en castellano. Sirve para ingresar datos numricos a
memoria en base hexadecimal, de dos en dos dgitos hexadecimales por vez, y la pulsacin del
tecla espacio para pasar a los siguientes dos datos. Los datos ingresados se almacenan en la
direccin que obligatoriamente tiene que digitarse despus de escribir la letra E.

G [direccin] aqu los corchetes indican que es opcional la direccin

G significa go en ingls y correr o ir en castellano. Sirve para ejecutar un programa en lenguaje
de mquina que se est examinando, hasta un punto de interrupcin especificado en [direcci n]
que es opcional. Si no se especifica la direccin, el programa contina hasta terminar.

H (nmeros hexadecimales)

H significa Hexadecimal. Sirve para mostrar la suma y diferencia de dos nmeros
hexadecimales. La longitud mxima de los datos es de cuatro dgitos hexadecimales.

N [nombre_del_archivo]

N significa name o nombre en castellano. Pone nombre a un programa o archivo que se desea
grabar en disco.

P [direccin] [valor]

P significa proceed en ingles o procedimiento en castellano. Efecta una llamada a una
subrutina (call), iteracin (loop), interrupcin (int) o repite una cadena de instruccin (REP) hasta
la siguiente instruccin. El formato general es: P [direccin] [valor], donde direccin es un
nmero que da la direccin de inicio que es opcional y valor es el nmero de instrucciones,
tambin opcional, para proceder con ellas.

Si no se especifica la direccin se ejecuta la instruccin a la que est apuntando el registro IP,
registro que describiremos ms adelante.





21


Q

Q significa Quit en ingles quitarse o salir en castellano. Sirve para salir del ambiente de
trabajo del Debug.exe

R [nombre_de_registro]

R significa Register en ingles o registro en castellano. Sirve para desplegar el contenido del
registro que figura en nombre_de_registro y abre la opcin de modificar su valor. Si no se
especifica [nombre_de_registro], despliega todos los registros sin opcin al cambio de sus
contenidos.

T [direccin][valor]

T significa Trace en ingls o rastreo en castellano. Ejecuta un programa en modo de un solo
paso. La entrada opcional [direccin] le indica a debug.exe en donde inicia el rastreo y el valor
opcional le indica el nmero de instrucciones por rastrear. La omisin de los operandos provoca
que debug.exe ejecute la instruccin siguiente a la que apunta el registro IP.

U [direccin o rango]

U significa en ingls Unemsamble o desensamblar en castellano. Desemsambla instrucciones
de mquina. El registro por omisin es la pareja CS:IP. Y si se omite la direccin o el rango
desensambla 32 bytes desde el ultimo U si hubo uno previo.

W [direccin [unidad sector_inicial nmero_de_sectores]]

W significa en ingls write y en castellano escribir. Graba en disco un archivo con las
caractersticas de nombre y tamao, previamente indicadas. Si no se utilizan operandos,
anticipadamente hay que poner nombre al archivo con el comando N, y el nmero de registros
con el comando R CX, que permite ingresar como valor en el registro CX, el nmero de bytes a
grabar

PASOS PARA PROGRAMAR EN LENGUAJE DE MAQUINA CON EL DEBUG.EXE

Ejemplo 0

El siguiente programa, es clebre por que era el primer ejemplo que apareca en 1978 en el
primer libro para aprender a programar en C, escrito por Kermighan y Ritchie, titulado The C
Programming Language, que atrajo gran atencin sobre este lenguaje, y que se convirti en uno
de los libros cientficos de computadoras de ms xito de todos los tiempos:

Void main()
{ printf(Hola mundo);
getch();
}

Escribamos este programa en lenguaje de mquina siguiendo los siguientes pasos (trabajando
con Windows 2000):
22
PRIMER PASO
Este paso ya fue descrito anteriormente. Comenzamos pulsando el botn Start (Inicio) del
Windows. En el men emergente elija la opcin Run (Ejecutar). En la ventana Open (Abrir)
digitar debug.exe y pulsar botn OK (Aceptar). En forma inmediata el Windows muestra en
pantalla un guin () como indicacin que se ha cargado en memoria el programa debug.exe

SEGUNDO PASO
A la derecha del guin digite la letra A y pulse la tecla enter (entrada). A continuacin digite el
siguiente cdigo una instruccin por lnea seguida de un enter para pasar a la siguiente lnea:

A <enter>
mov dx,109 <enter>
mov ah,9 <enter> el $ significa fin de cadena
int 21 <enter>
int 20 <enter>
db Hola mundo, desde el Assembler!$ <enter>
<enter>

El ltimo <enter> le sirve para salir del modo A (Ensamblador), que slo se utiliza para ingresar
o modificar cdigo fuente.

TERCER PASO
Verifique que el cdigo digitado es idntico al que figura ms arriba. No se olvide del smbolo $
en la ltima instruccin, antes de la doble comilla.

Para correr el programa digite G (Go) y el programa se ejecutar sin ningn problema, siempre
y cuando no haya cometido un error al ingresar el cdigo.

El resultado ser el siguiente: En la pantalla aparece el mensaje:

Hola mundo, desde el Assembler!

Y a continuacin un mensaje del DOS, indicando que el programa se ejecut normalmente:
Program terminated normally

CUARTO PASO
Procedemos a dar un nombre al programa y grabarlo en disco, ejecutando lo siguiente:

Digite N Ejem00.com <enter>, siendo Ejem00.com el nombre que hemos elegido para el
programa que est en memoria.

Establezcamos el tamao en bytes que va a tener el archivo en disco. Como el desplazamiento
va desde cs:100 hasta cs:012B, sumamos 1 a la diferencia de 012B menos 0100, y obtenemos
2C bytes (= 012B - 0100 + 1) de longitud del programa. En el sistema decimal esto equivale a
2*16+12 = 44 bytes. Por tanto este tamao se guarda en el registro cx. Debido a eso es que
utilizamos el comando R CX <enter> y luego se digita el valor calculado 2C y se da <enter>.

A continuacin grabamos el programa prueba.com en disco, digitando W sin ningn operador.
El DOS con el mensaje Writing 0002C, nos avisa que ha grabado el archivo en disco.




23


QUINTO PASO

Podemos verificar el programa que est almacenado en memoria utilizando el comando:
U (UnEnsamblador). Pero para que no aparezca ms informacin que la que se necesita
digitamos: U 100 109, que comprende el cdigo que v desde el desplazamiento 100 hasta el
109, como se ve en la siguiente pantalla:

SEXTO PASO

Para salir digitamos Q (quit) y retornamos al panel principal del Windows.



Ejecucin del programa Ejem00.com desde el DOS

Si deseamos volver a ejecutar el programa Ejem00.com, pero ahora desde el DOS, sin recurrir al
debug.exe, procedemos en la siguiente forma:

PRIMER PASO
Pulsar el botn Start (Inicio) del Windows. En el men emergente elija la opcin Run (Ejecutar).
En la ventana Open (Abrir) digitar cmd y pulsar botn OK (Aceptar). En forma inmediata el
Windows muestra la pantalla del sistema operativo DOS.

SEGUNDO PASO
Verifiquemos si el programa prueba.com se encuentra en el disco duro, digitando:

dir Ejem00.com,

si este programa est en el disco muestra su nombre, tamao y fecha de creacin. Si no lo
encuentra despliega un mensaje de error, y tiene que vol ver a ejecutar todo el procedimiento
que se ha descrito.
24
TERCER PASO
Para ejecutar el programa Ejem0.com, digite solamente el nombre Ejem00, no es necesario
utilizar la extensin .com. Acto seguido el programa muestra en pantalla el mensaje:

Hola mundo, desde el Assembler!

La siguiente pantalla muestra el resultado de correr el programa Ejem0.com:



NOTACION SIERRA

Cuando tengamos escritos varios programas Ejem00.com, Ejem01.com, . . . , Ejem12.com, . . . ,
Ejem26.asm, ..., etc., en el caso particular de uno de ellos, por ejemplo, el nombre Ejem00.com,
del programa que acabamos de crear con el debug.exe, no nos dice nada referente a lo que
hace el programa, y esto nos puede traer a confusin. Para evitar esto, recurrimos a la facilidad
que nos da el Windows, que nos permite utilizar nombres de hasta 255 caracteres, usando la
llamada notacin sierra, en alusin a los dientes de una sierra, que consiste en escriber el
nombre de un archivo, empezando cada palabra del nombre del archivo con una letra
mayscula. En esta forma mantendremos para cada programa dos nombres: el primer nombre
que es permitido por el DOS, con un mximo de 8 caracteres para el nombre y 3 caracteres
para la extensin, y el segundo nombre, que es permitido por el Windows, con notacin sierra,
que nos recuerde lo que hace el programa. As por ejemplo para el caso del programa
Ejem00.com conservaremos este nombre y este otro en notacin sierra:
Ejem00EscribeHolaMundo.com. Para obtener este ltimo digitamos lo siguiente:

Copy Ejem00.com Ejem00EscribeHolaMundo.com

El de notacin corta Ejem00.com nos sirve para ejecutarlo, digitando simplemente:

Ejem00 <enter>

As mismo, si deseamos modificar o depurar el programa Ejem00.com recurrimos al programa
debug.exe escribiendo:

debug Ejem00.com <enter>.




25


En cambio el otro con nombre ms largo, nos sirve para indicarnos lo que hace el programa; en
este caso concreto el nombre que le hemos asignado nos recuerda que este programa escribe
en pantalla el mensaje hola mundo desde el Ensamblador.

Si por alguna circunstancia ha perdido el Ejem00.com, pero conserva el que tiene nombre en
notacin sierra, puede recuperar el primero escribiendo:

copy Ejem00*.com Ejem00.com <Enter>

y quedar recuperado el programa Ejem00.com

2.2. Los recursos de la programacin en lenguaje de mquina y en lenguaje
Ensamblador:

La filosofa de los que disearon el lenguaje Ensamblador tiene que ser muy diferente de la que
utilizaron los diseadores de los lenguajes de alto nivel. Esto se ha hecho as en estos ltimos,
para aumentar la productividad del programador. La sintaxis de un lenguaje de alto nivel,
presenta al programador instrucciones que son potentes, si se comparan con las del
Ensamblador.

En promedio, por cada instruccin de un lenguaje de alto nivel se generan de 10 a 20
instrucciones de mquina.

En cambio por cada instruccin del Ensamblador se genera una sola instruccin de mquina.

Por eso programar en Ensamblador es completamente diferente a cmo se hace en un lenguaje
de alto nivel, cuya sintaxis debe aproximarse lo ms posible al idioma ingls mientras ms se
aproxima al lenguaje natural que es el ingls, mayor es su nivel y ms aceptacin tendr en los
programadores; el COBOL naci con esta filosofa, que es el lenguaje humano, en el que se
codifican las instrucciones de los programas fuente de casi todos los compiladores que existen
en el mercado.

Si se entiende bien cul es la filosofa de la programacin en Ensamblador, mayores
posibilidades de xito se tendr en la difcil tarea de programar en este lenguaje.

Un programa en lenguaje Ensamblador es un cdigo que combina, de la forma ms optima
posible, la utilizacin de los siguientes cuatro recursos:

(1) Memoria

(2) Registros

(3) Interrupciones y

(4) Instrucciones de Ensamblador.

Pasamos a describir cada uno de ellos:


26
2.3. Memoria

La memoria es uno de los principales recursos de las computadoras digitales. Ms adelante
comprobaremos que la primera, segunda, cuarta y quinta capacidades bsicas de la
computadora tienen que ver con la memoria.

La memoria es un dispositivo electromagntico, que permite almacenar los datos tratantes que
son las instrucciones y los datos tratados que son los datos propiamente dichos. Cuando se
ejecuta un programa los datos tratantes interactan con los datos tratados para producir nuevos
datos tratados, que son los que se devuelven al usuario del programa.

Lo que se almacena en la memoria son 1s y 0s, y sabemos que cada una unidad de
almacenamiento que almacenan estos 1s y 0s se llama bit. As la cadena 101111102, requiere
8 bits para almacenarse en memoria.

El tamao de la memoria, que por ser un medio de almacenamiento fsico, tiene un tamao
finito, es igual al nmero de bits que puede contener, es decir cuntos 1s y/o 0s puede
almacenar. Como este nmero que da el tamao es muy grande, se recurre a utilizar unidades
de almacenamiento ms grandes que el bit. Estas unidades son:

1 nibbel que tiene 4 bits
1 byte que tiene 8 bits
1 kbyte (kilo byte) que tiene 2
10
bytes = 1,024 bytes
= 8,192 bits
1 Mbyte (mega byte) que tiene 2
20
bytes = 1,024 Kbytes
= 1,048,576 bytes
= 8,388,608 bits
1 Gbyte (giga byte) que tiene 2
30
bytes = 1,024 Mbytes
= 1,048,576 Kbytes
= 1,073,741,824 bytes
1 Tbyte (tera byte) que tiene 1024 Gbytes = 2
40
bytes
= 1,048,576 MBytes
= 1,099,511,627,776 bytes

Recordemos que en el sistema mtrico 1 kilo, significa 1000 = 10
3
, en cambio en informtica
1 kilo equivale a 1,024 = 2
10
, aproximadamente 1000, pero no 1000.

Supongamos que la memoria tiene 1 Mbyte =1,048,576 bytes =8,388,608 bits, esto es tiene
aproximadamente 1 milln de bytes es decir 8 millones de bits.

Es necesario entender que todos los bits tienen que estar interconectados, para poder guardar y
recuperar ya sea el 1 o 0 que tenga almacenado; el hecho es que tenemos que poder dirigirnos a
la direccin de memoria a nivel de bit.

Para simplificar esto, se ha convenido en utilizar el byte como medida de direccionamiento, y
cada byte se le asigna un nmero hexadecimal que es su direccin, que va desde el primer byte
al que se le asigna la direccin que es el nmero hexadecimal 0000016 hasta la direccin
FFFFF16 que corresponde al ultimo byte 1,048,576.





27


2.3.1 Direccionamiento absoluto y segementado. Direccionamiento
segmentado segmento:desplazamiento

Haciendo una abstraccin, podemos entonces representar una memoria RAM de 1 Mbyte en
la siguiente forma:

Direccin Byte No.

0000016 1
0000116 2
0000216 3
0000316 4
0000416 5
0000516 6
0000616 7
0000716 8
0000816 9
0000916 10
0000A16 11
0000B16 12

. . . . . . . . .
8D29816 578,200
8D29916 578,201
8D29A16 578,202
8D29B16 578,203
. . . . . . . . .
FFFFC16 1,048,573
FFFFD16 1 1,048,574
FFFFE16 1,048,575
FFFFF16 1,048,576

Esta forma de direccionar se llama direccionamiento absoluto. Vemos entonces que para
direccionar a todos los bytes de una memoria RAM, de 1 Mbyte, requerimos nmeros
hexadecimales de 5 dgitos. Como cada nmero hexadecimal tiene 4 bits, para direccionar a la
memoria requerimos 4 x 5 = 20 bits. Pero como veremos ms adelante los registros del 8086
tienen 16 bits, entonces los diseadores del procesador Intel 8086, tuvieron que ingeniarse y
recurrieron al direccionamiento segmentado. Para ello imaginaron la memoria dividida en
segmentos de 64 Kbytes. A estos segmentos los numeraron desde 000016 hasta FFFF16,
usando nmeros de 4 hexadecimales que requieren 16 bits = 2 bytes para designarlos, y estos
16 bits si se pueden almacenar en los registros de segmento. A los bytes de cada sector de 64
Kbytes, los numeraron desde 000016 hasta FFFF16; a esta direccin le llamaron offset en ingls
(o desplazamiento en castellano). Al hacer esto para direccionar la memoria se requieren dos
datos: el nmero del segmento y el desplazamiento u offset dentro de este segmento . En esta
forma la direccin en memoria de cualquier byte la designaremos con dos valores:
segmento:desplazamiento, a este tipo de direccionamiento lo llamaremos direccionamiento
segmentado con relacin al direccionamiento absoluto, que solo requiere un solo dato
numrico.

28
Toda la programacin que hagamos en este libro de Ensamblador, la haremos utilizando el
direccionamiento segmentado segmento:desplazamiento, el sistema operativo se encargar de
convertir la direccin segmentada a direccin absoluta que es la real. Es fcil deducir la siguiente
frmula, que convierte la direccin segmentada a direccin absoluta o real:

Segmento16:desplazamiento16 = segmento16 * 1016 + desplazamiento16 (*)

Aunque parezca increble, esta forma de direccionamiento produce overlaps de segmentos
(sobre posicionamiento en castellano). Por suerte el sistema operativo es el que maneja la
distribucin de memoria cuidando que los overlaps no produzcan problemas de
sobreposicionamiento de datos en la memoria. Pasamos a ver unos ejemplos y verificar esto
utilizando el programa debug.exe

Ejemplo

Convertir las direcciones segmentadas, que se dan a continuacin, a direcciones absolutas. Las
direcciones estn dadas en base hexadecimal.

( 1 ) 0000:0010

( 2 ) 0001:0000

( 3 ) 0000:1050

( 4 ) 0070:0950

( 5 ) 0100:0050

( 6 ) 0105:0000

Solucion: Aplicando la frmula (*) se tiene sin considerar los ceros a la izquierda de los datos
numricos:

( 1 ) 0000:0010 = 016 * 1016 + 1016 = 10 = 0001016

( 2 ) 0001:0000 = 116 * 1016 + 016 = 1016 + 0 16 = 0001016

( 3 ) 0000:1050 = 016 * 1016 + 105016 = 016 + 1050 16 = 0105016

( 4 ) 0070:0950 = 7016 * 1016 + 95016 =70016 + 950 16 = 0105016

( 5 ) 0100:0050 = 10016 * 1016 + 5016 = 100016 + 50 16 = 0105016

( 6 ) 0105:0000 = 10516 * 1016 + 000016 = 105016 + 0000 16 = 0105016

Observamos que las direcciones segmentadas (1) y (2) a pesar que estn en diferentes
segmentos, tienen la misma direccin absoluta 0001016, es decir la direccin real.

Se afirma lo mismo con respecto a las direcciones segmentadas (3), (4) , (5) y (6), las cuatro
apuntan a la misma direccin absoluta 0105016.

Eso es lo que pasamos a probar:




29


Offset Direccin
Absoluta

00000
Segmento 0 0000 00001
0001 00002
0002 . . .
0003
Segmento 1 . . . 00010
0000
0001 0010
. . .
1050
. . .
FFFF 0104F
Segmento 70 01050
0000 01051
0001 FFFE . . .
0002 FFFF
. . .

0950

Segmento 100
0000
0001
. . .

0050

Segmento 105
0000
0001
. . .
. . .


. . . . . .
FFFD FFFFD
FFFE FFFFE
FFFF FFFFF

Prueba del overlap utilizando el debug.exe

Con el debug.exe probaremos la sobreescritura (overlap) de las direcciones segmentadas
0070:0950 y 0100:0050. Para hacerlo proceda as:

PRIMER PASO
Pulsar el botn Start (Inicio) del Windows. En el men emergente elija la opcin Run (Ejecutar).
En la ventana Open (Abrir) digitar debug.exe y pulsar el botn OK (Aceptar). En forma
30
inmediata el Windows muestra en pantalla un guin () como indicacin de que se ha cargado
en memoria el programa debug.exe

SEGUNDO PASO
A la derecha del guin digite -D 70:950 <enter>. El debug volcar el contenido de la memoria a
partir de la direccin segmentada, y podr observar que esa direccin de memoria contiene el
valor 0016. Procedamos a cambiar el valor 0016 por el valor CA16. Para hacerlo procedemos as:

Digite el comando E 70:950 <enter> y luego CA <enter>.

A continuacin digitando D 100:50 <enter>, podr verificar que en esta direccin est
almacenado el dato CA16

Todo esto se puede apreciar en la siguiente figura:



2.4. Disposicin de la memoria

Cada vez que se prende la computadora digital la memoria no contiene nada, por que debido al
carcter electromagntico de los componentes de la computadora, todo se destruy cuando
anteriormente se apag el sistema. Al comenzar a trabajar la computadora con la memoria vaca,
mediante un pequeo programa que se encuentra en el disco duro de la mquina, llamado boot
strap, el sistema operativo que administra la memoria, empieza colocando todos los
componentes RAM y ROM del sistema operativo en la memoria. Cuando se termina de cargar
todos los componentes que necesita la computadora para operar, la memoria queda distribuida
en la siguiente forma:






31


Direccin real

00000 Tabla de serv. de interr. - Vectores
00001 Area de programas de interrupcin
transitorios - Area datos BIOS y DOS
00600 Area de programas
de - Programas de aplicacin
0FFFF usuario
- Manejadores
9FFFF - Sistema operativo DOS
A0000
. . . 128 Kbytes - Memoria de exp. pant
BFFFF pantalla - Memoria de pantalla
C0000 Area de
CFFFF ROM
D0000 64 Kbytes
. . . memoria - Memoria expandida
DFFFF expandida
E0000
. . . Areas del sistema - ROM red
384 Kbytes - ROM disco
- Memoria de video
- Bios ROM
FFFFE
FFFFF

Memoria extendida



2.5. Registros

El procesador 8086 tiene 14 registros de 16 bits (pueden contener nmeros hexadecimales de
hasta 2 digitos), que son un recurso muy importante e imprescindible para almacenar datos que
no se encuentran en la memoria. Incluso se pueden hacer programas muy pequeos sin
necesidad de recurrir a la memoria para almacenar los datos intermedios. Adems la
programacin usando solo registros es ms rpida que aquella similar usando memoria y
registros.

Prcticamente los registros sirven para llevar el control de todo lo que sucede dentro de la PC.

Los registros pueden contener datos o direcciones de memoria.

Dichos registros se dividen en seis categoras como vemos a continuacin:

- De propsito general AX BX CX DX
(datos y direcciones) AH-AL BH-BL CH-CL DH-DL
acumulador base contador datos de
oper. aritm. Offset de bucles oper. aritm.

32
- De segmentos CS DS SS ES
(direcciones) Code Segment Data Segment Stack Segment Extra Segment
dir. del cod. dir. de dat. dir. de pila dir. extras
- Punteros de pila SP BP
(direcciones) Stack Pointer Base Pointer

- De indices SI DI
(direcciones ) Source Index Destination Index

- Puntero de instrucciones IP
(direcciones) Instruction Pointer

- Un registro de indicadores de estado (flags o banderas), sin nombre lgico

Pasamos a describir estos registros con mayor detalle:

( 1 ) 4 registros de propsito general. Que contienen datos y/o direcciones:

AX BX CX DX
AH AL BH BL CH CL DH DL

Estos cuatro registros son duales , es decir, pueden manipularse como si fueran de 8 o 16 bits:
En la modalidad de 16 bits son conocidos como AX, BX, CX y DX. En la modalidad de 8 bits se
les reconoce como AH, AL, BH, BL, CH, CL, DH y DL. Siendo la parte alta la que figura con la
letra H (high en ingls) y la parte baja la que figura con la letra L (low en ingls).

El registro AX, como iremos aprendiendo cuando empecemos a programar, tambin llamado
acumulador, resulta indispensable para toda operacin de entrada/salida, trabajando en
conjuncin con las interrupciones, y para algunas operaciones de cadenas.

El registro BX, tambin conocido como registro base, se usa para calcular direcciones que
accesan a la memoria.

El registro CX o contador es usado para llevar la cuenta en operaciones repetitivas, o como
contador en iteraciones que pueden involucrar o no operaciones sobre cadenas. Tambin sirve
como contador en operaciones relacionadas con bits individuales.

Finalmente se tiene el registro DX, tambin conocido como registro de datos, cuya finalidad es
servir como depsito de las direcciones de los puertos. En combinacin con el registro AX, se
utiliza para almacenar nmeros de 32 bits (DX:AX) en la multiplicacin y divisin. Otra aplicacin
de este registro es con las operaciones de interrupciones, durante las cuales conserva el
desplazamiento u offset del bloque de informacin que ser manejado. El registro DX,
generalmente se usa en combinacin con el registro DS, como DS:DX.

( 2 ) Los registros de segmento

El procesador tiene cuatro registros de 16 bits llamados registros de segmentos. El CS (code
segment) o registro del segmento de cdigo se encuentra asociado al cdigo del programa;
apunta al segmento que contienen el cdigo o datos tratantes; es decir, controla el cdigo de




33


los programas y tiene como socio al registro IP en el sentido que la combinacin CS:IP, es la
direccin de la prxima instruccin a ejecutar. El DS (data segment) o registro del segmento de
datos, contiene la direccin del segmento donde se guardan los datos propiamente dichos o
datos tratados. El ES (extra segment) o registro de segmento extra generalmente tiene la
funcin de servir de colchn para ampliar el segmento de datos. El SS (stack segment) o
registro del segmento de pila tiene la funcin de controlar el rea de la memoria donde se crear
la pila. Todo esto se puede apreciar en la siguiente figura:

direccin memoria

00000
00001
. . .
0016F
00170
CS = 0017 00171 64 kbytes
. . . de cdigo
1016F

. . .

1027F
10280
DS = 1028 10281 64 kbytes
. . . de datos
?


31000
SS = 3100 31001 64 kbytes de
. . datos de la pila
?


ES = 5000
50000
50001 64 kbytes de
. . . datos extras
5FFFF

FFFFE
FFFFF

Los registros DS, CS, SS y ES, son primordiales para generar la direccin de 20 bits que se
pondr en el bus de direcciones de la CPU. Cualquier operacin que accese la memoria usar
forzosamente uno de estos registros. Cada registro selecciona un rea que puede ser contigua o
no, de hasta FFFFh bytes de tamao o sea:

FFFFh bytes=16
4
bytes=2
16
bytes=2
6
x2
10
bytes =64x2
10
bytes=64 KBytes=65536 bytes
34
Toda instruccin utiliza los registros de segmentos con algn desplazamiento interno para
acceder a la informacin, como aprenderemos cuando empecemos a programar.

No es necesario utilizar los cuatro registros de segmento; el que si es imprescindible es el
segmento de cdigo. Si no est este segmento, sencillamente no hay programa.

( 3 ) Los registros de apuntadores de pila

BP SP



Como su nombre lo indica, son registros que apuntan a alguna localidad de memoria en general,
como se ve en la figura de ms arriba que apunta al segmento 310016. El BP (base pointer) o
apuntador base es muy usado para manipular la informacin que se encuentra en la pila. Una de
sus principales utilidades es proveer un mecanismo para poder pasar parmetros a rutinas. El
SP (stack pointer) o apuntador de pila, sirve para apuntar al comienzo de la pila, y el BP da el
desplazamiento u offset de la pila.

( 4 ) Los registros ndice

SI DI



Estos registros generalmente se utilizan en operaciones con cadenas. Un uso muy comn de
ellos es a travs de la instruccin MOVSB (move string byte), la cual copia bytes consecutivos a
partir de la direccin especificada por SI (source index) o ndice fuente en la direccin
especificada por DI (destination index ) o ndice destino. Tambin tiene uso en otro tipo de
operaciones, como el clculo de direcciones o el pase de parmetros a otras rutinas.

( 5 ) El registro apuntador de instrucciones

IP



El IP (intruction pointer) o apuntador de instrucciones, se usa en combinacin con el registro CS,
para especificar el rea de memoria donde se encuentra la siguiente instruccin por ejecutar.
Este registro cambia de contenido conforme al flujo de ejecucin del programa. Los programas
no pueden manejar directamente a este registro, pero si lo pueden hacer de forma indirecta
mediante instrucciones de bifurcacin (quinta capacidad bsica).

( 6 ) El registro de banderas

Este registro no tiene nombre lgico como los otros registros CS, DS, etc., nombre que se
podra utilizar en el programa fuente. Es un registro de 16 bits -de los cuales slo se utilizan 9-,
que reporta el status o resultado de alguna operacin aritmtica o lgica. Hay nueve banderas:





35


Seis banderas de estado

Registran el estado del procesador, normalmente asociado a una comparacin o una
instruccin aritmtica.

CF (Carry flag) - Bandera de acarreo. Indica acarreo en las instrucciones
aritmticas.
OF (Overflow flag) - Bandera de desbordamiento (aritmtico)
ZF (Zero flag) - Bandera de resultado cero o comparacin igual
SF (Sign flag) - Bandera de resultado o comparacin negativa
PF (Parity flag) - Bandera de paridad (nmero par de bits)
AF (auxiliar flag) - Bandera auxiliar. Indica si hay necesidad de ajuste en las
operaciones aritmticas con nmeros BCD (decimal codificado
en binario)

Tres banderas de control.

Registran el modo de funcionamiento del procesador.

DF (Direction flag) - Bandera de direccin. Controla la direccin (hacia delante o
hacia atrs) en las operaciones con cadenas de caracteres
incrementando o decrementando automticamente los registros
ndices SI y DI.
IF (Interrupt flag) - Bandera de interrupciones. Indica si estn permitidas o no las
interrupciones de los dispositivos externos.
TF (Trap flag) - Bandera de atrape. Controla la operacin modo de paso a
paso (usada por el programa debug.exe)

Las posiciones de las banderas dentro del registro son:

15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

OF DF IF TF SF ZF AF PF CF

Cada bit del registro de banderas tiene dos condiciones: encendido o apagado. En otras
palabras, puede ser igual a 1 (cuando est encendido) o igual a 0 (cuando est
apagado).

A continuacin se describe el significado de cada bit del registro de banderas.

Todas las banderas apagadas:

NV UP DI PL NZ NA PO NC

Todas las banderas prendidas:

OV DN EI NG ZR AC PE CY

36
Siendo el significado de los bits:

Overflow NV = no hay desbordamiento
OV =si lo hay
Direction UP = hacia adelante
DN = hacia atrs
Interrupts DI = desactivadas
EI = activadas
Sign PL = positivo
NG = negativo
Zero NZ = no es cero
ZR = si es cero
Auxiliary carry NA = no hay acarreo auxiliar
AC = hay acarreo auxiliar
Parity PO = paridad non
PE = paridad par
Carry NC = no hay acarreo
CY = si hay acarreo

Segmentos y registros asociados

En lenguaje de mquina o lenguaje Ensamblador, como la direccin segmentada se compone de
registro:desplazamiento, en muchos casos, para simplificar el cdigo, cada segmento tiene
asignados uno o ms registros asociados. Por ejemplo, en vez de escribir la instruccin mov
ax,DS:[BX], se escribe solamente mov ax,[BX], instruccion en la que [BX], significa
desplazamiento.

Podemos hacer esto por que el registro DS, tiene al registro BX como uno de sus asociados en
la siguiente relacin de registros asociados:

( 1 ) CS IP ( 2 ) DS BX, SI, DI

( 3 ) SS SP, BP ( 4 ) ES BX, SI, DI

2.6. Interrupciones

Recordemos que la tercera capacidad bsica de una computadora digital es la capacidad de
interface de entrada/salida y se ejecuta mediante instrucciones de entrada/salida. Las
interrupciones son el medio que tiene el procesador para realizar operaciones de entrada/salida.

De alguna manera, la CPU tiene que estar consciente de lo que sucede a su alrededor. Esta
conciencia la adquiere mediante las interrupciones. Cada vez que se oprime una tecla, el
teclado interrumpe a la CPU y le dice Oye, tengo algo para ti!. La CPU detiene lo que est
haciendo y pone atencin en el teclado y reacciona y ejecuta una predeterminada accin
dependiendo de cul tecla ha presionado el usuario. Para cada tecla la CPU reacciona en forma
diferente. Algo parecido sucede cuando se quiere escribir un carcter en la pantalla o en la
impresora, se produce una interrupcin. Las interrupciones ocurren tan seguido que la CPU
necesita un modo eficiente de manejarlas. Una manera de administrar las interrupciones, que se
usa en el entorno MS-DOS, es mantener una tabla de vectores (entindase direcciones) en la
memoria baja (esto lo explicaremos ms adelante en detalle cuando estudiemos programas
residentes TSR). Estos vectores de interrupcin sealan otra localidad de la memoria donde la




37


CPU empezar a ejecutar el cdigo que ah se encuentre. A esta tcnica se llama darle servicio
a la interrupcin. Despus de ejecutar esta tarea se retorna a la siguiente instruccin que sigue
a la interrupcin. En otras palabras, una interrupcin es una bifurcacin a cierta localidad de la
memoria (RAM o ROM) donde la CPU iniciar la ejecucin de una serie de instrucciones, y al
terminar regresar a la siguiente localidad de la instruccin que caus la interrupcin.

Las interrupciones se dividen en:

1. Interrupciones de hardware (interrupciones externas e internas)
Ejemplo el desperfecto de un perifrico o pulsar una tecla.

2. Interrupciones de software o internas

Ocurren como resultado de la ejecucin de una instruccin int, o una operacin de divisin
que cause desbordamiento, o ejecucin en modo paso a paso, con el debug.exe, con los
comandos T o P, por ejemplo. Existen 256 interrupciones de software (numeradas desde el
00h hasta FFh) Las interrupciones de software se dividen a su vez en:

( a ) Interrupciones del BIOS (Basic Input / Output System), que maneja
las interrupciones 00h hasta 1Fh.
- Controlan los perifricos y a veces funciones de disco
( b ) Interrupciones del DOS (Disk Operating System), que maneja las interrupciones
20h hasta 3Fh.
- Administran la memoria y el disco

La Interrupciones de DOS generalmente se usan cargando el parmetro de la funcin deseada
en el registro AH, invocando la interrupcin 21h. A este proceso se le llama utilizar las
funciones del DOS. En la prctica esta interrupcin resulta ser la ms usada. Una razn de ello
es mantener la compatibilidad a travs de las futuras versiones del sistema operativo
MS-DOS, que sigue siendo parte importante de los sistemas operativos Windows.

En esta primera parte, que programaremos en lenguaje de mquina, utilizaremos dos
interrupciones: la interrupcin INT 20h que no tiene funciones, y la interrupcin INT 21h, con
algunas de sus funciones de AH para los valores 01h, 02h, 08h, 09h, 0Ah, 4Ch, que pasamos a
describir:

INT 21h


AH


Funcin

01h Esperar para leer un carcter del teclado con eco
(con chequeo de CTRL-BREAK).
Salida: AL = Carcter ASCII, ledo de teclado

02h Escribe en pantalla el carcter ASCII contenido en
el registro DL

09h Escribe en pantalla la cadena de memoria
direccionada por DS:DX, que debe terminar en $
38
0Ah Lee una cadena caracteres del teclado y los almacena
en un rea de memoria. El primer byte del rea, grabado
previamente, debe ser distinto de cero e indica el nmero
mximo de caracteres a teclear (incluido el retorno
de carro). El segundo byte del rea indica el
nmero de caracteres tecleados ( sin incluir el
retorno de carro). Los datos se almacenan a partir
del tercer byte.
Direccin de entrada DS:DX

04Ch Retorno al DOS

INT 20h


Pasa el control al DOS, en programas COM


2.7. Instrucciones.

Ya hemos mencionado que a las computadoras digitales tambin se les llama computadoras
de programa almacenado porque para ejecutar un programa tienen que cargarlo ntegramente
en la memoria antes de correrlo. Aclaremos ms este concepto: Las computadoras o sistemas de
proceso de datos se caracterizan por el proceso digital de la informacin, as como por la
diferenciacin en instrucciones (programas) y datos de la informacin ambos representados
digitalmente en la memoria principal. Un programa es una secuencia de instrucciones dadas
por una persona (programador) a una maquina (computadora), indicandole a esta ultima con
detalle y precision cmo tiene que actuar para obtener la solucion de un problema, cuyos datos
van incluidos en el programa. Es decir se le indica a la maquina, exacta y totalmente que es lo
que tiene que hacer, mediante una secuencia de instrucciones, que se supone, la maquina
obedece ciegamente.

La computadora digital no hace otra cosa que explorar secuencialmente la informacin
almacenada en su memoria, que est en el programa, compuesto de un conjunto de
instrucciones, y las procesa siguiendo el principio de Von Neumann: primero lee cada instruccin
la decodifica e interpreta y segundo la ejecuta guardando los resultados en la memoria. Cada
vez que se ejecuta una instruccin el IP automticamente aumenta en 1 o ms, dependiendo del
tamao de la instruccin en bytes, y pasa a apuntar la siguiente instruccin.

El juego bsico de las instrucciones del microprocesador 8086 y que son compatibles con todos
los microprocesadores de la familia X86, est conformado con 92 instrucciones, agrupadas de la
siguiente manera, y que estudiaremos, poco a poco, con el suficiente detalle ms adelante.

Instrucciones de transferencia de datos ................ 14
Instrucciones aritmticas........................................ 20
Instrucciones de manejo de bits.............................. 12
Instrucciones de transferencia de control................ 23
Instrucciones de manejo de cadenas...................... 8





39


Instrucciones de interrupciones ............................ 3
Instrucciones de control del procesador.................. 12

Total ................................................ 92 instrucciones

Una instruccin en lenguaje de mquina esta compuesto por el nombre de la instruccin y de 0 a
2 operandos

Ejemplo: mov ax,41


nombre operandos

En lenguaje de mquina todas las constantes estn en base hexadecimal, as en el ejemplo
anterior el 41 significa 41h es decir 4116. Tampoco est permitido el uso de variables, etiquetas o
comentarios.

La terminacin de un programa de mquina se tiene que hacer con la INT 20h.

A continuacin pasamos a disear algunos programas simples en lenguaje de mquina.
Usaremos el programa debug.exe y sus rdenes: E, A, U, D, G, P, T, Q, N, R, que ya hemos
descrito anteriormente. Haremos algunos clculos aritmticos con nmeros hexadecimales y
rastrearemos los programas escritos.

Sabemos que en base a la equivalencia 2
4
= 16, se demuestra que la conversin de un nmero
hexadecimal a binario y viceversa es inmediata recurriendo a la siguiente tabla de conversin,
que se puede aprender de memoria en forma muy fcil, por que es muy til.

Numero_binario Nmero hexadecimal

00002 016
00012 116
00102 216
00112 316
01002 416
01012 516
01102 616
01112 716
10002 816
10012 916
10102 A16
10112 B16
11002 C16
11012 D16
11102 E16
11112 F16

Con esta tabla podemos convertir un nmero de binario a hexadecimal o viceversa en forma
inmediata:
40
1 0 1 0 1 1 1 1 1


1 5 F
Ejemplo 1

Este es un ejemplo ilustrativo. Es increble pero afirmamos que la siguiente cadena de unos y
ceros:

1011101000001001000000011011010000001001110011010010000111001101001000000110
0001011011000110011101101111011100100110100101110100011011010110111100100100

es un programa de computadora digital, que contiene tanto las instrucciones como los datos, y
que escribe en la pantalla la palabra: algoritmo. En realidad todos: programas grandes y
pequeos son cadenas de unos y ceros.

Para trabajar con mejor facilidad, usando la tabla de equivalencias anterior, convertimos los
nmeros binarios a hexadecimales y obtenemos esta otra cadena de nmeros hexadecimales:
BA 09 01 B4 09 CD 21 CD 20 61 6C 67 6F 72 69 74 6D 6F 24

Para ingresar el programa, utilizamos el comando E (Enter), que podemos utilizar en dos formas
diferentes:

( 1 ) Digitamos E 100 <enter> y a continuacin digitamos los nmeros hexadecimales, por
pares; despus de ingresar cada par pulsamos la tecla espacio. Al terminar con los dos ltimos
nmeros hexadecimales 2 y 4, pulsamos la tecla <enter> y aparece el guin que es el smbolo
del debug.exe.

Despus, para correr el programa usamos el comando G (go) y vemos que aparece la cadena
algoritmo y en la siguiente lnea el mensaje: El programa ha terminado con normalidad. Todo
esto lo podemos apreciar en la siguiente pantalla:






41


( 2 ) Digitamos E 100 BA 09 01 B4 09 CD 21 CD 20 61 6C 67 6F 72 69 74 6D 6F 24 <Enter>
y para correrlo digitamos -G, y obtenemos:


Si pulsamos el comando u 100, vemos los siguientos datos:

DIRECCION DIRECCION CONTENIDO LOS 1s y 0s
RELATIVA ABSOLUTA DE LA INTERPRETADOS
DE LA MEMORIA DE LA MEMORIA EN LENGUAJE
MEMORIA DE MAQUINA
IP=0100 IP=14BD0
00000
00001
. . .
14AD:0100 14BD0
14AD:0101 14BD1 mov dx,109
14AD:0102 14BD2
14AD:0103 14BD3
14AD:0104 14BD4 mov ah,09 instrucciones
14AD:0105 14BD5
14AD:0106 14BD6 int 21
14AD:0107 14BD7
14AD:0108 14BD8 int 20
14AD:0109 14BD9 a
14AD:010A 14BDA l
14AD:010B 14BDB g
14AD:010C 14BDC o
14AD:010D 14BDD r
14AD:010E 14BDE i datos
14AD:010F 14BDF t
14AD:0110 14BC0 m
14AD:0111 14BC1 o
14AD:0112 14BC2 $
. . . . . . . . .
14AD:FFFE 24ACE
14AD:FFFF 24ACF

Se pide grabar este programa con el nombre Ejem01.com y duplicarlo a su notacin sierra:
Ejem01CadenaBinariaComoPrograma.com.




10111010
00001001
00000001
10110100
00001001
11001101
00100001
11001101
00100000
01100001
01101100
01100111
01101111
01110010
01101001
01110100
01101101
01101111
00100100


42
A continuacin codificaremos en lenguaje de mquina los ejemplos dados al describir las
capacidades bsicas 1, 2, 3, 5, 6 y 7 de la computadora, con excepcin de la capacidad 4, de
programa almacenado, que acabamos de tratar ampliamente. (Grabar todos los programa como
.com)

Ejemplo 2. (Primera capacidad bsica: almacenar datos en memoria)

Verifiquemos la forma como se puede almacenar un dato numrico, tal como el nmero
hexadecimal 4116, en la memoria de la computadora. Tenemos que hacer algo similar a lo que en
Ensamblador hara la instruccin de asignacin mov X, 41h. Primero hay que decidir en que
segmento y desplazamiento tenemos que guardar el nmero 41h. Para esta eleccin,
ingresamos al debug.exe en la forma ya conocida, y averigemos qu sector nos ha asignado el
sistema operativo para trabajar. Para ello pulsamos el comando r sin parmetros y obtenemos
la siguiente pantalla:



Observamos que a los cuatro registros de segmento: DS, ES, SS, CS, se les ha asignado el
segmento 1533 en su mquina el DOS puede asignarle otro valor diferente. A nosotros slo
nos interesa en particular el segmento de datos DS=1533. Podramos seguir con esta misma
direccin 1533, pero elijamos una diferente, el segmento 14AC y el desplazamiento 0, en cuya
direccin almacenaremos el numero hexadecimal 41h, cuya longitud es de 1 byte. Entonces la
direccin elegida es la direccin segmentada 14AC:0000, que corresponde a la direccin
absoluta o real: 14AC * 10 + 0 = 14AC0. A continuacin tenemos que escribir el cdigo en
lenguaje de mquina que nos permita hacer esto. Recurrimos al comando A para digitar el
siguiente cdigo:

mov ax,14AC
mov ds,ax
mov byte ptr [0000],41
int 20

Antes de correr el programa averiguamos qu valor hexadecimal existe en esa direccin. Para
eso utilizamos el comando d 14AC:0000 y observamos que en esa localidad de la memoria
existe el valor 00h en su mquina puede encontrar otro valor diferente. Corremos el programa
con la instruccin g, y acto seguido volvemos a volcar (dumpear) la memoria con el comando d
y verificamos que en vez de 00h esta el hexadecimal 41h.

La siguiente pantalla muestra el resultado de ejecutar los pasos indicados:





43




Expliquemos el cdigo escrito. Con las instrucciones:

mov ax,14AC y mov ds,ax

se le ha indicado al procesador que el registro DS, apunte al segmento 14AC. Se utilizan dos
instrucciones por que el Ensamblador, no permite mover datos numricos directamente al
segmento de datos DS. Para mover datos a uno de los cuatro segmento DS, CS, SS y ES, se
requiere utilizar un registro auxiliar, que sirva de intermediario, en este caso hemos usado el AX.

La siguiente instruccin:

mov byte ptr [0000],41

le dice al procesador que mueva al desplazamiento 0000 del segmento de datos, el nmero 41h.
Ntese que el Debug.exe, para hacernos recordar que es un desplazamiento el valor 0000 se
coloca entre corchetes. Adems si no se colocan los corchetes se obtiene un mensaje de error.
La palabra byte ptr (byte pointer) le est indicando al procesador que solamente tiene que
almacenar un dato de tamao de 1 byte.

y finalmente la instruccin: int 20, sirve para terminar el programa.

El programa se graba con el nombre Ejem02.com, y se le hace la copia:
Ejem02Cap_Bas1MoverDatosAMemoria.com

Ejemplo 3. (Segunda capacidad bsica: aritmtica simple)

Primero verificamos la suma de 3 + 5 y la resta 8 - 3. Utilizando el comando a ingresamos
el siguiente cdigo:

mov al,3
add al,5
44
mov al,8
sub al,3
int 20

y procedemos a ejecutar el programa, paso a paso, usando el comando p (proceed) y
verificamos que en el medio registro AL de AX, queda la suma 8, y despus, en este mismo
registro queda el nmero 5 que es la diferencia de 8 3. La siguiente pantalla muestra los
resultados obtenidos, paso a paso, con el comando -P del Debug.exe:



Para verificar la multiplicacin de 3 * 8 = 24 y la divisin 10 / 2 = 5, ingresamos el siguiente
cdigo, recordando que el debug.exe solo trabaja con nmeros hexadecimales:

mov al,3
mov bl,8
mul bl
mov al,A
mov bl,2
div bl
int 20

Al ejecutar este cdigo, utilizando el comando p (proceed) , obtenemos el siguiente resultado de
1816 en el medio registro al que es el producto de 316 * 816 = 1816 . En cambio la divisin de A16
(diez en decimal) entre 216 da 516 que tambin se guarda en al

La siguiente pantalla muestra los resultados en la multiplicacin:






45


y esta otra pantalla muestra los resultados obtenidos en la divisin:



Se graban el programa y la copia con los nombres Ejem03.com y
Ejem03Cap_Bas2AritmeticaSimple.com

Ejemplo 4 (Tercera capacidad bsica: entrada/salida)

El siguiente cdigo en Ensamblador lee un carcter de teclado, lo almacena en la variable x,
luego salta de lnea y escribe el carcter leido y termina.

mov ah, 1 ; se prepara para leer un carcter de teclado
int 21h ; lo lee y guarda en AL
mov x,al ; almacena el carcter ledo en la variable x
mov ah,2 ; se prepara para escribir un carcter en pantalla
mov dl,0Ah ; en dl, el salto de lnea
int 21h ; salta de lnea
mov dl,x ; en dl la el carcter leido
int 21h ; escribe el carcter leido en pantalla
mov ah,4ch ; se prepara para terminar
int 21h ; termina y pasa el control al DOS

A continuacin escribimos el mismo cdigo, pero en lenguaje de mquina:

100 mov ah, 1
102 int 21
104 mov [115],al
107 mov ah,2
109 mov dl,A
10B int 21
10D mov dl,[115]
111 int 21
113 int 20
115
46
Ingresamos el cdigo con el comando A y cuando se ejecuta con el G el programa se queda
esperando hasta que ingresemos cualquier carcter usando el teclado; si pulsamos la tecla M,
obtenemos el siguiente resultado:



Si a continuacin procedemos a vaciar (dumpear) el contenido de memoria en el desplazamiento
[115], con el comando d 115, verificamos que en memoria en el desplazamiento 115 aparece el
hexadecimal 4Dh, que corresponde al carcter ASCII M:



Este programa se graba con los nombres Ejem04.com y
Ejem04Cap_Bas3EntradaYSalida.com

Ejemplo 5 (Quinta capacidad bsica: tomar decisiones simples)

Ya hemos mencionado que las computadoras tienen circuitos electrnicos que pueden tomar
decisiones simples, que son instrucciones de comparacin para bifurcar a determinada direccin
de memoria.





47


Cuando estudiamos la quinta capacidad bsica suministramos el siguiente programa en
lenguaje Ensamblador:

mov ah,2
mov ch,5
mov cl,3
cmp ch, cl
jl salgo ; jl significa jump if less (salta si es menor)
mov dl,ch
int 21h
mov dl,0Ah ;se prepara para saltar de lnea
int 21h ; salta de lnea
salgo: mov dl,cl
int 21h
mov ah,4ch
int 21h

Lo que hace este programa es verificar que cuando ch < cl sea verdad debe escribir en
pantalla el valor que contiene cl, y en caso contrario debe escribir ambos: primero el valor de ch
y en la siguiente lnea el valor de cl.

Para ch=3 y cl=5, el programa debe escribir solamente el valor de cl, es decir 5, y en cambio
si ch=5 y cl=3, debe escribir ptimero 5 y despues 3 en la siguiente lnea. Adaptemos el
programa para este segundo caso y tenemos el siguiente cdigo en lenguaje de mquina.

100 mov ah,2
102 mov ch,35
104 mov cl,33
106 cmp ch, cl
108 jl 112
10A mov dl,ch
10C int 21
10E mov dl,A
110 int 21
112 mov dl,cl
114 int 21
116 int 20

Debe notarse que no es lo mismo el nmero 5 cuya representacin hexadecimal en un byte es
0516 = 05h = 000001012, que el ASCII 5, cuya representacin hexadecimal es 3516 =35h=
001101012 .

El siguiente programa es el resultado de ejecutar este cdigo

48


El programa se graba con los nombres Ejem06.com y
Ejem05Cap_Bas5TomarDecisionesSimples.com.

Ejemplo 6 (Sexta capacidad bsica: persistencia de datos)

Anteriormente hemos visto que para lograr la persistencia se utiliza un dispositivo de
almacenamiento secundario llamado archivo y que no forma parte de la memoria. Cuando
describimos esta capacidad suministramos el cdigo de dos programas en lenguaje
Ensamblador: el primero para crear un archivo de nombre a:\DATOS;DAT que se encuentra
en un disquete-, y el segundo para grabar en este archivo el nmero 3 y como comprobacin
desplegarlo en pantalla. A continuacin damos el cdigo de esos dos programas, adaptados en
uno slo, pero en lenguaje de mquina. Si no entiende el cdigo, no se preocupe, ms adelante
cuando estudiemos archivos, despejar todas sus dudas sobre como opera el programa. Por
ahora se pide ingresar este cdigo con el comando A del debug.exe y correrlo con el comando
G. Al terminar puede verificar si se ha creado el archivo a:\DATOS.DAT, utilizando el
comando:

edit a:\DATOS.DAT

que utiliza el editor de consola de Windows de nombre edit.exe

No debe olvidarse que antes de correr el programa debe tener un disquete en la unidad A:

100 mov ah,3c ;se prepara para crear un archivo con direccin dx)
102 xor cx,cx ; cx=0
104 lea dx,[156] ;carga en dx direccion de archivo a crear
108 int 21 ;crea archivo cuya direccion es dx
10A mov ah,3d ;se prepara para abrir un archivo
10C mov al,1 ;al=1 significa que va a escribir en el archivo
10E lea dx,[156] ;carga en dx la direccin del archivo
112 int 21 ;abre archivo y guarda en ax=# (# handle)
114 mov [164],ax ;guarda #handle en memoria, desplaz. 164
117 mov ah,40 ;se prepara para escribir el archivo con handle en bx
119 mov bx,[164] ;recupera en bx=#handle




49


11D mov cx,1 ;le indica que escribira 1 byte
120 lea dx,[155] ;en dx = direccin donde esta el 3 a escribir en arch
124 int 21 ;escribe el 3 en el archivo de direccion dx
126 mov ah,3e ;se prepara para cerrar archivo con handle en bx
128 mov bx,[164] ;recupera en bx = #handle
12C int 21 ;cierra archivo de handle bx
12E mov ah,3d ;se prepara para abrir archivo de handle bx=desplaz 164
130 mov al,00 ;al=0 significa que leer el archivo
132 lea dx,[156] ;en dx la direccin del archivo
136 int 21 ;abre archivo de handle bx = apunta desplaz. 164
138 mov ah,3f ;se prepara para leer archivo de handle en bx
13A mov bx,[164] ;bx = #handle del archivo a leer
13E mov cx,1 ;leer 1 byte
141 lea dx,[166] ;dx = direcc. memoria para guardar el byte leido
145 int 21 ;lee de archivo 1 byte y lo guarda en memoria desplz. 166
147 mov dl,[166] ;dl = byte del desplaz 166 (byte leido desde el archivo)
14B mov ah,2 ;se prepara para escribir el ASCII que est en dl
14D int 21 ;escribe ASCII en pantalla
14F mov ah,1 ;se prepara para leer ASCII de teclado
151 int 21 ;lee <enter> y aguanta pantalla
153 int 20 ;termina y pasa el control al DOS
155 db 33 ;dato a grabar en el archivo
156 db a:\DATOS.DAT,00 ; nombre del archivo que se crea en el disquete

A continuacin se da el resultado de correr este programa:



El programa se graba con los nombres: Ejem07.com y
Ejem06Cap_Bas6PesistenciaDeDatos.com


50
Ejemplo 7 (Stima capacidad bsica: reutilizacin)

Al describir esta capacidad bsica, presentaremos un programa modular, que utiliza una librera
de programas objetos de nombre LIBASS.LIB. Por ese motivo este programa no puede
codificarse en lenguaje de mquina; y lo nico que haremos ahora es utilizar el debug.exe para
correr el programa Ejem7.exe, cuyo programa fuente est en lenguaje Ensamblador, desde el
ambiente del DOS. Para ello digitamos lo siguiente: debug Ejem7.EXE y aparece la siguiente
pantalla:



Digitamos u, para ver el cdigo fuente y luego corremos el programa con el comando G.
Siguiendo las instrucciones del programa ingresamos el nmero flotante 2.00E00, que equivale a
2 x 10
0
= 2.00 y obtenemos la raz cuadrada 1.41421356237309x10
0
. Si probamos con otro dato
tienen que ingresarse en el formato flotante D.DD..DE[+/-]DD, en el que D significa un dgito
decimal.

Este programa, se explicar con mayor detalle, cuando se estudie aritmtica flotante. El cdigo
del programa Ejem07.asm es el que se ha dado al describir la stima capacidad bsica en la
seccin 1.4.7., y se graba con los nombres: Ejem07.asm y
Ejem07Cap_Bas7Reutilizacin.asm. Tambien est disponible, el programa ejecutable
Ejem07.exe.

1.5 Algo ms sobre el lenguaje de mquina.

El lenguaje de mquina es til para apreciar como trabaja internamente el procesador. En este
sentido es un auxiliar irremplazable, y puede usarse para depurar programas, de ah el nombre
del programa de utilera: debug.exe. Antes de continuar con el tercer captulo en el que
empezaremos a estudiar el lenguaje Ensamblador, vamos a disear algunos programas ms en
lenguaje de mquina.

Ejemplo 8

Se pide escribir un programa, en lenguaje de mquina, que lea una cadena de teclado de hasta
72 caracteres como mximo = (48h), la almacene en memoria y despus despliegue esta
cadena en pantalla. Como 72 = 48h, en el programa figura 47h.




51


Este es un programa que tiene que manejar la capacidad bsica de la computadora de
entrada/salida, por tanto tenemos que utilizar la interrupcin 21h. Como se trata de leer de
teclado una cadena, de acuerdo a la tabla de funciones de la int 21h, tenemos que utilizar la
funcin AH=0Ah, para leer la cadena y la funcin AH=9h, para escribir la cadena.

Antes de utilizar la funcin AH=0Ah, tenemos que decidir dos cosas: primero de que tamao ser
la cadena a leer, y segundo en que parte de la memoria vamos a almacenar la cadena leda.
Acordemos que la longitud mxima de la cadena sea de 47h caracteres, y que almacenaremos
la cadena al terminar el cdigo del programa en lenguaje de mquina.

Adems acordamos desplegar dos mensajes, para solicitar que se ingrese la cadena y para
mostrar la cadena leda. En esa forma el diseo de la pantalla es el siguiente:

Ingrese una cadena : Estoy aprendiendo Ensamblador
Cadena leda : Estoy aprendiendo Ensamblador

Como primer paso vamos a ingresar tentativamente el cdigo de ms abajo. Las direcciones que
aparecen en este cdigo que son el desplazamiento 0000, que corresponde a la direccin de
donde se va almacenar el mensaje Ingrese la cadena: , el valor de desplazamiento 1111, que
corresponde a la direccin de memoria donde guardaremos la cadena leda y el valor de
desplazamiento 2222, que corresponde a la direccin de donde almacenaremos el mensaje
cadena leida :, son tentativos, y sus valores reales los vamos a obtener despus de ingresar el
siguiente cdigo en el que se han numerado las instrucciones, slo con el propsito de explicar
qu hace cada instruccin en lenguaje de mquina; para ello utilizamos el comando A del
debug.exe:


1. lea dx,[0000] (desplazamiento 0000 del mensaje 1)
2. mov ah,9
3. int 21
4. lea dx,[1111] (desplazamiento 1111 para almacenar cadena)
5. mov ah,A
6. int 21
7. mov ah,2 (se prepara escribir carcter)
8. mov dl,A ( A salto de lnea)
9. int 21 (salta de lnea para escribir el segundo mensaje)
10. lea dx,[2222] (desplazamiento 2222 del mensaje 2)
11. mov ah,9
12. int 21
13. lea dx,[1111] (desplazamiento 1111 de la cadena leda)
14. add dx,2 (ms 2, para saltar el 50 y # de caracteres ledos)
15. mov ah,9
16. int 21
17. int 20
18. db Ingrese una cadena que termina en $: $ (primer mensaje)
. 19. db Cadena leida : $ (segundo mensje)
20. db 48, 48 dup ($); 48h= 72 es decir se pueden leer hasta 72 incluido el <enter>


52
Descripcin:

1. Tentativamente suponemos que el primer mensaje que se declara en la instruccin 18 es
0000, pues no conocemos cul es su valor. La instruccin de mquina LEA dx, [0000],
significa Load Efective Address, que se traduce al castellano por: carga en el registro
dx, la direccin efectiva del desplazamiento 0000.

2 y 3. Escribe en pantalla la cadena que se encuentra en la direccin ds:dx. Como
acabamos de leer en dx el desplazamiento del primer mensaje y DS=CS=SS=ES cuando
se trata de cdigo de mquina, al ejecutarse estas dos instrucciones escriben en pantalla
el primer mensaje. La cadena a desplegar debe terminar en $, caso contrario el
programa no funcionar bien.

4, 5 y 6. Leen el desplazamiento dx de la cadena a ser leda y almacenada donde se
encuentra la instruccin 20. Suponemos que este desplazamiento es 1111. Cuando se
ejecutan estas instrucciones, la computadora lee de 0 hasta 50 caracteres y los
almacena en la direccin que corresponde al desplazamiento 1111.

7, 8 y 9. Utilizan la funcin ah=2 que escribe en pantalla el carcter que se encuentra en dl.
Como dl=A16 =salta de linea, cuando se ejecutan estas instrucciones el cursor salta de
linea.

10, 11 y 12. Esta tres instrucciones primero leen el desplazamiento 2222 del segundo mensaje
y despus lo escriben en pantalla: su funcin es similar a la que cumplen las
instrucciones 1, 2 y 3.

13 Lee el desplazamiento de la direccin donde se almacen la cadena, cuando se
ejecutaron las instrucciones 4, 5 y 6.

14 Al desplazamiento dx le suma 2 bytes, 1 para saltar el nmero 28h y el otro para saltar
el nmero de caracteres ledos que se coloca a continuacin del nmero 28h.

15 y 16 Escriben en pantalla la cadena de caracteres leidos y almacenados en el
desplazamiento 1111, sin incluir el nmero 28h y el nmero de caracteres ledos.

17 Termina el programa y pasa el control al DOS.

18 Declara una cadena de bytes, con el mensaje Ingrese una cadena, que tiene que
terminar con el carcter $. Por eso se utiliza la directiva db que significa define bytes,
que despus aprenderemos que no es una instruccin si no ms bien una directiva o
seudo instruccin.

19 Declara una cadena de bytes con el segundo mensaje Cadena ingresada

20 Separa 28h = 40 bytes de memoria, para almacenar la cadena que va a ser leida al
ejecutar las instrucciones 4, 5 y 6. Como esta cadena va a ser desplegada con las
instrucciones 15 y 16, se inicializa con 40 veces $.





53


A continuacin tenemos la pantalla que muestra qu se ha hecho. Recurriendo al comando A se
ingres todo el cdigo del programa de ms arriba. Al terminar podemos visualizar los valores de
los desplazamientos de cada instruccin que nos servirn para reemplazar a los tres
desplazamientos 0000, 1111 y 2222.



En esta pantalla vemos lo siguiente:

que el desplazamiento del primer mensaje, es 012B, que reemplaza al valor 0000;
que el desplazamiento del segundo mensaje, es 0140 que reemplaza al valor 2222;
y que el desplazamiento de la direccin para cargar la cadena leda es 0155, que
reemplaza al valor 1111.

Por tanto el nuevo cdigo que resuelve el problema es:

lea dx,[012B]
mov ah,9
int 21
lea dx,[0155]
mov ah,A
int 21
mov ah,2
mov dl,A
int 21
lea dx,[0140]
mov ah,9
int 21
lea dx,[0155]
add dx,2
mov ah,9
int 21
int 20
12B db Ingrese una cadena: $
140 db Cadena leida : $
155 db 28, 28 dup (24)
54
El resultado de correr este cdigo es el siguiente:



El programa se graba con los nombres Ejem08.com y Ejem08LeeYEscribeCadena.com.

Ejemplo 9

Aprenderemos a multiplicar nmeros hexadecimales, utilizando el lenguaje de mquina. Si se
tenemos dos nmeros decimales: a con n dgitos y b que tiene m dgitos; si calculamos el
producto de a por b, es decir a x b, por matemticas sabemos que a x b tiene m+n-1 o m+n
dgitos.

As por ejemplo si multiplicamos los nmeros decimales 5409 x 1011 el producto debe tener 7 u 8
dgitos; en efecto 5409 x 1011 = 5468499 tiene 7 dgitos decimales. En el caso extremo tenemos
que el producto 9999 x 9999 = 99980001 tiene 8 dgitos decimales.

Sucede algo parecido en el sistema hexadecimal. Hemos visto que para multiplicar dos nmeros,
tenemos que utilizar dos registros que tienen 16 bits = 2 bytes, por tanto cada uno puede
almacenar 4 hexadecimales como mximo, y el producto llegar a tener 7 u 8 hexadecimales, o
sea necesitamos dos registros para almacenar el producto. Por este motivo el procesador utiliza el
par de registros DX:AX para guardar el producto.

Si tenemos dos nmeros a y b y queremos calcular su producto a x b, forzosamente debemos
colocar uno de ellos en el registro AX, es decir hacemos mov AX,a. El otro nmero lo
almacenamos en cualquier registro que no sea el AX o DX, por ejemplo el BX, y hacemos mov
BX,b; la instruccin mul BX, calcula a x b y el resultado lo guarda en DX:AX, la parte ms
significativa en DX y la parte menos significativa en AX.

Si queremos calcular el producto FFFFh x FFFFh =FFFE0001h, el siguiente cdigo en lenguaje de
mquina resuelve el problema:

mov ax,FFFF
mov si,FFFF
mul si
int 20




55


el producto se almacena en el par de registros DX:AX: que es igual a DX=FFFEh y AX=0001h,
segn se puede apreciar si corremos este programa



Este programa se graba con el nombre Ejem09.com y Ejem09Multipliacion.com

Ejemplo 10

La divisin es la operacin inversa de la multiplicacin. Por tanto el dividendo puede tener entre 1
y 8 dgitos y requiere dos registros, el par DX:AX, y el divisor puede ser cualquier otro registro que
no sea el DX o AX, digamos el BX, entonces la divisin se efecta con la instruccin div BX. El
cociente se almacena en AX y el resto en DX. As por ejemplo, si dividimos 8 entre 3, escribimos
el siguiente cdigo

mov dx,0
mov ax,8
mov si,3
div si
int 20

si corremos el programa obtenemos en AX=2 y en DX =2, por que:


3
8
= 2 +
3
2
, o sea el cociente es 2 y el resto 2

En base al ejemplo 9, el mximo valor que podemos colocar en el par de registros DX:AX es el
nmero hexadecimal FFFE0001, en caso contrario recibiremos un mensaje de error. El siguiente
cdigo en lenguaje de mquina:

mov dx,FFFE
mov ax,1
mov si,FFFF
div si
int 20

56
nos da un cociente en AX igual a FFFFh y un resto en DX igual a 0:



Este programa se graba con el nombre Ejem10.com y Ejem10Division.com

Ejemplo 11

Vamos a empezar a disear ciclos de repeticin en nuestros programas y tenemos que utilizar
nuevas instrucciones de mquina:

Las instrucciones cmp, jl y nop

Las instrucciones cmp (compare), jl (jump if less), permiten formar ciclos de repeticin. La
instruccin nop (no operation), nos ayudar en la depuracin.

Por ejemplo para calcular, y almacenar la suma 1+2+...+100, en el registro DX:

DX = 1 + 2 + 3 + ... + 10010 = 505010 (=13BA16)

escribiremos el siguiente cdigo en lenguaje de mquina (6416=10010), que repite 100 veces las
instrucciones 3 a 6:

1. mov si,0 (si=0)
2. mov dx,0 (dx=0)
3. 106 add si,1 (si=si+1)
4. add dx,si (dx=dx+si)
5. cmp si, 64 (compara contenido de si con 6416 = 10010)
6. jl 106 (jump to 106h if less than 64h) salta a la direccin 106h si es verdad que si < 64
7. nop (no operar)
8 int 20 (termina y pasa el control al DOS)





57


Cuando este programa termine tendr almacenado en DX =13BA16 (=505010) y en SI=6416=10010
como se puede apreciar en la siguiente pantalla. El programa tiene que ejecutarse con el
comando G 110, que le indica al debug.exe que ejecute el programa hasta la instruccin 110
nop, y as se puede verificar los valores en los registros DX y SI, que no sucede si usamos G.



Este programa se graba con los nombres Ejem11.com y
Ejem11CalculaSumatoria1a100.com.

Ejemplo 12

La instruccin LOOP

El par compuesto por el registro CX y la instruccin LOOP nombre_etiqueta, nos permiten repetir
CX veces el conjunto de instrucciones que abarca desde nombre_etiqueta hasta la instruccin
LOOP. Cada vez que se llega a la instruccin LOOP, el valor de CX disminuye en 1, en esta forma
llega un momento en que CX vale 0, y termina el ciclo.

As por ejemplo, en el siguiente cdigo de mquina, como CX contiene el valor 1Ah (=26), todas
las instrucciones desde el desplazamiento 107 hasta el desplazamiento 10C se repiten 26 veces,
por tanto el siguiente programa escribe las 26 letras del alfabeto ingls, empezando con la letra A:

100 mov ah,2
102 mov dl,41
104 mov cx,1A
107 int 21
109 add dl,1
10C loop 107
10E int 20

la prueba de correr este programa es la siguiente:

58


Este programa se graba como Ejem12.com y Ejem12EscribeLetrasAlfabetoIngles.com

Ejemplo 13

Las instrucciones PUSH y POP

PUSH y POP, nos sirven para agregar y sacar datos de la PILA, que no debemos olvidar, tambin
es una parte de la memoria. El almacenamiento de datos en la pila se hace en forma diferente a
como se hace con la instruccin MOV. Ambas instrucciones PUSH y POP utilizan un solo
operando que es el nombre de un registro.

Ya sabemos que JL , significa jump if less (salta si es menor que). Por eso el siguiente
programa escribe, en pantalla, los 10 nmeros decimales, desde el 9 al 0, uno al lado del otro
con un blanco intermedio:

100 mov ax,0
103 push ax
104 add ax,1
107 cmp ax,A
10A jl 103 ( jump to 103 if less , salta a 103 si es menor)
10C mov ah,2
10E mov cx,A
111 pop dx
112 add dx,30
115 int 21
117 mov dl,20
119 int 21
11D loop 111
11F int 20

el primer ciclo de repeticin desde el desplazamiento 103 hasta el 10A, sirve para almacenar en
la pila diez nmeros desde el 0 hasta el 9. Hagamos una abstraccin e imaginemos la pila como
un arreglo, tal como aparece en la siguiente figura. Al terminar el ciclo vemos que quedan uno
encima del otro, igual a una pila de nmeros de ah el nombre-, en la que el ultimo nmero en
entrar va a ser el primero en salir:






59


9h
8h
7h
6h
5h
4h
3h
2h
1h
0h

El cero hexadecimal est en el fondo de la pila, pues fue el primer PUSH AX, el que se ejecut,
cuando AX contena el valor 0h.

El segundo ciclo dado por el par CX=A16=10 y LOOP 111, hace que las instrucciones 111 hasta
117, se repitan 10 veces; y sirve para sacar los elementos de la pila.

Por cada POP DX, se saca un elemento de la pila en el registro DX. Se empieza por 9h que est
al tope de la pila y se termina en 0h que es el que est al fondo. Si al hexadecimal sacado en DX,
por ejemplo 0009h, se le suma 30h, se obtiene 0039h, es decir en DH queda el valor 00h y en DL
queda 39h, o sea el ASCII 9, que es el carcter que se escribe en pantalla con la interrupcin
21h y la funcin ah=2. Esta funcin se prende antes de iniciar el segundo ciclo de repeticin en la
instruccin 10C.

El resultado final es que se escriben en pantalla los caracteres ASCII desde el 9 hasta el 0.

La siguiente pantalla, muestra el resultado cuando se corre el cdigo de mquina de ms arriba:


60


Este programa se graba como Ejem13.com y
Ejem13ManejoDeLaPilaLeeYEscribeNumeros.com

Ejemplo 14

Vamos a continuar aprendiendo a disear ciclos de repeticin, esto es, conseguir que un nmero
de instrucciones que se encuentran en la memoria se repitan un nmero determinado de veces, lo
que es necesario para convertir un nmero hexadecimal a binario. Primero debemos resolver
manualmente el problema, para ver que pasos tenemos que repetir varias veces.

Cuando dividimos un nmero entre 2, el resto solo puede ser 1 o 0. Si tenemos que convertir el
nmero 29 (=1Dh) a binario, empezamos dividiendo el nmero 29 y despus los cocientes
resultantes entre 2, hasta obtener un cociente 0. Conforme se avanza en este proceso se van
almacenando los restos, tal como se muestra a continuacin:

29 2
1 14 2
0 7 2
1 3 2
1 1 2
1 0

El resultado es el nmero binario 11101, formado por los restos, pero escritos en orden reverso
del que fueron obtenidos.

El siguiente programa en lenguaje de mquina resuelve el problema

mov dx,0 (DX = 0)
mov ax,1D (AX = 1Dh = numero a convertir a 00011101; el dividendo)
mov bx,2 (el divisor en BX)
mov cx,0 (CX servir como contador de las repeticiones)
10C div bx (divide DX:AX entre BX, cociente en AX, resto en DX)
push dx (guarda el resto DX en la pila)
add cx,1 (suma uno al contador CX)
mov dx,0 (DX=0 para borrar el resto y volver a dividir)
cmp ax,0 (es el cociente AX=0?)
jg 10C (si es mayor que 0 salta a 10C, si no sigue)
mov ah,2 (se prepara para escribir en pantalla DL)
11C pop dx (recupera resto en DX)
add dx,30 (Le suma 30h para convertirlo a ASCII)
int 21 (escribe en pantalla ASCII de DL)
loop 11C (resta 1 a CX y bifurca a 11C si CX 0)
int 20 (termina, pasa el control al DOS)

Los valores de 10C y 11C se obtuvieron en forma parecida a como fue hecho en el ejemplo 8.

El resultado de correr este programa es el siguiente:




61





Este programa se graba con el nombre Ejem14.com y Ejem14EscribeNumeroBinario.com.


































62

CAPITULO III EL LENGUAJE ENSAMBLADOR

3.1 Introduccin

En el captulo I, aprendimos cules son las capacidades bsicas de una computadora digital. En
el captulo II aprendimos a disear programar pequeos en lenguaje de mquina; pero nos dimos
cuenta que el debug.exe tiene muchas limitaciones; sin embargo utilizar el lenguaje de mquina,
nos ha ayudado a tomar conceptos de muchas cosas que utilizaremos ahora que empezamos a
programar en lenguaje Ensamblador, que representa un nivel ms alto de codificacin, en el que
podremos utilizar directivas o seudo instrucciones, declarar variables, utilizar datos numricos
constantes en el sistema binario, octal, decimal y hexadecimal, etc.

La modularidad es un aspecto importante

Y sobre todo por que el lenguaje Ensamblador nos permite aprovechar la tercera razn por la
que se utiliza las computadoras para resolver problemas, ya mencionada en el capitulo I, por la
cual con su creatividad el hombre es capaz de descomponer un problema grande y de difcil
solucin, en un conjunto de pequeos problemas de fcil solucin.

Lo repetimos ahora por que esto es importante: Cuando el hombre enfrenta un problema de gran
complejidad no lo resuelve directamente, sino por el contrario soluciona equivalentemente un
conjunto de pequeos problemas -uno despus de otro-, con la aclaracin pertinente de que
las soluciones a estos pequeos problemas pueden ser obtenidos usando las limitadas
capacidades bsicas que poseen todas las computadoras.

El lenguaje Ensamblador, nos permitir trabajar en forma modular, descomponiendo un
programa muy grande, en un conjunto de procedimientos o mdulos, que tienen un nmero de
instrucciones que no sea muy grande para que pueda ser manejable.

La entrada y salida de datos, es un escollo.

Sin embargo al programar en lenguaje Ensamblador tambin encontraremos que existen muchas
limitaciones sobre todo con las instrucciones de entrada y salida. Ya hemos mencionado
anteriormente que en la representacin de informacin siempre est implcita la lectura y
escritura de datos, en un lenguaje que tiene esencia matemtica cuando se usa la
computadora.

La computadora digital no lee, no hace sino registrar datos. Transfiere datos de un medio
magntico llamado disco o teclado a otro medio magntico llamado memoria (almacenamiento
principal).

La computadora no escribe, transfiere o duplica los datos de un soporte sobre otro,
desde la memoria (almacenamiento principal) a el disco o a la pantalla.

La filosofa del procesador consiste en que todo lo que se lee de teclado es cdigo ASCII y todo
lo que se escribe en pantalla tambin son caracteres ASCII, pero se almacenan en memoria en
el sistema binario, en correspondencia con la tabla de cdigos ASCII.





63


Tambin los datos numricos internamente estn almacenados en memoria en el sistema
binario, pero resulta que su representacin est muy lejos de los patrones binarios que se utilizan
para los 256 caracteres de la tabla ASCII.

Si se lee de teclado el ASCII 3 se almacena en un byte de la memoria, como 33h (en binario
001100112), que es muy diferente del nmero hexadecimal 3h (en binario 000000112).

El mismo problema se presenta cuando se tiene en memoria el nmero 03h (000000112), si
escribimos este valor en pantalla, tal como est almacenado, se escribir el carcter ASCII que
corresponde a un nmero con dos dgitos hexadecimales, el nmero 03h, que segn la tabla de
caracteres ASCII para comprobarlo ejecute el programa Ejem19.com, que despliega esta tabla
en pantalla, es el smbolo , y no el 3 como hubiramos esperado.

Para probar esto ejecute el siguiente programa en lenguaje de mquina, y comprobar que
despliega en pantalla la figura .

mov ah,2
mov dl,3
int 21
int 20

El resultado se aprecia en la siguiente pantalla:



Posteriormente daremos solucin al problema de salida, recurriendo a la reutilizacin, que es una
de las capacidades bsicas de las computadoras; para este propsito construiremos, una la
librera esttica de mdulos objeto, de nombre UPA.LIB, que contendr varios procedimientos
objeto, para salida de datos numricos. Este tema ser tratado ms adelante.

3.2. Programa fuente

Recordemos que cuando trabajamos con el debug.exe, para ingresar las instrucciones de
mquina, utilizbamos el comando A, y luego para ejecutar el programa el comando G.
Trabajando con el compilador del lenguaje Ensamblador, el ingreso y la ejecucin, forman parte
de un conjunto de pasos que tienen que ejecutarse uno despus de otro, y que hay que seguir
en forma rgida. Esto es asi, porqu el ambiente del lenguaje Ensamblador es ms logrado que el
que se usa con el programa debug.exe.

Los pasos que se siguen para llegar a construir un programa en lenguaje Ensamblador son: 1
0
)
edicin, 2
0
) ensamble, 3
0
) enlace y 4
0
) ejecucin.

Pasamos a describir cada uno de estos pasos.
64
PRIMER PASO: Edicin.

Las instrucciones y la definicin de los datos que se codifican respetando la sintaxis del lenguaje
Ensamblador, se llaman programa fuente. El programa que sirve para digitar estas instrucciones
se llama editor. Existen varios editores que pueden utilizarse, por ejemplo el programa edit.exe,
proporcionado por el Windows como un componente del DOS.

La estructura de un programa fuente Ensamblador, contiene ms de un segmento: uno para
cdigo (que es obligatorio), y como opcionales, un segmento para los datos, la pila y el segmento
extra. En este sentido la estructura de un programa fuente en lenguaje Ensamblador es la
siguiente:
nombre1 segment
Assume cs:nombre1, ds:nombre2, ss:nombre3, es:nombre4
s nombre5 proc
e instruccin 1
g instruccin 2
m ...
e Termina
n nombre5 endp
t nombre6 proc
o instruccin 1
instruccin 2
d ...
e ret
nombre6 endp
c . . .
o nombren proc
d instruccin 1
i instruccin 2
g ...
o ret
nombren endp
nombre1 ends
nombre2 segment
directiva 1 de definicin de datos
seg directiva 2 de definicin de datos
de ...
datos directiva n de definicin de datos
nombre2 ends
nombre3 segment stack
directiva 1 de definicin de datos de la pila
seg directiva 2 de definicin de datos de la pila
de ...
pila directiva n de definicin de datos de la pila
nombre3 ends
nombre4 segment
directiva 1 de definicin de datos del segmento extra
seg directiva 2 de definicin de datos del segmento extra
extra ...
directiva n de definicin de datos del segmento extra
nombre4 ends
end nombre5




65


El siguiente es un ejemplo de un programa fuente en lenguaje Ensamblador:

Programa: Prueba.asm y PruebaProgramaConCuatroSegmentos.asm
codigo segment directiva
assume cs:codigo,ds:data,ss:pila,es:extra directiva
principal proc directiva
mov ax,data ; carga direccion del segmento de datos
mov ds,ax ; ds apunta segmento de datos
lea dx, mensaje1 ; carga direccion efectiva de mensaje1
mov ah,9 ; se prepara pra escribir cadena ds:dx
int 21h ; lo hace
mov ax,"A" ; mete en
push ax ; la pila "A"
mov ax,"B" ; mete en
push ax ; la pila "B"
mov ax,"C" ; mete en
push ax ; la pila "C"
mov ax,"D" ; mete en
push ax ; la pila "D"
mov ah,2 ; funcion para escribir caracter
mov bp,sp ; bp=sp= comienzo de la pila en bp
mov dl, byte ptr [bp+6] ; dl=primer caracter metido en la pila
int 21h ; lo escribe en pantalla
mov dl, byte ptr [bp+4] ; dl=segundo caracter metido en la pila
int 21h ; lo escribe
mov ah,2 ; se prepara para escribir caracter
mov dl,0dh ; retorno de carro CR
int 21h ; retorna
mov dl,0ah ; salto de linea LF
int 21h ; salta
mov ax,extra ; lee direccion de segmento extra
mov es,ax ; es apunta a segmento extra
mov si,0 ; si=desplazamiento 0
mov cx,33 ; cx = 33 veces
sigo:
mov dh,0
mov dl,es:otro_mensaje[si] ; dl=letra de otro mensaje en desplaz. si
add si,1 ; aumenta el desplazamiento
mov ah,2 ; se prepara para escribir caracter de dl
int 21h ; lo escribe
loop sigo ; repite loop cx = 33 veces
mov bp,sp ; comienzo de la pila en bp
mov dl, byte ptr [bp+2] ; dl=tercer caracter metido en la pila
int 21h ; lo escribe
mov dl, byte ptr [bp] ; dl=cuarto caracter metido en la pila
int 21h ; lo escribe
mov ah,4ch ; se perpara para salir
int 21h ; sale
principal endp directiva
codigo ends directiva
66

data segment
mensaje1 db "Letras leidas segmento de datos: $" directivas
data ends

pila segment stack
db 4 dup ("PILA") directivas
pila ends
extra segment
otro_mensaje db "Letras leidas segmento extra : " directivas
extra ends
end principal

Todo lo que no est sealado como directiva no es una instruccin.

La edicin del programa anterior se puede hacer utilizando el Edit.exe. Previamente hay que
adoptar un nombre para el programa fuente, que tiene que tener un nombre de 1 a 8 caracteres
y una extensin .ASM. Para nuestro caso adoptemos el nombre Prueba.ASM, y procedemos a
editarlo con el siguiente comando en el ambiente del DOS:

Edit Prueba.asm

y acto seguido se digita el programa fuente tal como aparece ms arriba, como puede verse en
la siguiente pantalla:






67


SEGUNDO PASO: Ensamble.

Hemos identificado dos lenguajes de programacin de alto nivel y de bajo nivel. Los
programadores que escriben en un lenguaje de alto nivel, como C o Object Pascal, codifican
comandos poderosos, cada uno de los cuales puede generar muchas instrucciones en lenguaje
de mquina. Por otro lado, los programadores que escriben en un lenguaje ensamblador de bajo
nivel codifican instrucciones simblicas como las que aparecen en el programa fuente de ms
arriba, cada una de las cuales genera una instruccin en lenguaje de mquina.

Sin importar el lenguaje de programacin que utilice, de todos modos es un lenguaje simblico
que tiene que traducirse a lenguaje de mquina. Un lenguaje de alto nivel utiliza un compilador
para traducir el cdigo fuente a lenguaje de mquina no ejecutable (a veces llamado cdigo
objeto). Un lenguaje de bajo nivel utiliza un ensamblador, para realizar la traduccin. Despus
un programa de nombre Link.exe, para ambos niveles, alto y bajo, completa el proceso para
convertir el cdigo objeto a lenguaje de mquina ejecutable

El programa ensamblador de microsoft se llama MASM.EXE y el ensamblador de Borland es
TASM.EXE. Para ensamblar los programas de este libro se puede usar cualquiera de los dos
ensambladores.

Los comandos para ensamblar el programa fuente son los siguientes:

MASM prueba.asm

o este otro:

TASM prueba tambin TASM prueba.asm

Si no existen errores en el programa fuente, el ensamblador genera el programa objeto de
nombre prueba.OBJ.

Si se requiere un listado del programa fuente en un archivo de nombre prueba.lst, se recurre a
los siguientes comandos:

MASM prueba,,prueba.lst,,

esta otra

TASM prueba,,prueba.lst

Despus de generado prueba.lst, puede imprimirse o editarse con el editor del DOS edit.exe
utilizando el comando:

Edit prueba.lst

TERCER PASO: Enlace

Una vez que el programa Prueba.asm queda sin mensajes de error, el ensamblador genera el
programa objeto prueba.obj. El siguiente paso es enlazar el mdulo objeto.
68
Por qu se realiza el ensamble?. La respuesta es por que el programa enlazador Link.exe
realiza las funciones siguientes:

Si se pide combinar ms de un mdulo ensamblados de forma separada en un
solo programa ejecutable. Incluso el programa Link.exe puede combinar mdulos
objeto generados por compiladores como el C y/o el ensamblador.
Genera un mdulo .EXE y lo inicializa con instrucciones especiales para facilitar
su subsecuente carga y ejecucin.

El comando para el ensamble, en nuestro caso es:

LINK prueba;

Y le recomendamos que no se olvide de digitar el punto y coma final, por que de lo contrario el
LINK trabaja en modo interactivo y le va a solicitar ms datos, que aparentemente resultan ser
obvios, y es el punto y coma final,el que evita este dialogo con el programa enlazador Link.exe.

CUARTO PASO: Ejecucin del programa .EXE

Una vez que se han enlazado uno o ms mdulos .OBJ en un solo mdulo .EXE, puede ejecutar
el programa.exe cualquier nmero de veces, digitando el siguiente comando:

Prueba <entrada>

Aunque al principio estos pasos no sean por completo claros, encontrar que con un poco de
experiencia se vuelven automticos.

El resultado de ejecutar el programa prueba.exe es el siguiente:








69


Diagrama conjunto de los pasos para editar, ensamblar , enlazar y crear el ejecutable de
un programa
pantalla

teclado




edit.exe en memoria el editor



prueba.asm programa.fuente



MASM.exe
en memoria el ensamblador
TASM.exe



Otros.obj Prueba.obj programa.objeto




LINK.EXE en memoria el enlazador



Prueba.exe programa,exe (ejecutable)

Ejecucin del programa
Disco disquete pantalla/teclado

ENTRADAS




Nombre.exe programa ejecutable




SALIDAS

pantalla Disco disquete impresora
70
3.3 Tipos de sentencias fuente

Hemos dicho que un programa de computadora est compuesto de instrucciones y datos; ambos
son los principales componentes de lo que se llama programa fuente y por eso se les llama
sentencias fuente; por tanto un programa fuente contiene dos tipos de sentencias:

1. Las instrucciones, que son enunciados que comienzan con un verbo en forma imperativa,
tal como ADD y MOV, que ocasionarn que el procesador haga algo. Despus veremos que
las instrucciones generan cdigo, esto es por cada instruccin de lenguaje Ensamblador
se origina una instruccin en lenguaje de mquina.

2. Las directivas o seudo instrucciones, que sirven para definir los datos, indicar donde
comienza y donde termina un programa, o indicar dnde empieza y termina el segmento de
datos, la pila y muchas otras cosas ms. A diferencia de las instrucciones, las directivas no
generan cdigo, esto es, solamente son utilizadas por el compilador, pero sirven para
armar la estructura del programa.

Las instrucciones se aplican en tiempo de ejecucin, en cambio las directivas se aplican en
tiempo de ensamblaje.

3.3.1. FORMATO DE UNA INSTRUCCIN ENSAMBLADOR

El formato de una instruccin contiene cuatro campos:

[ etiqueta[:] ] nombre_de_instruccin [operandos] [;comentarios]

los corchetes [ ] significan que el campo correspondiente es opcional.

Ejemplo: mover: mov AX,45h ; Asigna 45 a AX


etiqueta operandos comentarios
instruccin



3.3.1.1. Campo etiqueta

- Puede tener hasta 31 caracteres
- Tiene que terminar con el smbolo de dos puntos :

3.3.1.2. Campo nombre

Es el nombre simblico de la instruccin. Puede tener de 2 a 6 letras.

3.3.1.3. Campo operandos

Puede tener 0, 1 2 operandos

3.3.1.4. Campo comentario

Debe empezar con un punto y coma ;. Todo lo que se escriba a la derecha del smbolo ; es
ignorado por el compilador








71


3.3.2. Identificadores

Un identificador es un nombre que se aplica a elementos del programa fuente. Los dos tipos de
identificadores son: nombre o variable, que se refiere a la direccin de un elemento de dato, y
etiqueta que se refiere a la direccin de una instruccin y que es el primer campo opcional de
una instruccin.

Un identificador puede utilizar los siguientes caracteres:

Letras del alfabeto: desde la A hasta la Z
Dgitos: desde el 0 al 9
Caracteres especiales: signo de interrogacin (), subrayado (_), signo de dlar ($),
arroba (@) y punto (.).

El primer carcter de un identificador debe ser una letra o uno de los caracteres
especiales, excepto el punto.

El Ensamblador trata las letras maysculas y minsculas como iguales; por esto hay veces que
se suele decir que el Ensamblador es sensible slo a maysculas, por que el compilador
convierte las minsculas a maysculas en la etapa de compilacin. Para el Ensamblador es lo
mismo escribir MOV, mov, Mov, mOv, etc. Todas significan lo mismo MOV.

La longitud mxima de un identificador es de 31 caracteres (247 desde el MASM 6.0)

Ejemplos de declaracin de variables, es decir de identificadores de datos son las siguientes:


3.3.3. FORMATO DE DEFINICIN DE DATOS.

Los datos se definen en el segmento de datos DS, y se emplea el siguiente formato general que
contiene 3 campos, siendo el primero opcional:

[nombre_de_dato] directiva expresin

3.3.3.1. Campo nombre de dato

Es un campo opcional, y es el nombre de la variable. Su formacin esta definida por las reglas de
los identificadores que se dan ms adelante.

3.3.3.2. Campo directiva

Las directivas que definen los diferentes tipos de datos o tipos de variables son:

DB Define variables de tipo byte ( 1 byte)
Es el nico tipo que admite definicin de cadenas de caracteres
que exceden a dos caracteres.
DW Define variables tipo word (2 bytes)
DD Define variables de tipo palabra doble (4 bytes)
DQ Define variables de tipo palabra cudruple (8 bytes)
DT Define variables de tipo diez bytes (10 bytes)
72
3.3.3.3. Campo expresin

Una expresin puede contener varios valores constantes separados por comas y limitados solo
por la longitud de la lnea.

Ejemplos: X db 23h, 45, hola amigo, 101011b, 56o

hexadecimal decimal cadena binario octal
de bytes

Y dw 0ADE4h, -0FFEh, 324567
SUMAR dw 2345h
_Y12 dd 234567h
$A dt 2345678

FORMA ABREVIADA DE LOS PROGRAMAS FUENTES

Cuando describimos el paso uno:edicin hicimos referencia al formato clsico. Los
ensambladores de Microsofot y Borland proporcionan una forma abreviadas para definir
segmentos, que ahorran cdigo y tiempo, por tanto pasamos a describirla:

Un programa fuente tiene la siguiente estructura:


tiny
small
.model medium
compact
large
.stack tamao_de_la_pila (en bytes)
.data
directivas de datos
.code
.386
nombre_1 proc
instruccin 1
instruccin 2
. . .
Termina
nombre_1 endp
nombre_2 proc
instruccin 1
instruccin 2
. . .
ret
nombre_2 endp
. . .
nombre_n proc
instruccin 1
instruccin 2
. . .
ret
nombre_n endp
end nombre_1




73


Requisitos para cada modelo de memoria

El modelo de memoria puede ser tiny, small, mdium, compact o large. Tambin existe el modelo
huge, que requiere conocimientos avanzados para tratarlo, y que no estudiaremos en este libro.

Los requisitos para cada modelo son:


FORMATO ABREVIADO

MODELO NUMERO DE SEGMENTOS NUMERO DE SEGMENTOS
DE CODIGO DE DATOS
TINY 1
(programas .COM: DS=CS=SS=ES)
Small 1 1
Mdium ms de 1 1
Compact 1 ms de 1
Large ms de 1 ms de 1


A continuacin resolveremos un problema utilizando los dos formatos:

Ejemplo 15

Escribir un programa en lenguaje Ensamblador que escriba en pantalla, un nmero decimal sin
signo de 16 bits, esto es, un nmero cuyo valor est en el rango [0,65535] o en hexdecimal
[0h,FFFFh]

Solucin

Antes de entrar a codificar, tenemos que resolver el problema manualmente. Ya conocemos las
capacidades bsicas de una computadora y tenemos que resolver el problema solamente
utilizando estas capacidades bsicas.

Supongamos que tengamos el nmero 375, cmo podemos separar sus 3 dgitos?. La
respuesta es recurriendo a la divisin entre 10, as tenemos:


10
375
= 37 y el resto es 5

10
37
= 3 y el resto es 7

10
3
= 0 y el resto es 3

Como vemos, dividendo el nmero dado 375 y los cocientes sucesivos entre 10, hasta que el
cociente sea cero, los restos sucesivos obtenidos, que son 5, 7 y 3, resultan ser los dgitos del
nmero, pero al revs. Entonces el problema ya est resuelto, hacemos varias divisiones
sucesivas hasta que el cociente sea cero y guardamos los restos en memoria, utilizando la pila.
Para repetir el procedimiento varias veces recurrimos a la capacidad bsica de hacer
comparaciones simples.

No olvidemos que para dividir dos nmeros, se tiene que guardar el dividendo en el par de
registros DX:AX, y el divisor en un registro que no sea DX ni AX. En nuestro caso, como el
nmero no puede ser mayor que FFFFh, hacemos DX=0 y movemos el valor del nmero a
74
escribir en formato decimal al registro AX, y elegimos el registro SI, para almacenar el divisor
cuyo valor es 10. Entonces el algoritmo seudocodigo es el siguiente:

* Guardamos en la pila los restos de dividir entre 10
Cx=0 (contador)
DX=0
AX=numero
SI=10
Sigo: DIV SI
Push DX
CX=CX+1 ; cuento en cx los nmeros de la pila
CMP AX,0
Salta a sigo si es mayor que cero
* sacamos los restos de la pila y los escribimos en pantalla
Muestro: pop dx
Escribe dl en pantalla
LOOP muestro
Termina


Ya tenemos los conocimientos necesarios para codificar este programa en lenguaje
Ensamblador, que es lo que pasamos a hacer, primero en el formato clsico (Ejem15CL.ASM) y
segundo en el formato abreviado (Ejem15AB.ASM); y aclaramos que solamente usaremos un
solo segmento. de cdigo CS.


Codificacin en formato clsico

; Programa Ejem15cl.asm Ejem15clEscribeNumeroDecimalFormatoClasico.asm
Codigo segment
Assume cs:codigo
main proc
mov cx,0
mov dx,0
mov ax,9648 ; numero a escribir 9648
mov si,10
sigo: div si
push dx
add cx,1
mov dx,0
cmp ax,0
jg sigo ; jump if great salta a sigo si ax es mayor que 0
mov ah,2
muestro: pop dx
add dl,30h
int 21h
loop muestro
mov ah,4ch ; se prepara para terminar
int 21h ; termina
main endp
codigo ends
end main






75


Codificacin en formato abreviado

; Programa Ejem15ab.asm Ejem15ablEscribeNumeroDecimalFormatoAbreviado.asm
.model small
.code
main proc
mov cx,0
mov dx,0
mov ax,9648 ; nmero a escribir:9648
mov si,10
sigo: div si
push dx
add cx,1
mov dx,0
cmp ax,0
jg sigo ; jump if great salta a sigo si ax es mayor que 0
mov ah,2
muestro: pop dx
add dl,30h
int 21h
loop muestro
mov ah,4ch ; se prepara para terminar
int 21h ; termina
main endp
end main

La ejecucin de ambos programas se v a continuacin:



y en formato abreviado:
76


Ejemplo 16

Escribir un programa en lenguaje Ensamblador que escriba en pantalla un nmero de 1 dgito
hexadecimal.

Solucin

Utilizaremos solamente el formato abreviado, por ser ms funcional.

La siguiente tabla es la de los caracteres ASCII, 0, 1, 2, . . . 8, 9, :, ;, <, =, >, ?, @, A, B, C, D, E,
F.
Carcter ASCII Hexadecimal

0 30
1 31
2 32
3 33
4 34
5 35
6 36
7 37
8 38
9 39
: 3A
; 3B
< 3C
= 3D
3E
? 3F
@ 40
A 41
B 42
C 43
D 44
E 45
F 46




77


De acuerdo a esta tabla, si en DL tenemos almacenado cualquier nmero hexadecimal desde 0,
1, 2, ,9; y sumamos a DL el valor 30h, entonces obtenemos en DL el ASCII: 0, 1. 3, . . . ,
9. Por ejemplo, para DL=8h = 10002, resulta DL=3h +30h = 38h, y si escribimos en pantalla el
contenido de DL, obtendremos el carcter 8.

Si en cambio tenemos en DL = Dh = 11012, si sumamos 30h, tenemos DL=Dh + 30h = 3Dh. Si
escribimos en pantalla el valor DL obtenemos, de acuerdo a la tabla de ms arriba, el carcter
=, que no es la respuesta correcta.

Cmo resolvemos el problema?. Observemos que hay una franja de 7 datos que est entre 9
y A, y por tanto a DL hay que aadirle tambin 7. Esto es, si originalmente tenamos DL = Dh,
si le sumamos ya no 30h, si no 37h, obtenemos DL = Dh + 37h = 44h. Ahora si escribimos el
contenido de DL en pantalla obtenemos D, que es el resultado correcto..

En definitiva si en DL hay un nmero hexadecimal menor o igual que 9h se le suma 30h y si el
nmero es mayor que 9, se le suma 37h.

Entonces para escribir un nmero hexadecimal de 1 dgito, el algoritmo a aplicar es:

escribe un nmero hexadecimal de 1 dgito
mov dl,Numero ; dl=numero hexadecimal
add dl,30h ; dl = dl + 30h
cmp dl,39h ; compara dl con 39h
jle saltar ; dl 39 ir a saltar
add dl,7 ; dl > 39, dl = dl + 7h
saltar: escribe dl en pantalla


El programa completo es el siguiente, que grabamos con el nombre ejem16.asm:

; Programa Ejem16.asm Ejem16EscribeNumeroHexadecimalDeUnDigito.asm
.model small
.code
main proc
mov dl,7
add dl,30h
cmp dl,39h
jle saltar
add dl,7
saltar: mov ah,2
int 21h
mov ah,4ch ;
int 21h ; termina
main endp
end main

Los resultados de ejecutar este programa primero con DL=7 y despus con DL=0Dh son los
siguientes:

78




Ejemplo 17

Escribir un programa en lenguaje Ensamblador que escriba en pantalla un nmero de 2 dgitos
hexadecimales.




79


Solucin

Utilizando el programa Ejem16.asm disearemos un programa que escriba un nmero de 2
cifras hexadecimales.

Ahora empezamos a usar la instruccin call nombre_de_procedimiento.

Supongamos que tenemos en DL= E7h =111001112 , y lo que pretendemos es que nuestro
programa escriba en pantalla la cadena E7.

Hacemos lo siguiente, utilizamos la instruccin SHR DL,CL(shift right), que produce un
corrimiento de CL bits a la derecha, del contenido de DL, en la forma siguiente:

MOV CL,4
DL = E7h SHR DL,CL DL = 0Eh

11100111 00001110

y despus llamamos al procedimiento que escribe el valor 0Eh de DL.

A continuacin utilizamos la instruccin AND para convertir en 0000 una parte de un registro.

La tabla de AND, es el de la conjuncin, y est definida en la siguiente forma:

AND 0 1
0 0 0
1 0 1

Entonces si DL = E7h = 111001112

DL = 111001112
0Fh = 000011112

AND DL,0Fh = 000001112 = 07h

y nuevamente llamamos al procedimiento que escribe 1 hexadecimal es decir el nmero
hexadecimal 7.

El procedimiento main del programa ejem16.asm, tiene que adaptarse para que funcione como
un procedimiento interno, que pueda ser activado desde otro procedimiento utilizando la
instruccin call.

Lo primero que tenemos que hacer es adoptar como nombre del procedimiento un identificador
que nos recuerde en forma directa cul es su funcin, es decir que el nombre suscintamente nos
diga qu hace el procedimiento. En este caso, convenimos en llamar al procedimiento
escribe_1_hexa, por que la tarea que va a ejecutar es justamente esa: escribir en pantalla un
nmero de 1 dgito hexadecimal.

80
El procedimiento main del programa ejem16.asm, ya convertido como procedimiento interno es
el siguiente, y que puede ser utilizado por quin lo necesite (recurdese el concepto de
reutilizacin):

escribe_1_hexa proc
push ax
push dx
add dl,30h
cmp dl,39h
jle saltar
add dl,7
saltar:
mov ah,2
int 21h
pop dx
pop ax
ret
escribe_1_decimal endp


Adems del cambio de nombre, se suprime la instruccin mov dl,7 y se han aadido dos
instrucciones push, y dos instrucciones pop; y al finalizar el procedimiento una instruccin ret
(return). Las instrucciones push y pop tienen la funcin de retornar todos los registros que son
utilizados dentro del procedimiento, tal como los recibi. Para el programador que llama (call) un
procedimiento, este ltimo debe funcionar como una caja negra y por ningn motivo debe
cambiar los valores de los registros. La instruccin ret (return en ingles -retorna en castellano-),
permite retornar a la instruccin que sigue a la instruccin call.

A continuacin damos todo el programa completo, el que se ha grabado con el nombre
Ejem17.asm, y la pantalla con los resultados de correr este programa

; Programa Ejem17.asm Ejem17EscribeNumeroHexadecimalDeDosDigitos.asm

.model small
.code
principal proc
mov dl,0E7h
push dx
mov cl,4
shr dl,cl
call escribe_1_hexa
pop dx
and dl,0Fh
call escribe_1_hexa
mov ah,4ch
int 21h
principal endp
escribe_1_hexa proc
push ax
push dx
add dl,30h









81


cmp dl,39h
jle saltar
add dl,7
saltar:
mov ah,2
int 21h
pop dx
pop ax
ret
escribe_1_hexa endp
end principal



Ejemplo 18

Escribir un programa en lenguaje Ensamblador que escriba en pantalla un nmero de 4 dgitos
hexadecimales.

Solucin

Seguimos utilizando la stima capacidad bsica de las computadoras: la reutilizacin. Para
escribir un nmero de 4 hexadecimales, llamaremos dos veces al procedimiento
escribe_2_hexas, convenientemente adaptado.

El siguiente es un programa con su respectivo segmento de datos, para declarar la variable de
nombre numero de tamao 16 bits, es decir del tipo dw (define word) que describimos en el
prrafo 3.2.3. formato de definicin de datos. Tambin en este programa aparece la directiva
.386, que es valida para procesadores 80386 y posteriores, y que usamos porque permite usar
las instrucciones pushA, -que equivale a las instrucciones push AX, push BX, . . . , push SI, push
82
DI-, y la instruccin popA -que equivale a las instrucciones pop DI, pop SI, . . . , pop BX, pop AX-.
El uso de estas instrucciones nos permite ahorrar cdigo. Tambin usamos la directiva ptr, que
estudiaremos con ms detalle ms adelante, que permite mover un dato numrico al medio
registro DL de 1 byte de tamao, desde la variable numero que es de 2 bytes.

; Programa Ejem18.asm Ejem18EscribeNumeroHexadecimalDeCuatroDigitos.asm
.model small
.data
numero dw 0B5E4h ; dato a escribir en pantalla
.code
.386
main proc
mov ax,@data
mov ds,ax
mov dl,byte ptr numero+1 ; dl = B5h
call escribe_2_hexas
mov dl,byte ptr numero ; dl = E4h
call escribe_2_hexas
mov ah,4ch
int 21h
main endp
escribe_2_hexas proc; tiene como par metro a DL
pushA
push dx
mov cl,4
shr dl,cl
call escribe_1_hexa
pop dx
and dl,0Fh
call escribe_1_hexa
popA
ret
escribe_2_hexas endp
escribe_1_hexa proc
pushA
add dl,30h
cmp dl,39h
jle saltar
add dl,7
saltar:
mov ah,2
int 21h
popA
ret
escribe_1_hexa endp
end main

El programa anterior se graba con el nombre Ejem18.asm y el resultado de su ensamble, enlace
y ejecucin se pueden apreciar en la siguiente pantalla:




83



































84
CAPITULO IV PROGRAMAS .EXE vs PROGRAMAS .COM

4.1 Como ejecuta los programas el DOS

En el entorno MS-DOS existen tres tipos diferentes de programas ejecutables desde la lnea de
comandos: los que tiene la extensin .COM (de COMmand), los que tiene la extensin .EXE (de
EXEcutable), y los que tiene la extensin .BAT (de BATch). Este ltimo ya no se utiliza mucho,
pero no deja de ser til. Ahora nos concentraremos en estudiar las diferencias entre programas
.COM y :EXE y tambin las semejanzas.

Si se tiene tres archivos con el mismo nombre prueba, pero diferentes extensiones .COM, .EXE
y .BAT, el orden de prioridad en ejecucin es:

prueba.COM
prueba.EXE
prueba.BAT

es decir, si estn los tres y se digita, en la linea de comandos del DOS, la palabra prueba, se
ejecuta el prueba.COM; si slo estn prueba:EXE y prueba.BAT se ejecuta el prueba.EXE; y si
slo est el prueba.BAT, ste es el que se ejecuta; y si no est ninguno de los tres, el DOS
escribe un mensaje de error, tal como este: comando o nombre de archivo no vlido.

El prefijo del segmento de programa (PSP)

El PSP (Program Segment Prefix) es una estructura usada para controlar ciertos aspectos del
programa. Tiene una longitud de 256 bytes, y siempre est ubicado en los primeros 256 bytes del
segmento donde se carga el programa. En esta estructura se almacena informacin importante,
que es til para la programacin de sistemas y programacin de la computadora, que es un
trabajo muy diferente al de hacer programas de aplicacin. A continuacin se detalla la estructura
del PSP. El PSP entre otros, como un ejemplo, contiene una tabla de manejadores de archivos,
que se utiliza cuando se necesitan ms de 20 archivos abiertos al mismo tiempo.

Programa cargador del sistema

El Dos da soporte de carga a memoria, a dos tipos de programas ejecutables: .COM y .EXE. Un
programa .COM consta de un solo segmento que contiene cdigo, datos y la pila. Si se necesita
de un pequeo programa de utilera o un programa residente en memoria (un programa que es
instalado permanentemente en y est disponible mientras otros programas estn ejecutndose),
se escribe un programa .COM. Un programa .EXE consta de segmentos de cdigo, datos y de la
pila separados y es el mtodo usado para la mayora de programas serios.

4.2. Programa tipo .COM

Los programas .COM son una reminiscencia de la poca que predominaba el sistema operativo
CP/M (el cual trabajaba con procesadores de 8 bits, que son los precursores del 8086 y dems
familia). Este sistema operativo utilizaba la extensin COMmand para implicar que era un
programa ejecutable (no existan los programa con extensin .EXE y slo se poda distinguir un
programa ejecutable de los dems si tena la extensin .COM)





85


Un tipo de programa .COM es almacenado en el disco exactamente como ser cargado en
memoria para su ejecucin. Dicho de otra manera, el programa se almacena en el disco como
una imagen exacta de lo que se cargar en la memoria y se ejecutar.

El PSP de un programa .COM se carga en el desplazamiento 0 a FFh y el programa .COM
empieza en el desplazamiento 100h. Todos los programas en lenguaje de mquina son .COM.
La longitud de un programa .COM, est restringida a 64 Kbytes.

Un programa .COM tiene un solo segmento fsico y cuatro segmentos lgicos el CS, DS, SS y
ES, y todos tienen la misma direccin. Al final del segmento se usa una palabra (16 bits) como
pila. Entonces, la longitud de un programa .COM es en realidad 65536 256 2 = 65278 bytes.
Los 256 son los del PSP y los 2 son de la pila.

Inicializacin de un programa .COM

Cuando el DOS carga un programa .COM para ejecucin, inicializa de forma automtica todos
los registros de segmentos con la direccin del PSP. Por tanto no se requiere programar su
carga. Puesto que el direccionamiento comienza en un desplazamiento de 100H bytes desde el
inicio del PSP, se necesita codificar una directiva ORG como ORG 100h, inmediatamente
despus de segment o el enunciado .CODE. La directiva ORG (Origin) le indica al
emsamblador que empiece la generacin del cdigo objeto en un desplazamiento de 100h bytes
pasando el inicio del PSP, en donde el programa .COM real comienza.

La pila del .COM

El registro SP que apunta a la cabeza de la pila se inicializa con el valor 0FFFEh, y el MS-DOS
almacena un cero en la pila antes de pasarle el control al programa .COM. La pila inicializada con
cero, es para que acte como desplazamiento para el IP, si se utiliza RET para terminar la
ejecucin del programa. Si el programa .COM es grande, o si la memoria est limitada, se debe
tener cuidado al enviar palabras a la pila.

No debe olvidarse que la pila es una parte de la memoria. Adems diremos que existen dos
formas de recuperar datos de la pila: en forma destructiva y en forma no destructiva que
estuduaremos ms adelante.

Conversin a formato .COM

Si su programa ya est escrito en formato .EXE, puede utilizar un editor para convertir
instrucciones a formato .COM. Los formatos de codificacin de MASM y TASM para programas
.COM son idnticos, aunque sus mtodos de conversin difieren. Cuando la conversin .COM
est completa, se puede borrar los archivos .OBJ y .EXE.

Aqu estn los pasos para convertir un programa para Microsoft y Borland, suponiendo que ya
fue creado con un editor el programa fuente de nombre Prueba.ASM

MASM Archivo generado TASM Archivo generado

MASM Prueba Prueba.OBJ TASM Prueba Prueba.OBJ

86
LINK Prueba; Prueba.EXE TLINK /T Prueba Prueba.COM

EXE2BIN Prueba Prueba.COM

4.3 Programas .EXE

Por su parte los programas .EXE (contraccin de la palabra EXEcutable) pueden tener los cuatro
tipos de segmento fsicos diferentes: CS, DS, SS y ES al mismo tiempo (Ver el programa
PRUEBA.asm, del capitulo III).

Cuando el DOS carga un programa .EXE del disco a la memoria para su ejecucin construye un
PSP de 256 bytes (100h) en un lmite de prrafo de memoria interna disponible y almacena el
programa inmediatamente siguiendo al lmite. Despus el DOS hace lo siguiente:

Carga la direccin del segmento de cdigo en el CS

Carga la direccin de la pila en el SS; y

Carga la direccin del PSP en los registros DS y ES

El cargador del DOS inicializa los registros CS:IP y SS:IP, pero no los registros DS y ES. Sin
embargo, por lo comn su programa necesita la direccin del segmento de datos en el DS ( y con
frecuencia tambin en el ES). Como consecuencia, tiene que inicializar el DS con la direccin del
segmento de datos, con la instruccin mov. Vase el programa Prueba.asm en la seccin 3.2
Programa fuente.

Los programas .EXE pueden ser tan grandes como lo permita la memoria instalada. Adems otra
ventaja es que son reubicables; esto permite que ms de un programa sea cargado en memoria
utilizando todo el espacio disponible.

La desventaja de los archivos .EXE es el tamao de la cabecera aadida por el enlazador para
hacer posible la reubicacin.

En contraste, ya sabemos que un programa .COM tiene un solo segmento fsico. Cuando un
programa en lenguaje ensamblador no es muy grande, un archivo .COM es ms que suficiente
para incluir todo lo referente a datos, instrucciones y manipulaciones de pila. De forma distinta al
archivo .EXE, el archivo .COM no es reubicable y debe comenzar en la direccin 100h. La
ventaja de un archivo .COM sobre un archivo .EXE es que reducir significativamente el tamao
del archivo ejecutable.

EJEMPLO DE UN PROGRAMA .COM

Ejemplo 19

Convertir a programa .COM el siguiente programa Ejem19EX.asm, que es un programa .EXE, y
que tiene 3 segmentos fsicos (El segmento de la pila no se utiliza):







87




; Programa Ejem19EX.asm Ejem19EXProgramaEXEAConvertirSumaBinaria.asm
; Programa EXE
codigo segment
assume cs:codigo, ds:datos, ss:pila
main proc
mov si,datos
mov ds,si
mov ah,9
lea dx,cuadro
int 21h
mov bx,x
call binario
lea dx,sigmas
int 21h
mov bx,y
call binario
lea dx,sigigual
int 21h
mov bx,x
add bx,y
call binario
lea dx,saltos
int 21h
mov ah,4ch
int 21h
main endp
binario proc
push ax
push bx
push cx
push dx
mov cx,16
mov ah,2
sigo:
rcl bx,1
mov dl,0
adc dl,30h
int 21h
loop sigo
pop dx
pop cx
pop bx
pop ax
ret
binario endp
codigo ends

datos segment
x dw 13456
y dw 7685
cuadro db 12 dup (0ah)
db 15 dup (20h),36 dup ("*"),0ah,0dh
db 15 dup (20h),"* OPERACION DE SUMA BINARIA *",0ah,0dh
db 15 dup (20h),36 dup ("*"),0ah,0ah,0ah,0dh, 5 dup (20h),"$"
sigmas db " + $"
sigigual db " = $"
saltos db 9 dup (0ah),"$"
datos ends

pila segment stack
db 10 dup ("PILA")
pila ends
end main
88
La conversin consiste en los siguientes pasos:

1
0
) Suprimimos el segmento de pila, eliminando las siguientes instrucciones:

pila segment stack
db 10 dup ('PILA')
pila ends

2
0
) Utilizamos la directiva GROUP, que sirve para agrupar dos o ms segmentos lgicos en un
solo segmento fsico. La sintaxis de esta directiva es:

nombre GROUP nombre_de_segmento1 [, nombre_de_segmento2...]

En nuestro caso, como nombre utilizamos el identificador todos, que puede ser cualquier otro
diferente, solo que tienen que empezar con una letra. La sigiente directiva tiene que colocarse
antes de la directiva codigo segment:

todos GROUP codigo,datos

y esto nos obliga a modificar la directiva assume en la siguiente forma:

assume: cs:todos, ds:todos

3
0
) Antes de la directiva main proc, colocamos la directiva: org 100h, por que todo programa
.COM comienza en el desplazamiento 100h.

4
0
) Eliminamos las instrucciones:

mov ax,datos
mov ds,ax

por que ya no son necesarias, dado que el programa .COM solamente tiene un solo
segmento.
5
0
) Eliminamos las instruccin mov ah,4ch e int 21h, y en su lugar colocamos la instruccin:
int 20h
que utilizan los programas .COM, para pasar el control al DOS

Hechos estos cambios el programa .COM queda as:


; Programa Ejem19.asm Ejem19ProgramaCOMSumaBinaria.asm
; Programa COM
group todo codigo,datos
codigo segment
assume cs:todo, ds:todo
org 100h
main proc
mov ah,9
lea dx,cuadro
int 21h
mov bx,x
call binario






89


(Continuacin)

lea dx,sigmas
int 21h
mov bx,y
call binario
lea dx,sigigual
int 21h
mov bx,x
add bx,y
call binario
lea dx,saltos
int 21h
int 20h
main endp
binario proc
push ax
push bx
push cx
push dx
mov cx,16
mov ah,2
sigo: rcl bx,1
mov dl,0
adc dl,30h
int 21h
loop sigo
pop dx
pop cx
pop bx
pop ax
ret
binario endp
codigo ends
datos segment
x dw 13456
y dw 7685
cuadro db 12 dup (0ah)
db 15 dup (20h),36 dup ("*"),0ah,0dh
db 15 dup (20h),"* OPERACION DE SUMA BINARIA *",0ah,0dh
db 15 dup (20h),36 dup ("*"),0ah,0ah,0ah,0dh, 5 dup (20h),"$"
sigmas db " + $"
sigigual db " = $"
saltos db 9 dup (0ah),"$"
datos ends
end main


ENSAMBLAJE, COMPILACION Y CONVERSION

Los comandos para ensamblar, enlazar y conversin a .COM son los siguientes:

TASM ejem19 <enter>

LINK ejem19; <enter>

EXE2BIN ejem19 ejem19.com <enter>

Para ejecutar el programa se digita el comando:

Ejem19 <enter>
90
El resultado de ejecutar este programa es el siguiente:



VERSION SIMPLIFICADA

La version en formato simplificado del programa .COM es el siguiente:

; Programa .COM version simplificada
; Programa Ejem19VS.asm Ejem19VSProgramaCOMSumaBinaria.asm

.model tiny
.386
.data
x dw 13456
y dw 7685
cuadro db 12 dup (0ah)
db 15 dup (20h),36 dup ("*"),0ah,0dh
db 15 dup (20h),"* OPERACION DE SUMA BINARIA *",0ah,0dh
db 15 dup (20h),36 dup ("*"),0ah,0ah,0ah,0dh, 5 dup (20h),"$"
sigmas db " + $"
sigigual db " = $"
saltos db 9 dup (0ah),"$"
.code
org 100h
main proc
mov ah,9
lea dx,cuadro
int 21h
mov bx,x
call binario
lea dx,sigmas
int 21h
mov bx,y
call binario
lea dx,sigigual
int 21h
mov bx,x
add bx,y
call binario
lea dx,saltos
int 21h
int 20h ; termina el programa .COM
main endp





91


(continuacin)


binario proc
pushA
mov cx,16
mov ah,2
sigo: rcl bx,1
mov dl,0
adc dl,30h
int 21h
loop sigo
popA
ret
binario endp
end main





































92
CAPITULO V PROCEDIMIENTOS vs MACROS

5.1 Programacin modular

La idea de programacin modular es producto del desarrollo de mtodos tericos para el diseo
de programas. Bsicamente, la programacin modular consiste en dividir un programa en
unidades ms pequeas, las cuales pueden ser probadas por separado para despus ser
integradas en un programa que cumple con los objetivos de diseo originalmente propuestos.
Esta definicin no dice nada con respecto al tamao de los mdulos, ni tampoco indica qu
criterio debe emplearse para definirlo, ya sea en trminos abstractos o del nmero de lneas de
cdigo. Afortunadamente se ha hecho un esfuerzo considerable para dar respuesta a estas
cuestiones. Cada mdulo debe llevar a cabo una sola tarea que debe ser independiente de las
que realizan los dems mdulos y contenida en su totalidad, con una sola entrada y una sola
salida. En lenguaje ensamblador la programacin modular se realiza por procedimientos. Estos
ltimos ya fueron estudiados en varios programas y, en muchos casos, constituyen una buena
aproximacin para tareas pequeas o partes mayores de una tarea.

5.2 Procedimientos

Hasta ahora los segmentos de cdigo han consistido slo en procedimientos near, codificados
como:

NOMBRE_PROCEDIMIENTO PROC

. . .
. . .

RET
NOMBRE_PROCEDIMIENTO ENDP

En este caso la directiva PROC informa al sistema que la direccin indicada es el punto de
entrada para la ejecucin del programa, mientras que la directiva ENDP define el final del
procedimiento.

Sin embargo, un segmento de cdigo puede tener cualquier nmero de procedimientos, todos
distinguidos por PROC y ENDP. Un procedimiento (tambin subrutina o mdulo) activado por
una instruccin CALL, es una seccin de cdigo que realiza una tarea definida y clara (tal como
ubicar el cursor en una determinada posicin de la pantalla o bien obtener entrada del teclado)

La organizacin de un programa en procedimientos proporciona los beneficios siguientes:

Reduce la cantidad de cdigo, ya que el procedimiento comn puede ser llamado varias
veces y desde cualquier lugar en el segmento de cdigo
Fortalece la mejor organizacin del programa.
Facilita la depuracin del programa, ya que los errores pueden ser aislados con mayor
claridad.
Ayuda en el mantenimiento progresivo de programas, ya que los procedimientos son
identificados de forma rpida para su modificacin.

La directiva PROC

La directiva PROC (PROCedure o procedimiento en castellano) tiene el siguiente formato:

Nombre_procedimiento PROC [atributo]




93


Indica el comienzo del procedimiento nombre_procedimiento, que consiste en un bloque de
instrucciones que sirven para realizar una tarea determinada y que puede invocarse desde varios
puntos del programa.

Un procedimiento puede ejecutarse por la instruccin CALL.

El atributo puede ser NEAR que es el default, es decir si no se consigna el atributo- o FAR.

Un procedimiento NEAR slo se puede llamar desde el segmento que est definido.

Al llamar a un procedimiento NEAR, se guarda en la en la pila solo el desplazamiento (valor del
IP) de la instruccin siguiente al CALL, que se recupera al retornar de un procedimiento con la
instruccin RET .

Un procedimiento FAR se puede llamar desde cualquier segmento. Al llamar a un procedimiento
FAR, se guarda en la pila el segmento (valor de CS) y el desplazamiento (valor de IP), valores
que se recuperan con la instruccin RET.

Directiva PUBLIC

Es posible desarrollar un programa que conste de un programa principal enlazado con uno o ms
subprogramas ensamblados por separado. As, si queremos que el procedimiento o dato o
etiqueta, sean accesibles desde uno o ms procedimientos PROC ensamblados por separado
con el enlazador LINK.EXE, debe utilizarse la directiva PUBLIC, que tiene el siguiente formato:

PUBLIC nombre [, . . . ]

Donde nombre puede ser:

El nombre de un procedimiento
El nombre de una variable
Una etiqueta

( 1 ) Ejemplo si queremos que el procedimiento SUMAR sea accesible de otros mdulos
separados, escribiremos:

PUBLIC SUMAR
SUMAR PROC [NEAR o FAR] ; Comienzo del procedimiento
. . .
RET
SUMAR ENDP ; Fin del procedimiento

En este caso el mdulo activador debe declarar que el mdulo SUMAR es externo, utilizando la
directiva EXTRN (EXTERN o externo en castellano), que identifica los elementos que fueron
declarados pblicos en otro mdulo separado.

EXTRN SUMAR:[NEAR o FAR]

( 2 ) Si queremos que una variable X, de tipo byte, sea accesible desde un mdulo separado,
escribiremos:

PUBLIC X
X DB 34h,567

Que requiere la directiva EXTRN en el mdulo activador en la siguiente forma:

EXTRN X:BYTE
94
Para otros tipos de variable se utiliza: WORD para tipo DW ( 2 bytes), DWORD (4 bytes) para
tipo DD.

Las instrucciones CALL y RET

La instruccin CALL transfiere el control a un procedimiento llamado, y la instruccin RET
regresa del procedimiento llamado al procedimiento original que hizo la llamada. RET debe ser
la ltima instruccin en un procedimiento llamado.

Parmetros para pasar datos a un procedimiento PROC.

Cuando se activa o se llama a un procedimiento es necesario pasarle datos y tambin el
procedimiento debe retornar datos. Es un intercambio de informacin

As como las personas pueden comunicarse e intercambiar informacin, podemos hacer que los
programas se comuniquen e intercambien informacin.

Un ejemplo practico de comunicacin es el que se presenta entre profesor y alumno, en el
proceso de enseanza-aprendizaje. El profesor enva un mensaje al alumno, ste recibe el
mensaje y debe enviar un mensaje de respuesta, es decir debe presentarse un ciclo cerrado de
intercambio de informacin: profesor-alumno y alumno-profesor; todo esto para que el proceso
de enseanza-aprendizaje sea exitoso. Esto se puede apreciar en la siguiente figura:

























En igual forma dos programas pueden intercambiar informacin. En vez del profesor podemos
imaginar un programa activador que hace las veces de amo y en vez del alumno podemos
imaginar otro programa activado que hace las veces de esclavo , ambos algoritmos
datos
profesor
alumno
datos




95


intercambian datos. El proceso de intercambio de datos siempre lo inicia el algoritmo activador,
por eso su condicin de amo. Convenimos en que al programa activado le llamaremos
subprograma (o tambin rutina o mdulo).








Pasemos a estudiar los subprogramas en detalle.

En los lenguajes de programacin de alto nivel existen dos tipos de subprogramas. Ellos son
llamados subprogramas procedimiento y subprogramas funcion. Hay ms similitudes que
diferencias entre ambos tipos y los dos pueden hacer la misma tarea sin mayores cambios, y por
lo tanto la eleccin depende mucho de las preferencias del programador. Podramos afirmar que
cada programa funcin tiene un programa procedimiento equivalente y viceversa. Pero hay
situaciones en que un programa funcin se adapta mejor que su programa procedimiento
equivalente, porque permite ahorrar lneas de cdigo.

Algunos lenguajes trabajan con los dos tipos de subprogramas la mayora de lenguajes estn
en esta categora, otros en cambio como el lenguaje C solo trabaja con subprogramas funcion y
este marco filosfico de concepcin de la programacin le da a este lenguaje mucha potencia.
En cambio el lenguaje Ensamblador solo trabaja con subprogramas procedimiento, que son los
que hemos descrito

SUBPROGRAMAS PROCEDIMIENTO

Antes de dar otro ejemplo, sera apropiado resumir las ideas desarrolladas hasta aqu. Estas
pueden ser ilustradas examinando la estructura del siguiente esquema:




p1pppp







Instruccin que sigue a la instruccin CALL

En un lenguaje alto nivel cuando se ejecuta la instruccin Call (o su equivalente), la secuencia
de eventos es como sigue:

1. Los valores de los argumentos a1, a2, a3, ,an son asignados a los parmetros p1,p2,p3,
,pn.

2. El control se pasa a la primera instruccin ejecutable en el procedimiento.



programa activador
(amo)



programa activado
(esclavo)
DATOS
DATOS
pn=an
* Programa principal ...
p2=a2
p1=a1

CALL NOMBRE (a1, a2, a3,...,an)


ar+1=pr+1, ar+2=pr+2, ,an=pn

,



PROCEDIMIENTO NOMBRE(p1,p2,p3,...,pr; pr+1,...,,pn)









retorna


96
Cuando una instruccin retorna (RET en Ensamblador) es ejecutada (pueden haber varios RET),
la secuencia de eventos es esta otra:

1. Solamente los valores de los parmetros por referencia pr+1,pr+2, ,pn son asignados a los
argumentos por referencia ar+1, ar+2, ,an ...

2. El control se pasa la instruccin que sigue a la instruccin CALL

Observaciones

Naturalmente el nmero de argumentos debe ser el mismo en la lista de argumentos y en la
lista de parmetros.
No slo eso, tambin deben ser del mismo tipo.

El lenguaje ensamblador para el paso de parmetros utiliza registros o variables de tipo public
y/o tambin la pila.

EJEMPLOS DE PROGRAMACION MODULAR.

A continuacin disearemos procedimientos externos, esto es, que se encuentren en un archivo
separado y que se enlazan usando el programa LINK:EXE. No debemos olvidar que el
ensamblador (sea MASM.EXE o TASM.EXE) genera un programa objeto, que aunque est en
lenguaje de mquina, todava no es ejecutable, por que le faltan otros componentes. Es el
programa de utilidad LINK.EXE quien genera lo que se llama un programa reubicable, al aadir
una cabecera adicional al archivo .OBJ ya generado por el ensamblador. Con esto el enlazador
habilita al programa para que el sistema operativo lo pueda colocar en cualquier parte de
memoria disponible.

No slo esto, el programa LINK.EXE, permite ensamblar varias rutinas que han sido construidas
en archivos separados, como pasamos a estudiar.

5.3 Generacin del programa PROCS.ASM con mdulos objeto

Escribir dos procedimientos externos, (1) el primero de nombre clear, que blanquee la pantalla, y
(2) el segundo gotoxy para posicionar el cursor en la pantalla. Estos dos procedimientos deben
grabarse en el archivo PROCS.ASM

De acuerdo al manual de interrupciones de los procesadores Intel de la familia X86, para limpiar
pantalla o posicionar el cursor debemos utilizar la interrupcin del BIOS: int 10h, asociada a la
pantalla.

( 1 ) Para limpiar la pantalla, usaremos la funcin AH=6, que desplaza (scroll) hacia arriba la
pgina activa. Se requieren las siguientes entradas, es decir que se den antes de activar la
interrupcin:
AL = nmero de lneas. Las lneas de la parte inferior se borran. Si AL=0 se borra toda la
ventana (pantalla).
CH = Fila esquina superior izquierda
CL = Columna esquina superior izquierda
DH = Fila esquina inferior derecha
DL = Columna esquina inferior derecha
BH = Atributo a usar en los caracteres en la lnea en blanco




97


Siendo el atributo

0 Negro
1 Azul
2 Verde
3 Azul-Verde (cyan)
4 Rojo
5 Magenta
6 Marrn
7 Blanco

De acuerdo a estos requerimientos el cdigo del procedimiento clear para blanquear la pantalla y
que en ella se dibujen los caracteres en color blanco (atributo bh=7), en un fondo negro que
es el color por default de la pantalla, es el siguiente:

; Procedimiento para limpiar pantalla, fondo blanco
public clear
clear proc near ; no requiere parmetros
pushA
mov al,0.
mov cx,0
mov dh,24 entradas de la funcin AH=6
mov dl,79
mov bh,7
mov ah,6 ; solicitud de funcin de limpiado
Int 10h ; procede a limpiar
popA
ret
clear endp

( 2 ) Para posicionar el cursor utilizaremos la funcin AH=2, que requiere las siguientes entradas:

DH = Fila (0 24)
DL = Columna (0-79)
BH = Nmero de pgina. La pantalla tiene cuatro pginas disponibles
que se identifican con los nmeros 0,1,2 y 3, para el modo normal de 80
columnas. Por default se usa la pgina 0.

En este caso requerimos dos parmetros el DH para la fila y el DL para la columna. El
procedimiento resultante es:

; Procedimiento para posicionar el cursor
public gotoxy
gotoxy proc near ; Parmetros DH = fila DL=columna
pushA
mov bh,0
mov ah,2 ; solicitud para posicionar el cursor
int 10h ; lo posiciona
popA
ret
gotoxy endp
98
Aunque estos procedimientos pueden guardarse en forma separada en sus propios archivos, por
simplicidad de operacin, los almacenaremos en un solo archivo, que llamaremos PROCS.ASM.
Ms adelante a este archivo le agregaremos, uno por uno, nuevos procedimientos que tambin
sern pblicos, y nos servir para construir una librera de mdulos objeto. Al juntarlos en un solo
archivo de nombre PROCS.ASM, no importando en que orden se ubican, la disposicin en la
que quedan es la siguiente es el siguiente:

; Programa PROCS.asm PROCSProcedimientosClearGotoxy.asm
.model small
.386
.code
; Procedimiento para limpiar pantalla, fondo blanco
public clear
clear proc near ; no requiere parmetros
pushA
mov al,0.
mov cx,0
mov dh,24
mov dl,79
mov bh,7
mov ah,6 ; solicitud de funcin de limpiado
Int 10h ; procede a limpiar
popA
ret
clear endp
; Procedimiento para posicionar el cursor
public gotoxy
gotoxy proc near ; Parmetros DH = fila DL=columna
pushA
mov bh,0
mov ah,2
int 10h
popA
ret
gotoxy endp
end

Este programa solamente se ensambla, porque, solamente interesa generar el modulo objeto
PROCS.OBJ, que ser suficiente para nuestros propsitos. Por ese motivo solamente se utiliza
el comando:

TASM PROCS <enter>

El resultado de ensamblar el programa fuente PROCS.ASM, es el siguiente:







99


Ejemplo 20

Escribir el programa Ejem08.com, del ejemplo 8, que lee una cadena de teclado, la almacene en
memoria y despus despliegue esta cadena en pantalla.

El programa debe ser interactivo y tiene que utilizar las rutinas clear para borrar la pantalla y
gotoxy para posicionar los mensajes. El diseo de pantalla es el siguiente:


Ingrese una cadena : Estoy aprendiendo Ensamblador
Cadena leda : Estoy aprendiendo Ensamblador

Desea continuar (s/n)?:


Como la lgica del programa, ya fue explicada ampliamente al disear el algoritmo del ejemplo 8,
nos concentraremos en los cambios que deben hacerse para utilizar las rutinas clear y gotoxy, y
para conseguir que el programa sea interactivo. Los cambios al programa original y las nuevas
instrucciones se han escrito en letra negrita, para que se aprecien.

; Programa Ejem20.asm Ejem20LeeUnaCadenaYLaEscribeEnPantalla.asm
.model small
.data
mensaje1 db Ingrese una cadena : $
mensaje2 db Cadena leida : $
mensaje3 db Desea continuar (s/n)?: $
cadena db 50,$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
.code
extrn clear:near, gotoxy:near
main proc
mov ax,@data
mov ds,ax
sigo:
call clear
mov dh,12
mov dl,14
call gotoxy
lea dx,mensaje1
mov ah,9
int 21h
lea dx,cadena
mov ah,0Ah
int 21h
mov ah,2
mov dl,0Ah
int 21h
mov dh,13
mov dl,14
call gotoxy
lea dx,mensaje2
100
mov ah,9
int 21h
lea dx,cadena
add dx,2
mov ah,9
int 21h
mov dh,15
mov dl,14
call gotoxy
lea dx,mensaje3
mov ah,9
int 21h
mov ah,1
int 21h
cmp al,s
je sigo
mov ah,4ch
int 21h
main endp
end main

Este programa se ensambla, enlaza y ejecuta, con los siguientes comandos:

TASM ejem20 <enter>
LINK ejem20 PROCS; <enter>
Ejem20 <enter>

El resultado de su ejecucin es el siguiente:



5.4 Una alternativa: las macros

Lo mismo que se puede hacer con los procedimientos PROC, se puede lograr de otra manera
muy distinta, utilizando la directiva macro.

Una macro es un bloque de sentencias en lenguaje Ensamblador que utiliza una serie de
parmetros.





101


El formato de la directiva macro es el siguiente:

nombre MACRO lista_de_parmetros
. . .
instrucciones de lenguaje Ensamblador
. . .
ENDM

La primera directiva, que es la cabecera de la macro, comienza con un identificador que es el
nombre de la macro y termina con una lista de parmetros que se separan por comas. El fin de
la macro se indica mediante la directiva ENDM. Entre ambas directivas se incluyen las sentencias
que constituyen el cuerpo de la macro.

Los parmetros deben figurar en las instrucciones de la macro.

La invocacin de una macro consiste en especificar el nombre de la macro, junto con los
argumentos, que en la mayora de casos son iguales en nmero y en tipo que los parmetros de
la macro, por que la macro es muy flexible en los casos que no cumple esta condicin:

nombre_macro lista_de_argumentos

Cada argumento se corresponde con cada parmetro y cuando se invoca la macro hace que se
incluya en el bloque de sentencias que constituyen el cuerpo de la mquina, sustituyendo los
parmetros de la macro por los argumentos. A este proceso se le llama expansin de la macro.
En el listado del programa fuente ensamblado las lneas generadas se indican mediante el signo
+ en la columna 31. La columna 32 se deja en blanco. La columna 33 se corresponde con la 1
del mdulo fuente.
Hacemos las siguientes observaciones:

Pueden existir macros sin parmetros

El nmero de argumentos en la invocacin de una macro no tiene por qu coincidir con
el nmero de parmetros. Si hay ms argumentos que parmetros, se ignoran los
argumentos que sobran. Si hay menos argumentos que parmetros, los parmetros que
faltan se convierten en nulos.

Ejemplos:

( 1 ) Macro para calcular Z = X * Y

PRODUCTO MACRO X,Y,Z1,Z2

mov ax,X ; ax=X
mov si,Y ; si=Y
mul si ; DX:AX=X * Y
mov Z1,dx ; Z1=dx
mov Z2,ax ; Z2=ax
ENDM

Un programa de activacin para muliplicar 0FFFFh x =FFFFh es el siguiente
102

.model small
.data
parte_alta dw ?
parte_baja dw ?
.code
producto mecro X,Y,Z1,Z2
mov ax,X ; ax=X
mov si,Y ; si=Y
mul si ; DX:AX=X * Y
mov Z1,dx ; Z1=dx
mov Z2,ax ; Z2=ax
endm
main proc
mov ax,@data
mov ds,ax
PRODUCTO 0FFFFh,0FFFFh,parte_alta,parte_baja
mov ah,4ch
Int 21h
main endp
end

La expansin resultante, de esta ltima instruccin es:


mov ax,0FFFFh
mov si,0FFFFh
mul si
mov parte_alta,dx
mov parte_baja,ax


Si se corre el programa en parte_alta se almacena el valor FFFEh y en parte_ baja 0001h.

( 2 ) La siguiente es una macro que cuando se activa, escribe el carcter que se encuentra en el
identificador uno tantas veces como indica el valor de dos


lista macro uno,dos,tres
mov dl,uno
mov cx,dos
mov ah,2
tres: int 21h
add dl,1
loop tres
endm

por ejemplo si se corre el siguiente programa:





103



; Programa PruebaMC.asm PruebaMCPruebaUnaMacro.asm

lista macro uno,dos,tres
mov dl,uno
mov cx,dos
mov ah,2
tres: int 21h
add dl,1
loop tres
endm
miguel segment
assume cs:Miguel
main proc
lista 'A',10,sigo
lista 'K',11,continuo
mov ah,4ch
int 21h
main endp
miguel ends
end main

se producen dos expansiones, que son :

mov dl,A
mov cx,10
mov ah,2
sigo: int 21h
add dl,1
loop sigo

mov dl,K
mov cx,11
mov ah,2
continuo: int 21h
add dl,1
loop continuo

Almacenemos el programa con el nombre PruebaMC.asm, y si se corre el programa escribe la
cadena ABCDEFGHIJ seguida de la cadena KLMNOPQRSTU, como se puede apreciar en la
siguiente pantalla



104
As como hemos empezado a construir un archivo de procedimientos PROCS.ASM, que despus
convertiremos en una librera, se puede crear una biblioteca de macros. Para utilizar esta librera
de macros se utiliza la directiva INCLUDE en la siguiente forma:

INCLUDE C:\MACROS.LIB

Siendo MACROS.LIB, el archivo que contiene las macros. Veamos un ejemplo:

Ejemplo 21

El programa que se d ms abajo, de nombre PrPROCS.ASM, que lee un nmero como cadena
y lo escribe al revs, utiliza los procedimientos clear y gotoxy. Se pide:

( 1 ) Escribir los procedimientos clear y gotoxy, como macros, utilizando los mismos nombres, y
grabarlos en un archivo de nombre macros.lib
( 2 ) Modificar el programa PrPROCS.ASM, y ya modificado grabarlo con el nombre
Ejem21.ASM, para que en vez de usar los procedimientos utilice la librera de macros.lib,
creada en la parte ( 1 ).

; Programa PrPROCS.asm PrPROCSPruebaProcedimientosClearGotoxy.asm
.model small
.386
.data
titulo1 db "**************************************************************$"
titulo2 db "* Archivo de Procs:PPROCS.ASM *$"
titulo3 db "* Prueba de los modulos clear y gotoxy *$"
titulo4 db "* Programa: PrPROCS.asm *$"
titulo5 db "* Lee un numero como cadena y lo escribe al reves *$"
titulo6 db "**************************************************************$"
mensaje1 db "Ingrese un numero : $"
mensaje2 db "Numero leido al reves : $"
pregunta db "Desea continuar (s/n)? : $"
numero db 255
.code
extrn clear:near,gotoxy:near
main proc
mov ax,@data
mov ds,ax
mov es,ax
sigo:
mov dl,17h ; fondo_azul-letras_blancas
call clear
call titulo ;titulo es un procedimiento interno
mov dh,17
mov dl,15
call gotoxy
lea dx,mensaje1
mov ah,9
int 21h




105


lea dx,numero
mov ah,0ah
int 21h
mov di,1
mov cl,numero[di]
mov dh,18
mov dl,15
call gotoxy
lea dx,mensaje2
mov ah,9
int 21h
mov di,cx
add di,2
repite:
dec di
mov dl,numero[di]
mov ah,2
int 21h
loop repite
mov dh,20
mov dl,15
call gotoxy
lea dx,pregunta
mov ah,9
int 21h
mov ah,1
int 21h
cmp al,"s"
je sigo
mov ah,4ch
int 21h
main endp
titulo proc
pusha
mov dh,8
mov dl,15
call gotoxy
lea dx,titulo1
mov ah,9
int 21h
mov dh,9
mov dl,15
call gotoxy
lea dx,titulo2
mov ah,9
int 21h
mov dh,10
mov dl,15
call gotoxy
106
lea dx,titulo3
mov ah,9
int 21h
mov dh,11
mov dl,15
call gotoxy
lea dx,titulo4
mov ah,9
int 21h
mov dh,12
mov dl,15
call gotoxy
lea dx,titulo5
mov ah,9
int 21h
mov dh,13
mov dl,15
call gotoxy
lea dx,titulo6
mov ah,9
int 21h
popa
ret
titulo endp
end main

( 1 ) Conversin a macros de los procedimientos clear y gotoxy

La conversin es muy sencilla. La macro clear, no tendr parmetros y la macro gotoxy, tendra
dos parmetros fil, para indicar la fila y col para indicar la columna. El archivo macros.lib
contiene a las dos macros como apreciamos a continuacin:

;Macros.LIB MacrosContieneLasMacrosClearGotoxy.LIB
clear macro
pushA
mov al,0
mov cx,0
mov dh,24
mov dl,79
mov bh,7
mov ah,6 ; solicitud de funcion de limpiado
Int 10h ; procede a limpiar
popA
endm
gotoxy macro fil,col ; Parametros DH=fila DL=columna
pushA
mov dh,fil
mov dl,col
mov bh,0




107


mov ah,2
int 10h
popA
endm

( 2 ) Conversin del programa PrPROCS.ASM y grabarlo como Ejem21.ASM, para usar las
macros

El siguiente es el programa ejem21.asm, que es el resultado de convertir el programa original
PrPROCS.ASM para que use las macros clear y gotoxy.

; Programa Ejem21.asm Ejem21LeeUnNumeroYLoEscribeAlRevesConMacros.asm
.model small
.386
.data
titulo1 db "****************************************************************$"
titulo2 db "* Biblioteca MACROS.LIB *$"
titulo3 db "* Prueba de las macros clear y gotoxy *$"
titulo4 db "* Programa: Ejem21.asm *$"
titulo5 db "* Lee un numero como cadena y lo escribe al reves *$"
titulo6 db "****************************************************************$"
mensaje1 db "Ingrese un numero : $"
mensaje2 db "Numero leido al reves : $"
pregunta db "Desea continuar (s/n)? : $"
numero db 255
.code
include macros.lib ; utiliza las macros
main proc
mov ax,@data
mov ds,ax
mov es,ax
sigo:
clear
call titulo
mov dh,17
mov dl,15
gotoxy 17,15
lea dx,mensaje1
mov ah,9
int 21h
lea dx,numero
mov ah,0ah
int 21h
mov di,1
mov cl,numero[di]
mov dh,18
mov dl,15
gotoxy 18,15
lea dx,mensaje2
mov ah,9
int 21h
mov di,cx
add di,2
repite:
dec di
mov dl,numero[di]
mov ah,2
108
int 21h
loop repite
gotoxy 20,15
lea dx,pregunta
mov ah,9
int 21h
mov ah,1
int 21h
cmp al,"s"
je sigo
mov ah,4ch
int 21h
main endp
titulo proc
pusha
gotoxy 8,15
lea dx,titulo1
mov ah,9
int 21h
gotoxy 9,15
lea dx,titulo2
mov ah,9
int 21h
gotoxy 10,15
lea dx,titulo3
mov ah,9
int 21h
gotoxy 11,15
lea dx,titulo4
mov ah,9
int 21h
gotoxy 12,15
lea dx,titulo5
mov ah,9
int 21h
gotoxy 13,15
lea dx,titulo6
mov ah,9
int 21h
popa
ret
titulo endp
end main


Primero es necesario ensamblar el archivo Macros.LIB, para verificar si no tiene errores de
sintaxis, y obtenemos el siguiente resultado:






109



El error: Unexpected end of file encountered se genera porque el cdigo de las macros no
tiene la instruccin End. Por tanto no le damos ninguna importancia.

El resultado de correr el programa Ejem21.asm, es es el siguiente: