Professional Documents
Culture Documents
desde cero
+ Interrupciones
Unidad 3
3"edicin
ampliada
Mario Gir'lzburg
INDICE
EJERCICIOS 19 A 25: ejercicios varios con cambios internos en los elementos de vectores 34 a -39
EJERCICIO 25 a 28: ejercicios con traducciones de sentencias IF y FOR a bajo nivel 39 a40
CONSIDERACIONES GENERALES PARA PROGRAMAR EN ASSEMBLER 41
EJERCICIOS PARA REALIZAR 44
EJERCICIOS 30 y 31: uso de JBE (Jump if below or equal) 45
EJERCICIO 32: uso de la'instruccin .JPE (Jump if parity is even =Saltar si la paridad es par) 46
EJERCICIO 34 ordenamiento de una lista por burbujeo 46
EJERCICIOS VARIOS CON OPERACIONES ARITMTICAS 47 a 51
DIRECCIONES EFECTIVAS Y REGISTROS DE SEGMENTO EN MODO REAL 52
LLAMADO A SUBRUTINAS 54
40
AX SI
BX BX
' ex DI
'
- - BX ES EL UNICO REGISTRO QUE PUEDE USARSE
DX COMO ACUMULADOR O BIEN COMO PUNTERO
BP PUEDE USARSE COMO PUNTERO EN .COM
Figura 3.1
En las unidades 1 y 2 se trataron distintos ejemplos que empleaban el registro AX, de 16 bits, de la UCP como
acumulador, y para operaciones de entrada y salida. Este registro tambin es indispensable usarlo cuando se multiplica o .
divide, segn se ver. Pero en la UCP existen otros registros de 16 bits que pueden elegirse indistintamente como
acumuladores, como BX, CX y DX (1igura 3.1).
Tambin se dispone en la UCP de los registros SI y DI para guardar exclusivamente direcciones que apunten a posiciones
de memoria (registros punteros), como se ejemplifica a partir del ejercicio 7.
BX es el nico acumulador que tambin puede utilizarse como registro puntero (ejemplificado en el ejercicio 13).
El registro IP (instruction pointer) es afectado por las instrucciones de salto Uump). ,
Si se necesita operar datos de 8 bits, los registros de 16 bits: AX, BX, CX o DX (o sea los terminados en X), pueden
dividirse en dos registros de 8 .bits. Por ejemplo, AX se descompone en AH y AL; BX en BH y BL, etc.
Las letras H (de "high"), y L (de "low") hacen 'referencia a la parte alta y baja de un registro de 16 bits.
U3-2 M.Ginzburg- Assembler desde Cero _l -
Entonces, en assembler, cuando se necesita definir un registro para datos o resultados de 16 bits, el mismo tendr su segunda
letra terminada en X; y en caso de ser necesario emplear un registro para datos o resultados de 8 bits, se usar una mitad del
mismo, la cual se identificar por ser su segunda letra una H o una L, segn se elija.
En los procesadores 386, 486 y Pentium, los registros citados pueden tener 32 bits, indicndose EAX, EBX, ... , EDI, ESI,
EIP. La letra E hace referencia a "extended". Dichos registros tambin pueden elegirse para guardar 16 u 8 bits, mediante la
simbologa antes definida. El Debug slo permite definir registros de 16 u 8 bits.
El siguiente ejercicio bsico, analizado y realizado directamente en cdigo de mquina, sin usar Assembler
en la Unidad 1 de esta obra, muestra los pasos necesarios que se deben tener presente en los restantes ejerci-
cios que se plantearn. Asimismo conviene aclarar que un desarrollo en Assembler puede realizarse en una
infinidad de formas. Las que se presentan en este texto slo pretenden ser una gua, y no un modelo que Il
limite potencialidades creativas.
EJERCICIO 1
En un lenguaje de alto nivel se tiene la sentenciaR = P + P- Q para operar nmeros enteros (variable " Integrs").
Codificarla en lenguaje Assembler, lo cual tambin servir para poner en evidencia cmo se concreta a nivel de hardware
y cmo podra traducirla un programa traductor tipo Compilador cuando realiza la traduccin en seudo assembler.
lb) La figura 3.2 tambin sirve para plantear la secuencia de los movimien-
tos y -operaciones que deben ordenar las instrucciones a codificar, para ir lle-
vando a cabo en orden los pasos necesarios para concretar la suma algebraica
que ordena la sentencia R = P + P - Q teniendo presente que dichos movi-
mientos y operaciones son los que puede efectuar tpicamente un computador. Cocl
Estos ltimos, como se plante en la Unidad 1 de esta obra, pueden compren-
derse conceptualmente en relacin con lo que puede hacer una simpe
calculadora de bolsillo. Asimilaremos su visor-acumulador al registro AX del
procesador arriba definido, y sus circuitos para sumar/restar a la Unidad
Figura 3 .2 Aritmtico Lgica (UAL).
Memoria
En un computador los nmeros que se suman provienen directamente de su
memoria principal en vez de ser generados desde un teclado como en la calculadora, y los resultados que aparecen en AX
pueden ser guardados en dicha memoria. Esto lo indican las flechas dibujadas en la figura 3.2.
rnpan 2 cel- Cada instruccin ordena una operacin (MOV; ADD, etc.), seguida del destino del resultado con una coma final. Luego
gnaremos contina otro campo con el lugar de origen de un dato a operar. El campo de comentarios de la derecha es optativo.
:crivamente.
-A 0200 .J
xxxx:0200 MOV AX, [5000] .J2 Llevar a AX una copia del dato (P) que est en 5000 y 5001 de la memoria.
xxxx:0203 ADD AX, [5000] .J Sumar a AX una copia del dato (P) que est en 5000 y 500 l de la memoria.
smovimien- xxxx:0207 SUB AX, [5006) .J Restar a AX una copia del dato (Q) que est en 5006 y 5007 de la memoria.
t para ir !le- xxxx:020B MOV [5010), AX .J Transferir a 5010 y 5011 de memoria una copia del contenido de AX.
algebraica xxxx:020E .J (Se vuelve a pulsar .J para salir del comando A).
os movi- (E l guin indica que el Debug espera otro comando).
oomputador. Con xxxx se ha querido indicar 4 smbolos hexadecimales a tratar, cuyo valor puede ser distinto en cada PC.
compren-
a simple Cuando se ti pea MOV AX, [5000], a partir de la direccin 0200 quedarn en celdas sucesivas de memoria codificadas en
o AX del ASCII cada uno de los caracteres tipeados. Al tipear .J el programa Ensamblador del Debug traducir MOV AX, [5000]
en la instruccin de mquin a 10100001 00000000 00000101 = Al0050h que se escrib ir en 3 celdas a partir de dicha
direccin 0200, desapareciendo as todos los caracteres en ASCII antes tipeados desde 0200, y la direccin que aparecer
ente de su para escribir la segunda instruccin ser 0203 . El cdigo Al y el cdigo ASCII se tratan en la Unidad 1 de esta obra.
n enAX Al terminar de tipear las 4 instrucciones, las mismas quedarn traducidas en cdigo de mquina listas para ser ejecutadas.
Si se quiere ver estos cdigos en hexa, se debe tipear el comando U 0200 .J
4) Como se ejemplifica luego del ejercicio 13 y al igual que en los ejemplos de la Unidad 1 de esta obra, antes de eje-
cutar con el Debug esta secuencia de instrucciones, se deben escribir en memoria con el comando E los datos a procesar
(valores elegidos para las variables P y Q). De seguido, con el comando RIP se debe dar el valor 0200 al IP; con el
comando R se debe verificar que todo est en orden; y con 4 comandos T tuno por instruccin) se ejecutar la secuencia.
OTRA FORMA DE REALIZAR EL EJERCICIO 1
e:s -ooon. En un computador R = P + P- Q se puede hacer de mltiples maneras, como ser. (figura 3.4):
ciones 1) Llevar hacia AX una copia del valor (P) que est en memoria en las direcciones 5000/ l.
2) llevar hacia BX una copia del valor (Q) que est en memoria en las direcciones 5006/7.
d ireccio- 3) Realizar la suma AX f-AX + AX, o sea sumarle a AX su propio valor, y el resultado P + P dejarlo en AX.
4) Realizar AX f-AX- BX, o sea restar a AX el valor de BX, y el resultado P + P - Q dejarlo en AX. -
instrucc in
5) Llevar hacia las direcciones 5010/ 11 (donde est R) una copia del valor (P + P- Q) que est en AX.
est en AX.
oria.
Este programa Debug est presente en la mayora de las PC, vincu lado al DOS. Ya fue usado por su simplicidad didctica en la
Unidad 1 de esta obra para codificar en memoria datos e instrucciones en cdigo de mquina y luego ejecutarlas una a una. Ahora lo
usaremos tambin para programar directamente en Assembler, pues no requiere directivas para el traductor Ensamblador, como otros
Debug ms potentes (como el MASM o d TASM) que permiten entre otras cosas usar nombres de variables en lugar de direcciones
numricas, acercando al Assembler a lenguajes de alto nivel. Sin necesidad de usar ni pensar en esas directivas, el alumno desde el
- cado todos comienzo centra su esfuerzo en construir directamente secuencias de instrucciones en Assembler.
2
se codifiq ue Si una instruccin tiene un nmero entre corchetes se dice que est en "modo tlirecto", o en modo de direccionamiento directo, dado
s;:mbler. que directamente dicho nmero es la direccin para localizar en memoria el dato a procesar.
M signi-
U3-4 M.Ginzburg- Assembler desde Cero
En un lenguaje de alto nivel se escribi la sentenciaR = M x N para multiplicar nmeros enteros positivos.
Codificarla en lenguaje Assembler, suponiendo un microprocesador bsico que no tiene instrucciones para multiplicar, y
para plantear la correspondencia entre las estructuras tipo "FOR i = 1 to i = n .... "y su equivalencia en Assembler. -
UCP Este ejercicio es esencial, pues empezaremos a usar las instrucciones de salto
condicional, en este caso para repetir la ejecucin de una secuencia,
estructura que ser usada en muchos ejercicios para repetir n veces un 2b) Prt:Jd
procedimiento. resu
Emplearemos una instruccin de salto condicional para realizar el producto 2c) ~
R =M x N, repitiendo N veces una operacin de suma.
Por definicin de producto es R = M x N = M + M + . . . . + M expresin
con N sumandos iguales a M y N - 1 sumas.
Si bien puede partirse de esta expresin, a los fines didcticos haremos
R = M x N = O + M + M + . . . . + M; sea mediante N sumas con
sumando M, en vez de N- 1 sumas.
Si N= 4, es M x 4 =O + M+ M+ M+ M (N = 4 sumas con el sumando M)
A fin de que resulte una secuencia sencilla, supondremos: que M y N son n-
meros enteros positivos de dos bytes, que N es distinto de cero, y que es
R ~ 32767. En el ejercicio 3 se trata cmo detectar si se supera este mximo,
y en el ejercicio 4 la deteccin de si M N valen cero.
1) Asignaremos (figura 3.5) a la variable M las direcciones de memoria
8300 y B30 1; a la variable N las direcciones B31 O y B3 11; y se han reserva-
do 8320 y 8.321 para el resultado R.
2d) Al.
Para evidenciar la necesidad de una instruccin de salto, codificaremos en con el
Figura 3.5
assembler R =O+ M+ M+ ... generalizando lo aprendido en el ejercicio 1
Memoria La tigura 3.5, pensada para el ejercicio 2, muestra el paso para llevar una
copia del valor de M al registro 8X (poda haber sido AX, CX, o DX); y el
paso para inicializar en cero el registro AX usado como acumulador acorde con el cero presente en R =O+ M+ M+ ...
A fin de realizar las N sumas necesarias, un sumando es aportado por AX, y el otro por BX, siendo que el resultado
" pisa" el anterior valor existente en el acumulador AX, corno en una calculadora. En la primer suma se hace O+ M.
Una vez realizadas las N sumas en AX quedar el resultado de M x N, el cual debe ir a R como indica la tlecha.-
Con las instrucciones definidas en el ejercicio 1, una secuencia para realizar N sumas repetidas sera:
:s:!e Cero M,Ginzburg- Assembler desde Cero U3-5
MOV BX, [B300] Llevar a BX una cogia de M que est en 8300/1 UCP
SUBAX,AX Acumulador AX en cero, restndolo de s mismo
.. UCP
1
IADDAX,BX Hacer AX+ BX y dejar el resultado en AX
N veces ADD AX, BX !de m
1~
. ADD ADD AX, BX !dem
..
r E MOV [B320}, AX Se asigna el resultado a R, que est en 8320/1 Figura 3.5.a
Tambin se podra haber hecho la secuencia: MOV AX, [B300] , seguida por ADD AX, [B300] repetida N- 1 ~eces, y por
" ltimo MOV [B300], AX, pero sera ms lenta de ejecutar, pues en cada suma hay que acceder a memoria a buscar el dato.
La nica instruccin nueva es SUB AX, AX usada para llevar el registro AX a cero (lo mismo puede hacerse para limpiar
cualquier registro). Tambin existen otras formas de hacerlo.
Como aparece en el programa escrito ms abajo, la instruccin de
salto JNZ Qump ifnot cero) evita escribir N veces ADD AX, BX,
N
permitiendo escribirla una sola vez. Conforme se discutir en la
etapa 2), cuando se ejecute este programa, JNZ posibilitar repetir
N veces la ejecucin de ADD AX, BX escrita una sola vez, por
estar sta dentro de un "lazo" o secuencia corta de instrucciones
que tambin se ejecutar repetida N veces.
=-gura 3.4
2) En la etapa indicada 1) se asignaron direcciones a las variables
y se plantearon todos los movimientos y acciones que debern
DX); y el Cuando el dato a operar no est en memoria sino en un registro de la UCP, y el resultado va tambin a un registro de la UCP, el
, - . 1 + ... modo de direccionamiento se denomina "modo registro".
2
Como se plantea en la Unidad 1 de esta obra, la Unidad de Control (UC) no puede ver ni interpretar el contenido concreto de un
resultado
registro, en este caso CX, por lo que el programador se debe valer de los flags que gener la UAL, en este caso Z, para determinar si el
- M. contenido es o no es cero. Mediante la instruccin de' saltar si Z=O se ordena a la UC que lea el valor de Z, y que se salte si Z=O.
3
El tema de los flags se desarrolla en detalle en la Unidad 1 de esta obra, en el captulo sobre representacin de la informacin.
No confundir el hecho de que un resultado no sea cero, con la indicacin del flag para ese caso: Z=O que significa Zero no (NZ).
Tener presente que cuando un resultado si es cero, el flag es Z=1 (zero si), como se explica en la unidad 1 de esta obra.
U3-6 M.Ginzburg- Assembler desde Cero _f..
Aliado de cada rectngulo del diagrama lgico de la figura 3.6 se indica el resultado a obtener cuando ocurra la primer
ejecucin de las instrucciones del lazo; y abajo los pasos ciue modifican el valor de los flags SZVC.
La secuencia en assembler correspondiente al diagrama de la figura 3.6 ser:
R=
A 0100 FO
xxxx:OlOO MOV ex, [B310] Llevar a ex una copia de N que est en B310 y B311.
xxxx:Ol04 MOV BX, [8300] Llevar a BX una copia de M que est en 8300 y 830 l.
xxxx:0108 SUBAX.AX Poner acumulador AX en cero, restndolo de s mismo .
xxxx:OlOA ADDAX,BX Sumar a AX el valor de M que est en BX.
xxxx:OlOC DEC CX Restar uno a CX (con lo cual pueden cambiar los flags SZVC).
xxxx:OlOD JNZOJOA Si luego de la instruccin anterior Z=O (CX no zero) saltar a 0103
xxxx:OlOF MOV [B320}, AX Llevar a 8320 y 8321 de memoria, una copia del valor de AX.
xxxx:OI 12 INT 20 Instruccin de final de secuencia 1.
Al igual que en el diagrama lgico de la figura 3.6, se debe repetir N veces la instruccin ADD AX, BX. Cada vez que se
realiza esta suma, la instruccin siguiente DEC CX decrementa uno al contenido del registro CX (que inicialmente es N); y
la instruccin JNZ sirve para determinar por un lado si el nmero contenido en CX alcanz o no el valor cero.
Mientras este nmero en CX no sea cero (not zero = NZ), o sea mientras el resultado de restar uno a CX le corresponda
que sea Z=O (condicin de salto de JNZ), se salta a ejecutar otra vez la instruccin ADD AX, BX de in.icio de la
secuencia a repetir. La direccin de esta instruccin a la que se quiere saltar es el nmero que acompaa a JNZ.
En definitiva, la instruccin de saltar si resultado anterior no es cero (JNZ hhhh), ordena saltar a la instruccin de
direccin hhhh slo si Z=O (cero no); caso contrario (Z=l) ordena continuar con la instruccin que sigue a JNZ.
Esta mal escribir debajo de .TNZ la instruccin .TZ hhhh (saltar si Z=l), pues esto ya est contemplado en JNZ.
Tambin puede decirse que JNZ hhhh ordena saltar a la instruccin de direccin hhhh si es verdadero (cierto)
ue Z=O ue si es falso ue Z=O o sea si Z=l ordena continuar con la instruccin ue si a JNZ.
Despus de realizar N veces el lazo, el contenido de CX, que era N, se le habr restado N veces uno. La ltima resta que
z
efectuar la UAL con el valor de CX ser 1 - 1 =O, con lo cual ser Z=l, en correspondencia con CX=O.
En consonancia se habrn realizado N sumas.
A esta altura del proceso, el siguiente salto con la condicin que sea Z=O no se realizar, por no verificarse esa condicin,
y la secuencia continuar con MOV [8320] , AX escrita a continuacin.
Si fuera R = MxN = 3x4, puesto que N=4, se ejecutar 4 veces el lazo, realizndose en cada oportunidad las siguientes
operaciones que ordenarn las instrucciones indicadas, con los resultados en hexadecimal que aparecen.
ADDAX,BX DECCX JNZOJOA
Ira vez: AXf-0+3 AX=3 ex f-4-1 CX=3 (Z=O) Salta a O1OA pues Z=O
2da vez: AXf-3+3 AX=6 ex f- 3-1 CX=2 (Z=O) Salta a O1OA pues Z=O
3ra vez: AXf-6+3 AX=9 ex f- 2-1 CX=l (Z=O) Salta a OlOA pues Z=O
A
4ta vez: AXf-9+3 AX=C ex f-1-1 CX=O (Z=l) No salta, sigue, pues Z=l Xxn::!
JCL~
Esto puede verificarse paso a paso, ejecutando la secuencia anterior en Assembler, mediante el comando T del Debug.
La secuencia en Assembler, como cualquier otra, puede dividirse en las fases de inicializacin, procedimiento, control de xxxx::
xx:n;:
ste y almacenamiento, de acuerdo con las lneas horizontales que aparecen en esa secuencia, planteadas en el diagrama.
xxxx::
Este tipo de secuencia para repetir un procedimiento ser muy utilizada en ejercicios posteriores. XXXI:
xx:n::l
Resulta ilustrativo analizar qu sucede si se cambia el orden de alguna de las instrucciones de la presente secuencia. Xl
Las tres instrucciones de la inicializacin ueden escribirse en cual uier orden, ues no afecta al desarrollo si uiente. xxu;:
Vale la pena sealar que las instrucciones tipo MOV, como no ordenan operaciones en la UAL, no afectan el valor que
tenari los flags SZVC antes de su ejecucin. Slo pueden cambiar el valor de los flags las instrucciones que usan la UAL. A
Si bien luego de ejecutar SUB AX, AX resulta AX=O, y por lo tanto Z=l, como la instruccin siguiente no es una de
salto que pregunte por el valor de Z, sino que es ADD AX, BX, no interesa que sea Z=l.
Qu pasa si se intercambian los lugares de DEC CX y ADD AX, BX ?. Suceder que como ADD AX, BX cambia el
valor de los flags, y JNZ pregunta por el valor de Z luego de la operacin anterior de la UAL (como indica la flecha que
va del flag Z al rombo), se estara preguntando por el valor de Z de dicha suma, en vez del que resulta de DEC CX. el re
Qu sucede si MOV [8320], AX se coloca dentro del lazo?. Si bien el resultado final en R sera correcto, lsecuencia
tardara ms en ejecutarse, pues en cada vuelta habra que acceder a memoria para escribir cada suma parcial.
Esta instruccin no conviene ejecutarla mediante el comando T del Debug, pues puede hacer perder el programa tipeado. Su uso
indica que una secuencia termina, pero que la UCP no se detiene, pues INT 20 es una instruccin que ordena una interrupcin para que
se pase a ejecutar el mdulo del sistema operativo que determina cul es el siguiente programa que se seguir ejecutando a continuacin.
M,Ginzburg- Assembler desde Cero U3-7
Los pasos desarrollados en la figura 3.6 ordenan que una suma (y en general un procedimiento) se repita un nmero N de
veces conocido de antemano. Se los puede hacer corresponder con la siguiente estructura en un lenguaje de alto nivel:
R=O
FOR i= 1 to N
R=R+M
EJERCICIO 3: Mejora del ejercicio 2 usando JO (Jump if overflow), manejo de constantes, empleo de
la instruccin JMP, y uso de etiquetas
A 0100
xxxx:OIOO MOV ex, [8310] Llevar a ex una copia de N que est en 831 O y 8311
xxxx:Ol04 MOV 8X, [8300] Llevar a 8X una copia de M que est en 8300 y 8301
xxxx:Ol08 SUBAX, AX Poner acumulador AX en cero, restndolo de s mismo
xxxx:OIOA ADDAX,BX Sumar a AX el valor de M que est en 8X
xxxx:O!Oe JO 0130 Si de la suma anterior resulta V=1 , saltar a O130 (seguir si V=O)
xxxx:010E DECCX Restar uno a ex (con lo cual puede cambiar ei valor de los flags SZVe)
xxxx:010F JNZ OJOA Si luego de la instruccin anterior es Z=O (eX no zero) saltar a 010A
xxxx:0111 MO V [8320}, AX Llevar a 8320 y 8321 de memoria, un a copia del valor de AX
xxxx:0114 INT20 Instruccin de final
AOI30
xxxx:0130 MOV AX,FFFF Llevar a AX una copia de la constante FFFF
es una de xxxx:0133 MOV [8320], AX Llevar a 8320 y 8321 de memoria, una copia del valor FFFF de AX
xxxx:Ol36 INT20 Instruccin de final
Figura 3.8
BX cambia el
flecha que Entonces la secuencia que empieza en 0100 es la del ejercicio anterior con el agre gado de JO. La instruccin cie saltar si
i:CCX . el resultado anterior gener overflow que en assembler se escribe JO hhhh, ordena saltar a la instruccin de
direccin hhhh slo si V=!; caso contrario (V=O), ordena continuar con la instruccin que sigue a JO.
11. secuencia
En definitiva, si luego de una suma es V=O se ejecuta la secuencia del ejercicio anterior; y si V=1 se pasa a ejecutar la
secuencia que empieza en 130 y termina en 136, conforme al diagrama de la figura 3.7.
JO 0130 ordena saltar (si V=l) a otra instruccin que en este caso no forma parte de la secuencia donde JO se encuentra.
o. Su uso
n para que
Por ello mediante el comando A 0130 hubo que escribir otra secuencia, que empieza con MOV AX, FFFF. Esta ltima
tUlti nuacin. ordena pasar el nmero FFFF hacia AX y MOV [8320] ,AX ordena pasar a memoria lo que est en AX, o sea FFFF.
U3-8 M.Ginzburg- Assembler desde Cero
No existe una instruccin como MOV [B320], FFFF que ordene pasar directamente una constante a memoria. Esto obliga
a pasar primero FFFF a un registro (en este caso AX), y luego de este a memoria.
La direccin 130 fue elegida arbitrariamente, pero dentro de los lmites mximos permitidos para saltar, tema a tratar.
Nueva mejora: se puede obviar la secuencia de 0130 MOV AX, FFFF, si se hace JO 0111 (salto a MOV [B320}, AX).
Dado que con enteros positivos si V=l el resultado errneo siempre es negativo (S=1), al quedar ste en B320/1, su signo
negativo es suficiente para indicar al programa que lo utilizar que ese resultado es errneo, lo cual implica que V=1.
GENERALIZACION:
Instrucciones en modo "inmediato" con un operando que siempre tiene el mismo valor (constante):
Obsrvese la diferencia entre MOV AX, FFFF y MOV AX, [FFFF]. La primera ordena cargar en AX el nmero .fi.iQ
FFFF, mientras que la segunda ordena cargar en AX el nmero que contenga entonces la direccin de memoria FFFF.
MOV AX, FFFF al igual que todas las instrucciones que despus de la coma del medio sigue un nmero (sin corchetes)
se dice que estn en modo "inmediato". Esta denominacin puede explicarse observando el cdigo de mquina de una
instruccin en este modo de direccionamiento. Mediante el comando U del Debug podemos hallar por ejemplo el cdigo
de mquina de la instruccin MOV AX, FFFF (luego de haber escrito la secuencia en assembler donde ella se encuentra):
-u 0130
xxxx:0130 B8FFFF MOV AX,FFFF
xxxx:Ol33 A320B3 MOV [B320] , AX
xxxx:OI36 CD20 INT20
Se observa que en memoria, luego del cdigo de operacin B8 inmediatamente formando parte de la instruccin sigue el
nmero fijo FFFF que pasar a AX cuando B8FFFF se ejecute, de donde proviene el nombre " inmediato" de este modo.
Tambin pertenecen a este modo por ejemplo ADD BX, 2 (sumar siempre 2 al contenido de BX, y el resultado dejarlo en
BX), o MOV AX, O (llevar el nmero cero a AX, lo cual es otra manera de llevar un registro a cero), etc.
En todas las instrucciones en modo inmediato de un programa, un nmero que ellas operarn (cuando sean ejecutadas)
forma parte (en memoria) de estas instrucciones. Cuando cada una de ellas sea ejecutada y se acceda a memoria para
pedirla, dicho nmero llegar a la UCP desde memoria junto con la instruccin, pues el mismo est incluido en ella.
O sea que este tipo de instrucciones proveen a la UCP el valor (constante) de un nmero que intervendr en la operacin
que ordenan, y por lo tanto no ser necesario acceder otra vez a memoria (mayor tiempo de ejecucin) para obtenerlo.
Por consiguiente, los valores fijos (constantes) que operar un programa forman parte en memoria del mismo y estn con
las instrucciones en modo inmediato en lugar de estar en memoria en la zona de datos variables de ese programa, por ser
datos conocidos de antemano se hallan en la zona de instrucciones. Cambiar el valor de uno de estos nmeros fijos, que
se usan tpicamente para incrementar o decrementar el valor de un registro usado como puntero de datos de una lista, o
para dar valores iniciales a variables en registros al comienzo de un programa, implica modificarlo.
EJERCICIO 3 bis: Mejora del ejercicio 3 empleando la instruccin JMP. Uso de etiquetas
El programa de la figura 3.8 puede escribirse con menos instrucciones, como en la figura 3.9 dado que las secuencias que
empiezan en 100 y en 130 tienen las mismas dos ltimas instrucciones en comn. En el diagrama de la figura 3.7 aparece
una lnea grisada en punteado que va desde abajo del paso AX f- FFFF hasta el comienzo del paso [B320!1] f- AX.
O sea que esta lnea indicara saltar sin condicin alguna, de una secuencia a otra (o dentro de una misma secuencia).
As, luego de ejecutar la primer instruccin que est en 0130 se saltara incondicionalmente a ejecutar las dos ltimas
instrucciones de la secuencia que empieza en O100, que son tambin las dos ltimas de la secuencia iniciada en O130.
La instruccin JMP 0111 de salto Uump) de la figura 3.9 Cl!mplir este cometido. No es necesario indicar con un
rectngulo la existencia de la instruccin JMP, aunque en lo sucesivo por razones didcticas lo haremos (ver figura 3.11 ).
En general JMP hhhh ordena saltar incondicionalmente ("si o si") a la instruccin que est en la direccin hhhh, sin
posibilidad de seguir con la instruccin que sigue a JMP en memoria. Equivale a un " GO TO" en lenguajes de alto nivel.
Conforme al uso de JMP, las secuencias de la figura 3.7 con la lnea en punteado quedaran como indica la figura 3.9.
A 0100
xxxx:0100 MOV CX, [B310] MOV CX, [B31 O]
xxxx:0104 MOV BX, [B300] MOV BX, [B300]
xxxx:0108 SUBAX, AX SUBAX, AX
xxxx:OlOA ADDAX,BX OTRA ADD AX, BX
xxxx:010C JO 0130 JO ALFA
xxxx:OlOE DECCX DECCX
xxxx:OlOF JNZ 0/0A JNZ OTRA
xxxx:Olll MOV [B320}, AX BETA MOV [B320}. AX
xxxx:OII4 INT20 INT20
A0130
xxxx:OI30 MOVAX,FFFF ALFA MOV AX, FFFF
xxxx:0133 JMPOlll JMPBETA
Figura3 .9 Figura3 .10
Cero M,Ginzburg- Assembler desde Cero U3-9
La figura 3.10 repite la secuencia de la figura 3.9 pero sin las direcciones. En lugar de stas aparecen las etiquetas
("labels"), como " otra", "beta", "alta" , que son admitidas por otros traductores, pero que no son permiti'!as por el
traductor que provee el Debug. Est claro que dichas etiquetas se usan para indicar direcciones simblicas a las que
apuntan las instrucciones de salto. Para desarrollar programas en Assembler con papel y lpiz sin usar el Debug
usaremos etiquetas, De esta forma podemos independizarnos del Debug y de las direcciones.
EJERCICIO 4: perfeccionamiento del ejercicio 2 teniendo en cuenta que M N pueden valer cero.
En el ejercicio 2 se plante que si N=O el lazo con
la suma se repetira indefinidamente pues nunca
sera CX=O.
Esto ltimo no sucedera en el ejercicio 3, pues al
repetirse cierto nmero de veces la suma, llegara
un punto en que en AX no entrara el resultado
(V=!), y se escribira como resultado (errado)
FFFF en vez de cero, y el programa terminara.
Ahora completaremos el ejercicio 2, para que si M
N valgan cero inmediatamente sea R=O, sin
efectuar ninguna suma.
MOV CX, [8310]
MOV BX, [B300]
e modo. SUBAX,AX
arlo en SUB CX,O
JZ BETA
SUB BX,O
JZ BETA
OTRA ADD AX, BX
JO OVER
DECCX
JNZ OTRA
BETA MOV [B320}, AX
INT20 .
Si se escribe con el Debug JZ BETA (con salto hacia adelante), el nmero con la direccin que va en vez d BETA no se
conoce, pues an no se ha escrito MOV [B320], AX con esa direccin (a diferencia de un salto hacia atrs, donde esa
direccin se ve en pantalla). En el uso del Debug que acompaa al ejercicio 13 se indica cmo proceder en esos casos.
Esto es, puesto que el rombo que representa una instruccin de salto condicional, solamente permite saltar por uno solo
de sus vrtices laterales; y siendo que su vrtice inferior est ligado necesariamente a la continuacin de la secuencia, sta
se contina con una instruccin que ordena saltar incondicionalmente, "si o si", a otra instruccin.
En la figura 3.12 el salto condicional no se realiza sobre la misma secuencia, como en la fig. 3.6, sino que se salta a otra
secuencia, compuesta por dos instrucciones. Con el comando A 0130 del Debug esta secuencia en la fig. 3.13 se escribe
a arte, a artir de la direccin 0130, ele ida arbitrariamente, ero ue no su era el valor lmite ermitido ara un salto.
Por lo tanto, el "precio" de elegir el valor contrario de un flag, es una destructuracin del diagrama lgico, por la
aparicin de una secuencia nueva, innecesaria, con la consiguiente complicacin de la codificacin con el Debug.
En general cuando se elige la condicin de salto y aparece JMP, se debe probar qu pasa si se elige la condicin contraria.
Figura 3.12
Instruccin de salto condicional que sigue a una de resta para determinar si minuendo > < sustraendo
1) PARA NMEROS ENTEROS (POSITIVOS O NEGATIVOS)
Cuando en un papel restamos dos nmeros enteros A- B, sabemos que si el signo del resultado es positivo (flag S=O) es
A 2:: B; y si es negativo (S=1) es A< B. Esto mismo puede decirse si dicho resultado es correcto por haber sido V=O.
En un computador el signo solo no es suficiente para esta determinacin. Conforme se trat en la Unidad 1 de esta obra,
el resultado de una suma o resta de enteros puede ser errneo por no poder representarse en el formato (nmero de bits)
con que opera la UAL, lo cual denominamos overflow (V=1). Y si esto ocurre, el signo del resultado, si hubiese sido
V=O, es contrario al signo del resultado errneo cuando es V= l. Vale decir que aunque el resultado est mal por ser V=1,
igualmente se puede determinar el signo que ste hubiera tenido, aunque no el valor completo del resultado.
Pero basta con conocer el signo del resultado de una resta de enteros para poder afirmar que A 2:: B A< B.
Resumiendo lo anterior, luego de efectuar una resta de enteros A- B, el valor de los flags S y V permite determinar:
Si S=O y V=O est bien que sea S=O . y por lo tanto se deduce que A 2:: B
Si S=1 y V=O est bien que sea S=l y por lo tanto se deduce que A < B
Si S=O y V=! debi haber sido S=1 y por lo tanto se deduce que A < B
Si S=l y V=l debi haber sido S=O y por lo tanto se deduce que A 2:: B
De los 4 casos anteriores resulta ue:
Igualmente. para saber si A= B debe hacerse antes A - B para conocer Z. En el ejercicio 4 usamos JZ para ver si el con-
a repetir tenido de CX era igual o no a cero, para lo cual antes de JZ que pregunta por el valor del flag Z, se hizo la resta CX- O.
otra, ni
A continuacin se tratan todos los casos posibles para saber como es A respecto de B, siendo A y B enteros.
r - - - - - , Resta para hallar
L---,-__J szvc
(A=B) JG JGE
JZ
Sulta Jump if Greater
Jump ifZero Jump if Greater
or Equal
JNZ JL JLE
Jump ifLess Jwnp ifLess
orEqual
Figura 3.15
~ los
-que es Estos diagramas tambin sirven de recordatorio' que si no se cumple la condicin planteada, siempre debajo del rombo
debe seguir otra instruccin, o sea que no se puede saltar. Esto ltimo slo es posible si la siguiente es JMP (ejercicio 5).
sie:ue a Si bien cuando se ejecuta una instruccin de salto condicional la UC lee en el registro de estado el valor de uno o varios
~ 0 101). flags, en Assembler la condicin puede establecerse con dos o tres letras fciles de recordar (ya hemos usado JZ, JNZ,
JO), para preguntar si un nmero es mayor, igual, o menor que otro, como aparecen aliado de los rombos en la fig. 3.15.
U3-12 M.Ginzburg - Assembler desde Cero
Esto permite desentenderse de los flags, especialmente si la combinacin de flags es compleja, y es factible poder codifi-
car una instruccin de salto de dos o ms maneras (ver mnemnicas de instrucciones al final de esta obra).
Por ejemplo, la instruccin JZ Uump if Z=l) usada en el ejercicio 4 es equivalente aJE (Jump if equal) si se piensa en la
instruccin anterior de resta, pues si el resultado de sta es cero (Z=I ), implica que los nmeros restados son iguales.
2) PARA NM EROS NATURALES
Estos nmeros son usados para cuantificar magnitudes (litros, metros, .... ) o para codificar caracteres en ASCII, etc.
comparten con los enteros el flag Z en las instrucciones JZ y JNZ, pues el cero se codifica igual para enteros o naturales.
Con los naturales no se pueden usar los flags S y V, usados para enteros, so pena de resultados con errores inadmisibles.
El nico flag que es propio de nmeros naturales es el flag C. Su significado para una resta A- B de naturales con n bits,
es que si C=O se "pedira O prestado" si la resta continuara con n+ 1 bits, lo cual implica que A~ B; y si C=l se "pedira
1 prestado" en dicha resta, lo cual implica que A< B.
Este tema se desarroll en la Unidad 1 de esta obra, y se sistematiza en las siguientes porciones de diagramas lgicos:
JAE
Jump if Above
or Equal
JNZ JB JBE
Jump ifLess
or Equal
Figura 3.16
Por ejemplo (figura central superior), si al hacer A- B resulta C=O implica que en esa resta de naturales se pidi "O prestado" por lo que
A~ B, y si adems Z=O implica que el resultado no es cero, o sea que no puede ser A= B (lo cual ocurrira si C=O y Z=l), por lo que en
definitiva es A> B. Si al hacer A- B resulta C=l , implica que en esa resta se pidi"! prestado", por lo que A< B.
EJERCICIO 6
Codificar en Assembler una secuencia para realizar la suma R = M+ N de dos nmeros enteros de 32 bits
("long integers"), siendo que con ADD AX, [xxxx] slo pueden sumarse en la UAL dos nmeros de 16 bits.
Para de poder visualizar y concretar el ejercicio, esta vez supondremos que los datos tipeados son M= - 2.650.000d y
N= 3.250.876d . En lo que sigue se indican los valores de las variables M y N representados con bit de signo (tema visto
en la Unidad 1 de esta obra), sus direcciones, y la suma en cuestin planteada en 32 bits, convertida luego a hexa. ALE
cd~
M
+ 111111111IOI01I Ih oo1ooooo11100oo + FFD790 7 O
OOOOOOOOOOllOOOf t001101010111 100 00 319ABC
R=M+N= 100000000000010010010101100101100 100 092B 2C
J_ t
szvc szvc
0001 oo 1 1
Suponemos una UAL que slo puede sumar dos nmeros de 16 bits como la del 80286. Con esta UAL y
mediante instrucciones simularemos una UAL de 32 bits, dividiendo la suma en dos mitades de 16 bits,
lo cual implica ms tiempo que si la suma se realiza de una sola vez con instrucciones para operar 32
bits en una UAL apropiada. Para cada mitad se dan los valores de los flags SZVC que la UAL generara.
Primero sumaremos las mitades de M y N en negrita, suma que puede arrojar o no un transporte hacia la
otra mitad. Como los binarios enteros se suman como naturales, el flag C es propio de estos ltimos.
Dado que en una suma con 16 bits el valor del flag C es "lo que me llevo" si la suma contina en un bit
17, usaremos el flag C para memorizar si me llevo 1 O hacia la primer columna de la segunda mitad a sumar. En este
ejemplo se indica en grisado dicha columna, y la mitad en negrita luego de sumarse arrojar C=l ("me llevo 1") hacia la
segunda mitad.
En definitiva lo que haremos es que si C=l, sumaremos uno en la suma de la segunda mitad, y si C=O, no sumamos uno.
Desarrollaremos este ejercicio de tres maneras diferentes, siendo que los tres primeros pasos son comunes a todas ellas.
De la forma conocida se sumar primero los 16 bits m:nos significativos de M (arbitrariamente supuestos ms arriba en
las direcciones 2000/1) con los de N (en 2008/9), y se almacenarn en 2010/11 los 16 bits del resultado parcial obtenido,
que si se ejecuta el programa, en hexa seran 2C y 2B respectivamente, que aparecen en la suma realizada antes en hexa.
A continuacin plantearemos la suma de la segunda mitad de M y N de tres formas distintas:
p esde Cero M,Ginzburg- Assembler desde Cero U3-13
er codifi-
lgicos:
;wl.a hallar
~)
Salta
Figura 3.17.a Figura 3.17.b Figura 3.17.(b)
Solucin a): conforme a la figura 3.17.a, luego de [2010/ 11] f-AX se pregunta por rl valor del flag C (generado por la
UAL luego de AX f.- AX + [2008/9] y que no cambia luego del paso [2010/ 11] f.- AX, en el cual la UAL no opera).
"""?'2hallar
Si C=l (como ocurrira con estos valores de M y N), mediante AX f.- 1 se debe por\tr w uno a AX ("pisando" a 2B2C
resultado del paso AX f.- AX + [2008/9]). Luego se debe saltar incondicionalmente al paso AX f.- AX + [2002/3] que en
este caso sera AX f.- 1+ FFD7 = FFD8, para sumar el uno de acarreo de la posicin en grisado de la suma binaria citada.
(MB)
Si C=O se debe poner AX en cero, mediante AX f.- O, luego de lo cual ahora sera AX f.- AX + [2002/3] = O+ [2002/3].
Salta
Sigue AX f.- AX + [2009/A] para sumar al registro AX los 16 bits superiores de N, y luego [2012113] f.- AX para alma-
cenar el resultado de esta suma (0009 .:n este caso) en 2012113. Estos dos pasos sern comunes a las 3 soluciones.
La codificacin correspondiente al diagrama lgico de la figura 3.17.a resulta:
Codificaremos en Assembler la secuencia correspondiente a los pasos del diagrama, con las siguientes instrucciones:
MOV AX, [2000] Llevar a AX una copia del dato que est en memoria en 2000 y 2001
ADD AX, [2008] Sumar a AX una copia del dato que est en memoria en 2008 y 2009
MOV [2010], AX Transferir a 2010 y 2011 de memoria una copia del contenido de AX
JC ALFA Si C= 1 saltar a la instruccin que est en ALFA .
MOVAX,O Si C=O poner en cero el registro AX
de 32 bits SUMA ADD AX, [2002) Sumar al valor (1 O) de AX una copia del dato que est en 2002 y 2003
ADD AX, [200A) Sumar a AX copia del dato que est en 200A y 200B
MOV [2012], AX Transferir a 2012 y 2013 de memoria una copia del contenido de AX
INT20 Finalizar
(tema visto
ALFA MOV AX, 1 Como es C=l, poner en uno el registro AX
JMP SUMA Saltar incondicionalmente a la instruccin que est en SUMA
Solucin b): conforme a la figura 3.17.b, luego de [2010/11] f-AX sigue AX f.- [20v2J para llevar hacia AX una copia
de la mitad superior de M (para estos datos FFD7) "pisando" la suma parcial anterior existente en AX (2B2C). Como este
paso, como el anterior ([2010/11] f-AX) tampoco cambia el valor del flag C, pues en l no interviene la UAL, se pregun-
ta en el paso siguiente por el valor de C. Si C=O no se suma uno al valor de AX, se "puentea" este paso, y se salta a los
dos ltimos pasos de de la solucin a). Si C=l (o sea si no se cumple la condicin C=O) se debe sumar uno (de acarreo a
la segunda mitad de la suma) a AX con el paso AX f.- AX + 1 (en este caso FFD7 + 1). Luego siguen los dos ltimos
pasos de la solucin a). Las instrucciones que se corresponden con los pasos del diagrama de la figura 3. 17.b son:
MOV AX, [2000] Llevar a AX una copia del dato que est en memoria en 2000 y 2001
ADD AX, (2008) Sumar a AX una copia del dato que est en memoria en 2008 y 2009
} MOV [2010), AX
MOV AX, [2002]
JNC SUMA
ADDAX, 1
Transferir a 201 O y 2011 de memoria una copia del contenido de AX
Llevar a AX una copia del dato que est en memoria en 2002 y 2003
Si C=O saltar a la instruccin que est en SUMA
Si C=l sumar uno al registro AX
. En este SUMA ADD AX, [200A) Sumar al valor de AX una copia del dato que est en 200A y 200B
1~) hacia la MOV [201 2], AX Transferir a 2012 y 2013 de memoria una copia del contenido de AX
INT20 Finalizar
Variante menos efectiva de la solucin b) segn el diagrama lgico de la figura 3.17 .(b)
es todas ellas.
Veremos cmo se ~odifica la solucin b) si en el rombo se plantea C=l en vez de C=O como aparece en la figura
lE :::1s arriba en
3. 17 .(b). Entonces si C= 1 se debe saltar a otra secuencia con el paso AX f.- AX + 1, seguido por un salto incondicional a
"al obtenido,
AX f.- AX + [2009/A], suma que sigue al rombo si C=O.
en hexa.
U3-14 M.Ginzburg- Assembler desde Cero
MOV AX, [2000] Llevar a AX una copia del dato que est en memoria en 2000 y 2001
ADD AX, (2008] Sumar a AX una copia del dato que est en memoria en 2008 y 2009
MOV [2010], AX Transferir a 201 O y 2011 de memoria una copia del contenido de AX
MOV AX, (2002] Llevar a AX una copia del dato que est en memoria en 2002 y 2003
JC ALFA Si C=l saltar a la instruccin que est en SUMA
SUMA ADD AX, [200A] Si C=O sumar al valor de AX una copia del dato que est en 200A y 200B
MOV [2012], AX Transferir a 2012 y 2013 de memoria una copia del contenido de AX
INT20 Finalizar
ALFA ADD AX, 1 Si C=l sumar uno al registro AX
JMP SUMA Saltar incondicionalmente a la instruccin que est en SUMA
Resulta as que el hecho de haber elegido en un rombo como condicin de salto la contraria a la de la solucin b) trajo
aparejado la aparicin de una nueva sl!cuencia y un salto incondicional. Por lo tanto, si luego de elegir una condicin de
salto aparece una nueva secuencia que termina en un salto incondicional hacia la parte inferior de dicho rombo, esta
secuencia puede evitarse si se cambia en el rombo a la condicin contraria, con lo cual como en la solucin b) los pasos
que estaban en la secuencia nueva pasan a una secuencia nica, y se aprovecha la instruccin de salto para evitar JMP.
Solucin e): no emplea instruccin de salto. Las 4 primeras instrucciones son las mismas que las de la solucin b), pero
no se pregunta por el valor del flag C, dado que la instruccin. ADC ("Add with Carry ") es distinta de ADD, pues ordena
sumar a AX el contenido de dos posiciones consecutivas de memoria (200A y 200B) ms el ltimo valor que tena el
flag C antes de ejecutar la instruccin, o sea que automticamente incorpora a la suma el valor O 1 del dicho acarreo.
MOV AX, [2000] Llevar a AX una copia del dato que est en memoria en 2000 y 2001
ADD AX, [2008] Sumar a AX una copia del dato que est en memoria en 2008 y 2009
MOV [2010], AX Transferir a 201 O y 2011 de memoria una copia del contenido de AX
MOV AX, [2002] Llevar a AX una copia del dato que est en memoria en 2002 y 2003
ADC AX, [200A) Sumar a AX copia del dato que est en 200A y 200B ms Carry anterior
MOV [2012], AX Transferir a 2012 y 2013 de memoria una copia del contenido de AX
INT20
Con cualquiera de las soluciones planteadas se duplica por software el formato con que opera una UAL de 16 bits
(hardware) en una suma multibyte.
EJERCICIO 7: Lectura y escritura de una sucesin de datos consecutivos en memoria (lista o vector)
En memoria se tiene un vector conformado por una lista de n elementos NI , N2, N3 . . . Nn, que son.nmeros
de 2 bytes cada uno ordenados sucesivamente en posiciones consecutivas de memoria. La lista (figura 3.18)
comienza en la direccin 1000, siendo que en 1500 se da la cantidad n de elementos de la lista. Esta cantidad n en
todos los ejercicios se asumir siempre inayor que uno, para evitar su verificacin con la metodologa del ejercicio 4.
Se pide copiar la lista a partir de la direccin 2000.
La figura 3.18 indica (para NI) los dos movimientos que permiten pasar cada elemento de una lista a la otra, usando AX
como registro intermediario. Se han dibujado las dos listas a la par, siendo que en memoria estn una debajo de otra.
Con las instrucciones que conocemos hasta ahora, por un lado no existen instrucciones como MOV [2000], [ 1000] para el
pasaje de una copia de NI hacia la otra lista. Para tal fin (figura 3.18) primero se debe pasar una copia de N 1 hacia AX,
usando MOV AX, [1000]; y luego una copia de AX hacia 2000/1, mediante MOV [2000], AX.
Por otra parte, si con esas instrucciones codificaramos los pasos para pasar los n elementos que estn en memoria en la
primer lista hacia la otra, se tendra que escribir n veces cada par de instrucciones MOV:
MOV AX, [1000] Una copia de NI que est en 1000/ 1 pasa a AX
MOV [2000), AX Una copia de N 1 que est en AX pasa a 2000/1 (primer par de instrucciones MOV)
MOV AX, [1002] Una copia de N2 que est en 1002/3 pasa a AX
MOV [2002], AX Una copia de N2 que est en AX pasa a 2002/3 (segundo par de instrucciones MOV)
En el corchete de cada instruccin MOV AX, [lhhh] hay un nmero de valor fu.Q (lhhh), que es la direccin de una celda
de memoria. Lo mismo en MOV [2hhh], AX. Este nmero forma parte de la instruccin. As, el cdigo de mquina de
MOV AX, [1000] en hexa es: Al 0010 (0010 codifica a 1000).
Con el fin de evitar como en este caso repetir n veces la escritura de instrucciones, para localizar datos que estn en
direcciones consecutivas de memoria se usan los registros SI. DI y BX definidos en la figura l.
Los registros SI ("source indexation") y DI ("destination indexation") son los que se eligen en primer lugar como punte-
ros, y como BX tambin puede usarse como acumulador, conviene utilizarlo slo en el caso que haya tres listas a puntear.
e Cero M,Ginzburg- Assembler desde Cero U3-15
En correspondencia con el uso de estos registros para direccionar celdas de memoria, existen instrucciones para poner
entre corchetes el nombre del registro que proveer la direccin de memoria a acceder, como ser MOV AX, [SI].
Como siempre los corchetes simbolizan memoria, y la direccin a acceder es el valor que en este caso tiene SI.
MOV AX, [SI] ordena pasar a AX una copia del nmero contenido en la celda cuya direccin indica (apunta)'-entre cor-
chetes el registro SI, y tambin una copia del nmero contenido en la celda siguiente, pues el registro AX es de 16 bits.
Si al registro SI se le da el valor inicial 1000 mediante la instruccin en modo inmediato MOV SI, 1000, resultar
SI=IOOO; y si despus se ejecuta MOV AX, [SI), ser equivalente a ejecutar MOV AX, [1 000) , para que Ni pase a AX.
Dado que el elemento siguiente a pasar est en 1002, este valor se halla sumando 2 a SI (SI ~ SI +2 = 1000 + 2 = 1002),
y as indexando en 2 a SI se pueden determinar las direcciones (1004, 1006, ... ), de los siguientes elementos a pasar.
Ahora si se vuelve a ejecutar MOV AX, [SI) , ser equivalente a ejecutar MOV AX, [1002] , como se necesita.
Igualmente, si a DI se le da el valor inicial2000 mediante MOV DI, 2000, las sucesivas ejecuciones de MOV [DI) , AX
seguidas de sumarle 2 a DI, son equivalentes a MOV [2000], AX ; MOV [2002], AX ; MOV [2004], AX , etc.
Entonces, si repetidamente se ejecutan n veces 4 instrucciones: MOV AX, [SI) y MOV [DI), AX seguidas por el par de
sumas ADD SI, 2 y ADD DI, 2, se habrn copiado todos los elementos de una lista en la otra.
Para lograr la repeticin de estos 4 pasos, en el diagrama lgico de la figura 3.18 que luego desarrollaremos se arm un
lazo semejante al de la figura 3.6.
Sistematizando, hasta ahora hemos usado los registros AX, BX, CX, DX para contener valores de datos o resultados, y a
partir de este ejercicio usaremos SI, DI y BX para contener nmeros que son direcciones de datos o resultados. Los regis-
tros, al igual que las posiciones de memoria, se corresponden con variables, cuyo valor es el contenido de los mismos.
Las instrucciones del tipo ADD AX, [SI]; MOV AX, [BX]; MOV [DI], AX; etc., corresponden al modo de direc-
cionamiento indirecto por registro. Esto es, la direccin de una celda de memoria se da indirectamente a travs de un
registro, como SI, DI, o BX, que son los nicos registros que pueden aparecer entre corchetes.
Estos registros sern indexados con instrucciones, a diferencia del IP que es actualizado automticamente por la UC.
Las instrucciones en modo indirecto por registro permiten recorrer uno tras otro a datos contenidos en posiciones
sucesivas de memoria, como es el caso de una lista o vector.
UCP
, ., 16 bits
1 ector)
mando AX
:1:10ria en la
DY)
V)
Figura 3.18
El diagrama de la figura 3.18 tiene la misma concepcin que el de la figura 3.6 para repetir un procedimiento y se basa en
!OV) el esquema que lo acompaa. En este caso en cada vuelta (ciclo) del lazo se copia un nuevo elemento de una lista a otra.
una celda En el primer paso (JI) de la inicializacin, en el esquema y en el diagrama lgico se eligi ordenar que una copia del
, uina de nmero n que est en 1500 pase a los 8 bits de CL (mitad inferior de CX que puede contener hasta 11111111 = 255).
Esta asignacin del nmero n al registro CL la efectuaremos tambin en ejercicios siguientes, por si hace falta usar CH.
rpe estn en Al igual que N del ejercicio 2, el valor de n es el nmero de veces que se repetir el lazo.
Siguen los pasos 2 y 3 con la asignacin de los valores 1000 a SI, y 2000 a DI.
o punte- El procedimiento (14, 15, 16 e 17) son los 4 pasos antes planteados. Comienza con 14, que en el primer ciclo ordena que una
-,.\)mtre. copia de NI, que est en 100011, pase a AX. En este ciclo el paso 5 luego ordena que NI pase de AX hacia 2000/1.
U3-16 M.Ginzburg - Assembler desde Cero
Luego de los pasos 6 y 7 los registros SI y DI quedan apuntando a 1002 y 2002 direcciones necesarias para copiar a N2.
Con DI ~ DI + 2 termina el procedimiento a repetir, y como en el ejercicio 2 se resta uno al contador regresivo de ciclos
(CL ~ CL- 1), y se pregunta al final de cada ciclo si Z=O o sea si CL:;tO. De ser as se vuelve a repetir el ciclo para que
el elemento si uiente seco ie de una lista a la otra. En caso de ser Z=1 (CL=O) se finaliza el ro rama.
Esta forma de repetir ciclos para operar elementos de una lista ser usada en los ejercicios que traten este tipo de de datos.
Como direccin inicial de la lista y la cantidad n de elementos son datos, no hace falta dar la direccin final de la misma.
A continuacin se dan las instrucciones correspondientes al diagrama lgico de la figura 3.18.
MOV CL, [1500] Llevar a CL una copia de n que est en 1500.
MOV SI, 1000 Llevar a SI el valor 1000.
MOV DI, 2000 Llevar a DI el valor 2000.
OTRO MOV AX, [SI] Llevar hacia AX una copia de un nmero de 2 bytes de la lista apuntado por SI.
MOV[DI],AX Llevar hacia la direccin apuntada por DI el nmero de 2 bytes contenido en AX.
ADD SI, 2 Sumar 2 al contenido de SI. "
ADDDI, 2 Sumar 2 al contenido de DI.
DECCL Restarle uno a CL para que cambien los flags SZVC.
JNZ OTRO Mientras Z=O volver al procedimiento que empieza en OTRO .
INT20 Fin de secuencia.
Es importante manejar correctamente el uso de los corchetes. Si en vez de MOV CL, [1500] escribimos MOV CL, 1500
al registro CL ir el valor 1500 en vez de ir n. Y si en lugar de MOV SI, 1000 se escribe MOV SI, [1000] , hacia el
registro SI ir el elemento NI en vez de 1000.
EJERCICIO 8: Sumar los elementos de una lista (vector)
En un lenguaje de alto nivel con variable "enteros" se escribi la sentencia: R(n) = N(l) + N(2) + N(3) + ... + N(n)
que ordena sumar los valores (de 2 bytes cada uno) de los n elementos de un vector, localizados en celdas
consecutivas de memoria, conformando una lista a partir de la direccin 1000 (figura 3 .19).
La cantidad n de nmeros de la lista est en la direccin 1500. La variable R t:st en las direcciones 200011.
Si al sumar un nuevo nmero de la lista se produce overflow, no seguir sumando y slo enviar a la direccin
2002 la cantidad k de elementos que faltaban sumar. En caso de que se sumen los n nmeros, enviar aRel
resultdo y escribir en 2002 el valor de k que en ese caso ser cero, como indicativo de resultado correcto.
Codificar en Assembler un programa que obtenga los resultados requeridos. o -
El diagrama de la figura 3.19 tiene la misma estructura que el de las figuras 3.6 y 3.18 para repetir un procedimiento y se
basa en el esquema que lo acompaa. En este caso en cada vuelta (ciclo) del lazo se suma un nuevo elemento de la lista.
Como siempre a la derecha de los rectngulos se indican los valores resultantes correspondientes a la primera vuelta.
En el ejercicio 2 se codific R =O+ M+ M+ .. (N sumas); y ahora se codificar: R =O+ NI+ N2 + N3 + . . (n sumas).
El registro SI ir apuntando (mientras no haya overflow) al elemento siguiente a sumar. Para tal fin (Il) a SI se le di el
valor 1000, luego (12) el nmero n se llev hacia CL, y despus (I3) AX fue llevado a cero (pues R =O+ NI + ... ).
El procedimiento comienza (I4) con AX ~ AX + [SI] que ordena sumar a AX una copia de los 2 bytes del nmero que
est en la direccin indicada entre corchetes por SI; y dejar el resultado en AX. En Assembler es ADD AX, [SI].
En el primer ciclo se tendra AX =O+ NI =NI. Le sigue la pregunta (15) si V=1. Si es as (fig. 3.19), se salta a la instruc-
cin (I9) que ordena copiar el valor de CL (que indica la cantidad k de elementos que falta sumar) en la direccin 2002,
para despus finalizar la ejecucin del programa, sin guardar lo acumulado en AX.
Si no hay overflow (V=O) prosigue el ciclo (I6) sumando 2 a SI, que en el primer ciclo quedara en 1002, apuntando a N2.
Sigue el control de las veces que se ejecutar el lazo: se le resta uno a CL (17), y se pregunta si Z=O (18). Mientras as sea,
se salta a ejecutar otra vez al comienzo del ciclo donde est la instruccin (14) que suma el elemento siguiente.
Cuando sea Z=l (CL=O) si bien SI est apuntando a un supuesto elemento n+I, ste no se suma, dado que la secuencia
contina con dos almacenamientos: primero se guarda (18) una copia en 2000/1 (R) la suma total que est en AX, y luego
(19) se guarda en 2002 una copia del valor k de CL, que ahora debe ser cero, indicacin de que el valor de R es correcto.
En definitiva, si k= O el resultado presente en 2000/1 est bien, y si k :;t O el mismo es errado por que antes fue V=!.
Debe consignarse que en el ejercicio 2 se oper con enteros positivos, y si era V=! se escriba como resultado un nmero
negativo, que empezaba con uno, lo cual indicaba que estaba mal, pues ello no es posible. En este caso como el resultado
puede ser positivo o negativo, no puede hacerse lo mismo si V= 1, por lo que se opt por la indicacin que provee CL.
La secuencia correspondiente al diagrama lgico de la figura 3.19 sigue a continuacin del mismo. En dicho diagrama
aparecen los resultados obtenidos luego de cada paso, y en el lazo los correspondientes a la primer vuelta. Este diagrama
finaliza de forma semejante al del ejercicio anterior, y que se repetir en todos los ejercicios con listas.
Se debe tener presente que ADD AX, [SI] no es lo mismo que ADD AX, SI, dado que la primera es de modo indirecto
por registro, y la segunda es de modo registro, y ordena sumar al con ten id-:~ de AX una copia del registro SI, dejando el
resultado en AX.
e Cero M,Ginzburg- Assembler desde Cero U3-17
CL ...- [1500]
s)
r SI.
en AX.
'
1
CL, 1500
, hacia el
1
l V=1 ]=R
o
1CL=O
___ + N(n) 1
en celdas
'@ Figura3.19
200011.
eccin MOV SI, 1000 SI apunta al comienzo de la lista de datos
aRel MOV CL, [1500] Carga en CL (mitad inferior de CX) la cantidad n que est en 1500
::ecro. MOV AX,O Lleva AX a cero
OTRO ADD AX, [SI] Suma a AX el nmero de la lista apuntado por SI
JO ALFA Si hay overflow saltar a ALFA
ADD SI, 2 Suma 2 a SI para que apunte al elemento siguiente de la lista
DEC CL Decrementa CL
JNZ OTRO Mientras Z sea O, volver a OTRO
MOV [2000}, AX Carga en 2000 y 2001 el resultado de la suma
sumas).
ALFA MOV [2002}, CL Carga en 2002 el contenido k de CL
s:: le di el
INT20 Fin
- --1 + ... ).
EJERCICIO 9: bsqueda en lista usando la instruccin comparacin, con resta sin asignacin de resultado
A partir de la direccin 2000 se tiene una lista de caracteres codificados en ASCII (figura 3.20), siendo que su
nmero n est en la direccin 1500. Encontrar el nmero k de veces que en la lista se encuentra e letra E y dicho
nmero guardarlo en la direccin 3000. Asimismo, cada vez que se encuentra una E, indicar su cdigo ASCII
a N2. (45h) en una segunda lista que empieza en 2000, seguido de la direccin donde se encontraba dicha letra E.
~as sea,
En el esquema y diagrama de las figuras 3.20 y 3.21 primero se inicializan los registros. El registro CL con el nmero n
de caracteres (11); el registro SI con la direccin inicial (2000) de la lista de caracteres ASCII (I2); el registro DI con la di-
secuencia
"-.X, y luego reccin inicial (3000) de la segunda lista (I3), que guarda las direcciones donde se encontr una letra E; y el registro AH
(mitad superior de AX) se pone a cero (I4), pues va a ser usado como contador de las veces que se encontr una letra E.
Luego (IS), una copia del valor x de la lista apuntado por SI es llevado hacia AL (mitad inferior de AX, pues AX tiene 16
bits y cada dato x es un caracter ASCII de 8 bits). Si se usara AX iran hacia AH y AL dos caracteres consecutivos.
No hace falta llevar AL a cero, pues ntf se usa como acumulador, y cada MOV que enva un valor a AL "pisa" el anterior.
Entonces usaremos AL para enviarle cada uno de los n valores de la lista, paso previo a la resta AL- 45 en la UAL
En la primer vuelta en AL queda el valor x apuntado por SI = 1000.
De forma anloga al ejercicio 4, para saber si una variable tiene un valor determinado, en este caso si x vale 45, primero
se ordena hacer AL- 45 (I6), con lo cual tomarn valor los flags SZVC.
Hasta ahora en todas las instrucciones de resta, su resultado "pisaba" el valor que antes de ella tena el acumulador.
Si AL= x = 45, y se ordena la resta con asignacin AL ~ AL- 45, sta sera 45- 45 =O, resultando AL= O 1
- - directo
Entonces si se quiere enviar desde AL el 45 a la otra lista, como pide el ejercicio, en vez del 45 se enviara un cero.
' ando el
Inclusive en el ejercicio 4 como primer paso de la comparacin tambin se us la resta con asignacin ex ~ ex- O, i~~o como se
resta cero, el resultado que quedar en ex ser el mismo que el existente antes de esa resta.
03-18 M.Ginzburg- Assembler desde Cero
A fin de evitar usar ms instrucciones para salvar a 45 que est en AL antes que el resultado de la resta lo destruya, existe
la resta sin asignacin de resultado, que se usa como primer paso para determinar si un valor es igual. mayor o menor que
otro. Este tipo de resta para comparar, se denomina no muy felizmente "comparacin" (operacin CMP en Assembler).
O sea que una comparacin es una resta, pero sin asignacin, una resta en la que no interesa el resultado, y que solo sirve
para que la UAL genere valores de los flags SZVC correspondientes a dicha resta, sin afectar los nmeros que se operan.
Por tal motivo en el diagrama de la figura 3.21 en el paso AL - 45 se indica que AL sigue conteniendo el valor de x.
Decimos "no muy felizmente" por que en realidad la comparacin se determina con la instruccin de salto que siempre
sigue a la resta sin asignacin, que en este caso (17) ordena preguntar por el valor de Z, pues se necesita saber si AL= 45
En otros casos luego de dicha resta se pregunta por otros flags (figs 15 y 16) para saber si uno es mayor o menor que otro.
Si Z=l implica que el resultado es cero, y por lo tanto x = 45, o sea que x ~el cdigo ASCII de la letra E; y por lo tanto,
como se pide, una copia de x que est en AL debe ser llevada (18) a la direccin de la lista apuntada por DI=2000.
De ser Z=O, ser x i= 45, por lo que el valor de x no es el ASCII de la E, y como se tratar, hay que pedir otro caracter.
Siguiendo con Z=l, como luego de 18 el valor x = 45 ocup la celda 2000 apuntada por DI, hay que sumar uno a DI (19)
para que en el paso 110 que ordena que una copia del contenido de SI que sigue apuntando a la direccin (1 000) donde se
localiz X.= 45, se guarde en la segunda lista luego de dicho 45 . De no ser as, el 1000 se escribira en 2000 y 2001,
pisando el45. Entonces haciendo DI ('-DI+ 1 = 2000 + 1 = 2001, se escribir en 2001 y 2001 la direccin 1000.
Como luego de escribir las celdas 2001 y 2002, DI sigue en 2001, se debe ordenar (1! 1) sumarle 2, de modo que apunte 2
celdas ms abajo (a 2003), por si se encuentra otro cdigo x = 45 en la lista de los n caracteres, como se supone luego.
Conforme a lo pedido, como se encontr el cdigo 45 de una letra E, slo falta ordenar sumar 1 al contador del nmero
de veces k que se hall E, el cual (inicialmente en cero) est en AH. Por lo tanto (112), en cada oportunidad que se
encuentra un 45 se hace AH('- AH+ 1 (O + 1 = 1, la primea vez que se localiza 45).
Habiendo realizado todos los pasos solicitados cada vez que se localiza el 45, con 113 se ordena CL ('- CL- 1 = n- 1, pa-
ra registrar que faltan analizar n- 1 cdigos de caracteres de la lista. Mientras el resultado de esta resta no sea cero (Z=O),
se debe volver al paso 15 para leer el siguiente carcter de la lista y pasarlo al registro AL.
UCP
1
1
1
r
r
r
r
r
r
1
1
\ Sl~~gg~ tfi)J
..__,,
1
\ 1002 1
1
1 , 1003 x __ /
/
\ \ 1004 45- /
1~
/
\ 5
1~ / "
ICL=O "'
1
1
, , "'
1
1
m~~~~gg!
\\2003
\ 2004
\ 5
~Q006
' '
300'b Figura 3.20
Figura 3.21
En el paso 17 el que se pregunta por el valor de Z, seguimos los pasos si era Z=l, en cuyo caso (figura 3.21) se salta a 18.
Si es Z=O dijimos que x i= 45, o sea x no es el ASCII de la E, por lo que simplemente se debe ordenar que SI apunte a la
M,Ginzburg- Assembler desde Cero U3-19
direccin (2001) del elemento siguiente a analizar, para luego llevarlo hacia AL mientras CL no sea cero. Por lo tanto, se
deben realizar los mismos pasos 13, 14 y 15 antes desarrollados para tal fin en el caso de ser Z=l.
Se ha asumido en la figura 3.20 que en la direccin 1004 se localiz un segundo cdigo 45, y por consiguiente en la
direccin 2003 (hacia la cual qued apuntando DI en el supuesto que en 1000 sea x = 45) se guard 45 ; y 1004 en 2004/5.
Entonces en el contador debera ser k = AH = 2.
Si los n cdigos fueran todos 45, en la figura 3.20 se observa que n veces se repetiran los pasos 5, 6, 7, 8, 9, 10, 11, 12,
13, 14, 15, 5, 6, 7 .. . resultando k= n. De hallarse k veces el45 se repetiran estos pasos k veces; y de no encontrarse
ningn cdigo 45 en la lista, se repetiran n veces los pasos 5, 6, 7, 13, 14, 15, resultando k= O.
Cualquiera sea el valor de k alcanzado en AH, luego de analizar los n caracteres el programa finaliza (116) con k en 3000.
= n - I , pa-
::au (Z=O),
l)=x
~1=2001
1)=1000
Figura 3.22 Figura 3.23
Cuando desde un rombo se salta a otra secuencia, que termina en un jump hacia ese mismo rombo, si se invierte el valor
del flag(s) por el cual se pregunta en el rombo dicha secuencia puede escribirse debajo de dicho rombo, para seguir con el
paso a partir del cual comienza la secuencia comn, y conformar as una sola secuencia en vez de dos. En sta el rombo
con la condicin modificada ordena saltar a la instruccin a partir del cual empieza dicha secuencia comn. 1
En la figura 3.23, si Z=1 ahora se sigue haci<:t abajo con los pasos 8 al 14, como se desarrollaron ms arriba; y si Z=O se
Esta regla de simplificacin prctica es fruto de la experiencia del autor sobre el tema, y no la ha visto enunciada en ninguno de los
libros sobre Assembler que ha consultado.
U3-20 M.Ginzburg- Assembler desde Cero
ordena saltar al paso 13, "puenteando" los pasos 8 al 12, que slo deben ordenarse si Z=l. Suponiendo que los n elemen-
tos sean todos letras E, se repetiran n veces los pasos I5 al 115, y si no hubiera ninguna E, los pasos 15, 16, 17, 113, 114 e 115.
Del diagrama lgico de la figura 3.23 resultan la secuencia escrita a continuacin.
MOV CL, [1500] Carga en CL (mitad inferior de CX) el nmero n de elementos contenido en 1500
MOV SI, 1000 SI apunta al comienzo de la lista de datos
MOV DI, 2000 DI apunta al comienzo de la otra lista
SUB AH,AH Pone AH en cero
OTRO MOV AL, [SI] Lleva a AL una copia del caracter de la lista apuntada por SI
CMPAL,45 Compara el valor de AL con 45
JNZ ALFA Si AL no es igual a 45 (Z=O) saltar a ALFA
MOV [DI], AL Lleva a la direccin apuntada por DI una copia del nmero 45 que est en AL
INCDI Incrementa DI
MOV [DI], SI Escribe una copia del valor de SI en la lista apuntada por DI
ADDDI,2 Suma 2 al puntero DI
INCAH Incrementa AH
ALFA INC SI Incrementa SI
DEC CL Decrementa CL
JNZ OTRO Mientras Z sea O, volver a OTRO
MOV [3000], AH Carga en 3000 el valor del contador contenido en AH
INT20 Fin
Una instruccin como MOV AL,[SII con corchete a la derecha ordena leer un elemento de una lista en memoria, y
cargarlo en AL. En cambio MOV [Dij,SI ordena escribir en otra lista apuntada por DI, una copia del valor de SI.
Si por error se escribe MOV DI, SI se ordenara pasar a DI el contenido de SI (movimiento dentro de la UCP).
EJERCICIO 12: determinacin si un nmero natural es mayor que otro, usando la instruccin JA (Jump if
above, o sea saltar si est por arriba) para nmeros naturales para encontrar el mayor de una lista de nmeros.
Se tiene una lista de nmeros naturales de dos bytes cada uno, que empieza en la direccin 1000, siendo que
la cantidad n de nmeros est en la direccin 1500. Desarrollar una secuencia para encontrar el mayor de los
oria, y n nmeros naturales de la lista, y guardar el mismo en la direccin 2000.
El presente ejercicio lo realizaremos de 3 formas diferentes
Primera solucin: mantiene la forma conocida de contar la repeticin del lazo partiendo del nmero n
Didcticamente es ms sencilla, pero hay una repeticin extra de la ejecucin del lazo, por que en la primer vuelta se
_. + N(n) compara el primer nmero con s mismo. Usamos AX por que los nmeros son de 2 bytes.
celdas En las 3 soluciones al inicio comparten los pasos 1, 2 y 3; se supone que Nl es el mayor y se lo lleva hacia AX.
Si N2 >Nl, N2 sustituye a Nl en AX. De no ser as, en AX sigue N l. Si N3 > AX, N3 sustituye al mayor que indicaba AX
_0(}0/ 1. As en AX debe ir quedando el nmero. mayor encontrado a medida que se recorre la lista, mientras no sea superado por
el valor de otro elemento. En la 2da vuelta de la ler solucin (esquema de la fig 3.24), N2 reemplaza a Nl en AX.
-~ le R la
que pro-
_002/3. UCP
- N1
- N2
~ CL-1(n veces)
1
1 Lz
I'Z=O?--ira@
/ "'Z=1?-+ira(
ando y
. = gener
Figura 3.24
U3-22 M.Ginzburg - Assembler desde Cero
Para conocer en esa 2da vuelta si NI~ N2 se hace (ver figura 3.16): NI- N2 = AX- N2 (paso 4), y si C=O es,NI~ N2.
De ser as (paso 5) de la figura 3.22 se debe saltar al paso 7, salteando el paso 6 que ordena reemplazar el valor (NI) que
contena AX por una copia del valor (N2) contenido en la direccin de memoria (1 002) apuntada por SI.
Si C=O es NI< N2 por lo que N2 es el mayor, y debe seguirse con el paso 6 para que quede en AX el nuevo mayor (N2).
En el caso que se comparen dos nmeros iguales, como se indica para la primer vuelta del diagrama con NI- NI, ser
C=O y Z=1 por ser cero el resultado. Entonces tambin se saltear el paso 6, evitando el tiempo que requiere su ejecucin.
Obsrvese que la resta AX- [SI] ordenada, debe ser sin asignacin del resultado en AX (resta para comparar, planteada
en el ejercicio 9), pues de no ser as dicho resultado "pisara" el valor del nmero mayor hallado hasta ese momento.
La codificacin en Assembler correspondiente al diagrama lgico de la figura 3.24 resulta:
Segunda solucin: no se pierde tiempo para comparar el primer elemento consigo mismo. En la inicializacin, dado
que NI se lleva hacia AX con MOV AX, [SI], y que el lazo comienza restando NI - N2, el lazo se debe repetir n- 1
veces, pues con NI en AX ya se consider un elemento. Por tal motivo, luego de DEC CL se parte de n-l.
En Assembler resulta la siguiente secuencia, que slo difiere en la inicializacin de la primera solucin :
Tercera solucin: reduccin de la longitud del programa usando instrucciones con registro indexado en"la misma
Se puede escribir la secuencia anterior de la manera siguiente, donde las instrucciones ADD SI, 2 y CMP AX, [SI] se
han reemplazado por la instruccin CMP AX, [SI+2]. Esto es, en una misma instruccin se suma 2 a SI, y se resta AX
menos el nmero apuntado por SI + 2. El corchete con SI + 2 implica una suma sin asignacin del resultado a SI, o sea
que despus de ejecutar CMP AX, [SI+2) la direccin que guarda SI no cambia. Por ello se requiere ADD SI, 2 para
actualizar el contenido de SI, como se codific en las dos soluciones anteriores.
AX - O (n veces)
~~- 1 UCP
z/Z=1?@AX=N=0 ira@
QP '\..z=O?-AX=N~O ir a@
por SI
v7V=0 y 8=1 ?@ AX=N<O ir a~
'\..V=0 y 8=0? -AX=N;;.O ir a J
'-----JL......:ft-l
Ax +2
@1...... Dl+2
:)~)3000
DI .___ _.......;.='------' k veces
Mientras@
CLI:O (Z=O)
Figura 3.25
Este ejercicio cuyo esquema de pasos a efectuar y diagrama lgico correspondiente aparecen en la figura 3.25 se basa en
! ro)
los ejercicios 7 y 9. En los 5 primeros pasos se inicializan: CL con el numero r-; SI, DI y BX con las direcciones
iniciales elegidas en el esquema para las 3 listas a utilizar; y DX se pone en cero para que sus mitades DH y DL queden
AX,[SI)
en cero como contadores de cantidad ele numeras positivos y negativos, respectivamente.
Para saber si cada numero entero N de la lista (apuntado por SI) es positivo, negativo o cero, se debe restar N- O.
Como para ordenar esta resta no existe la instruccion CMP [SI],O, primero (paso 6) se debe enviar N (apuntado por SI)
hacia AX, con lo cual AX =N; y luego (paso 7) hacer AX- O= N- O. Si en el paso 8 se detecta Z=l implica (fig. 3.15)
que N- O= O, sea que N=O, en cuyo caso ese cero no se debe guardar, segn se pide, y se deben hacer los pasos 12 a 15
para pedir otro nmero; y si Z=O (cero no) implica que el resultado de N- O no es cero, por lo que N tampoco es cero.
Entonces, el paso 8 sirve para determinar si el valor de N que se analiza es igual o distinto de cero. En este ltimo caso
hay que detectar en el paso siguiente (9) si N es negativo o positivo, siendo que en el paso 7 se hizo AX - O = N - O.
Los valores de los flags SZVC que resultan de esta resta no cambian en el paso 8, puesto que una instruccin de salto slo
pregunta por los valores de los flags. pero no los modifica. dado que en la misma la UAL no hace ninguna operacin.
U3-24 M.Ginzburg- Assembler desde Cero
El diagrama central inferior de la figura 3.15 para nmeros enteros sirve de modelo para detectar si A< B, y proporciona
los flags por lo que se pregunta y el cdigo Assembler (JL) de la instruccin. Segn ese diagrama, si V f. S (o sea si S=O
y V=1 S=1 y V=O) es A< B; y si V=S (o sea si S=O y V=O S=1 y V=1) es A 2: B.
En nuestro caso el paso A- B se corresponde con AX- O del paso 6, en el cual es S=1 y V=O, o bien es S=O y V=O, pues
no puede haber overflow si a un nmero se le resta cero. Si en el paso 8 se detecta que fue S=1 y V=O, el resultado es ne-
gativo por empezar con uno, y si fue S=O y V=O, el resultado es positivo o cero, por comenzar con cero. Como que al pa-
so 9 se llega si en el paso 8 se detect Z=O, o sea que N no es cero, no puede ser N 2: O, y slo puede ser N > O (positivo).
Por lo tanto, si en el paso 8 se descarta que N sea cero, en el paso 9 se determina si N es negativo o positivo.
Si N es positivo, se siguen con los pasos 10 a 12, que incrementan el contador CH de positivos,
Si N es positivo, el curso del diagrama seguira con el paso 10 que ordena incrementar el contador DH de positivos.
Luego (paso 11) se en vi a una copia de AX hacia la lisa de positivos apuntada por DI, y como N ocupa 2 bytes, en el paso
12 se le suma 2 a DI, por si aparece otro numero positivo en la lista, como en el ejercicio 9.
Los pasos 13 al 15 son los mismos que cuando se detecta un cero en la lista, a fin de obtener el siguiente numero que
corresponde en la lista, o si se termino con los n numeros de la lista (Z=l), guardar en los valores de los contadores de
positivos y negativos (pasos 16 y 17).
Si N es negativo (V=O y S=1, o sea V f. S pues tienen distinto valor) saltar a otra secuencia que consta de los pasos 18 al
20 para: incrementar el contador DL de negativos, pasar una copia de AX = N a la lista de negativos apuntada por BX, y
luego indexar en 2 a BX por si aparece otro negativo, para terminar esta secuencia con un salto incondicional hacia la
secuencia principal, a fin de que se ejecuten los pasos 13 al 15 comunes para N=O, N> O y N< O.
Como se solicita, este ejercicio adems de ser codificado con el Debug, luego se ejecutar mediante el mismo, con valo-
res supuestos para las variables (datos). Para ello primero con el comando E se entrarn los datos, y luego con el
comando A el programa, aunque el orden es indistinto.
Se siguen las directivas para uso del Debug dadas en la Unidad 1 de esta obra. Los caracteres que debe tipear el operador
estn en negrita itlica, mientras que la respuesta del Debug se muestra en negrita normal.
C:\WINDOWS>debug
Con el comando E se escribirn un numero positivo (0025), un cero, un negativo (8033), y otro positivo (0042)
-E 2000 .J
xxxx:2000 BF.25 C9.00 El.OO AC.OO AA.33 OA.BO C0.42 75.00 .J
En 1500 se escribe la cantidad de nmeros (n=4)
-E 1500 .J
xxxx: 1500 E8.04 .J
Mediante el comando A se escriben las instrucciones en Assembler correspondientes a la figura 3.25. Luego de escribir
cada instruccin, con el Enter (,._, el traductor Ensamblador pasa los cdigos ASCII de la misma a cdigo de
mquina.
-A 0100 .J
xxxx:OIOO MOV CL, [1500/.J Carga en CL la cantidad de nmeros de la lista
xxxx:0104 MOV SI, 2000 .J El registro SI apunta al comienzo de la lista de enteros
xxxx:0107 MOV DI, 3000 .J DI apunta al comienzo de la lista de negativos
xxxx:OlOA MOV BX, 4000 .J BX apunta al comienzo de la lista de positivos
xxxx:OIOD SUB DX, DX .J DX se lleva a cero, para poner a cero los contadores DH (+)y DL (-)
xxxx:OIOF MOV AX, {Sij.J Carga en AX una copia del numero entero de la lista apuntado por SI
xxxx:Olll CMP AX,O .J Al nmero entero contenido en AX le resta O ara ue los fla s tomen valor
xxxx:0114 JZ 0100 .J Si el resultado de la resta es cero salta a una instruccin de esta misma secuencia 1
xxxx:0116 JL 0130 .J Si dicho resultado es negativo saltar a una secuencia que empieza en 0130 2
xxxx:0118 INC DH .J Si dicho resultado no es negativo (o sea es positivo) incrementa el contador de+
xxxx:OllA MOV {BXJ, AX .J Guarda una copia del nmero entero contenido en AX en la lista de positivos
xxxx:OllC ADD BX, 2 .J Se actualiza BX sumndole 2 para guardar el_prximo positivo
xxxx:OllF ADD SI, 2 .J Se actualiza SI en 2 por si hay que pedir otro nmero entero de la lista
xxxx:Ol22 DEC CL .J Se decrementa CL por haber considerado un elemento de la lista
xxxx:0124 JNZ 010F .J Mientras Z=O volver a O1OF
xxxx:0126 MOV {1600/, DL .J Guarda la cantidad de negativos en 1600
xxxx:012A MOV [1700J, DH .J Guarda la cantidad de positivos en 1700
xxxx:012E INT 20 .J
1
Si antes de codificar en Assembler se hizo el diagrama lgico (figura 3.25), en el mismo se ve la instruccin a la que se quiere saltar.
Pero en el Debug como an no se escribi dicha instruccin (que cuando as haga recin se ver que est en la direccin OIIF) en la
instruccin JZ se escribe 0100, direccin cercana falsa que luego se corregir, cuando ms abajo se escribe A 0114 JNZ 011F.
Al hacer luego U 0100 para revisar el programa, se venfica que todo lo esenio en Asssembler est bien.
2
Se eligi arbitrariamente 130 como una direccin cercana, siendo que en una instruccin de salto slo se puede saltar 127 (80 en hexa)
hacia delante expresado en decimal ( 128 hacia atrs) en relacin con la direccin de la instruccin que sigue a la de salto.
M,Ginzburg- Assembler desde Cero U3-25
Los puntos suspensivos de la secuencia izquierda indican otras instrucciones que arroja el comando U, pero que no
interesan. Son "basura". Este comando realiza lo que se denomina "disassembler" o "unassembler". Esto es, a partir de
la direccin dada (O 100) interpreta los cdigos de mquina en sus correspondientes instrucciones en assembler,
efectuando el proceso contrario al que realiza el programa traductor Ensamblador.
La secuencia de la derecha, que viene de la pgina anterior, es otra forma de resolver el ejercicio mediante una sola
secuencia, sin usar instrucciones jump ("go to"). En la codificacin se han usado etiquetas.
A continuacin se ejecutar el programa arriba codificado con A O100 y con flechas se detallan los movimiento-s.
-RIP ..1
IP 1246
: 0100-R ..1 AX=0025 BX=4000 CX=OOOO OX=OOOO SP=FFEE BP=OOOO SI=2000 01=3002
Tener presente que el comando T ejecuta la instruccin que se ve escrita arriba del mismo, como indica la primer flecha hacia la derecha
OS=1060 ES=l060 SS=1060 CS=l060 IP=OIOO NV UP El PL NZ NA PO NC
1060:0100 8~10V CL, [1500] OS:ISOO_:j;! (indica que antes de ejecutar MOV CL,[JSOO] en memoria 1500 hay 04)
-T ...,r--- .__ (04 pasa de memoria a CL)
AX=0025 BX=4000 CX=0004 DX=OOOO SP=FFEE BP=OOOO SI=2000 01=3002
OS=1060 ES=l060 SS=I060 CS=l060 IP=0104 NV UP El PL NZ NA PO NC
1060:0104 BE0020 MOV SI, 20 O
- T ..1 (2000 que vino con la instruccin pasa a Si)
AX=0025 BX=4000 CX=0004 OX=OOOO SP=FFEE BP=OO 00 01=3002
OS=l060 ES=1060 SS=l060 CS=t060 IP=Ol07 NV UP El PL NZ NA PO NC
106D:Ol07 BF0030 MOV
- T ..1
AX=0025 BX=4000 CX=0004 OX=OOOO SP=FFEE BP=OOOO SI= 3000
OS=l060 ES=l060 SS=l060 CS=l060 IP=OIOA NV UP El PL NZ NA PO NC
en hexa) 1060:0IOA 880040 MOV BX, 4000
U3-26 M.Ginzburg- Assembler desde Cero
- T ..J
AX=0025 BX=4000 CX=0004 OX=OOOO SP=FFEE BP=OOOO SI=2000 01=3000
OS=1060 ES=l060 SS=l060 CS=J060 IP=OlOO NV UP El PL NZ NA PO NC
1060:0100 2902 SUB OX, OX
- T ..J
AX=0025 BX=4000 CX=0004 OX=OOOO SP=FFEE BP=OOOO SI=2000 01=3000
OS=1060 ES=1060 SS=1060 CS=1060 1P=010F NV UP El PL ZR NA PE NC
1060:010F 8804 MOV AX, [SI] 025 (antes de ejecutar MOV AX, [SI] en memoria 2000/ 1 hay 0025)
- T ..J (De memoria pas hacia AX una copia de 0025 apuntado por S1=2000)
AX=0025 =4000 CX=0004 OX=OOOO SP=FFEE BP=OOOO Sl=2000 01=3000
OS=1060 ES=l060 SS=1060 CS=l060 1P=Ol11 NV UP El PL ZR NA PE NC
1060:0111300000 CMP AX, 0000 (se ordena restar AX - O= 25- O para ver el valor de los flags)
- T ..J
AX=0025 BX=4000 CX=0004 OX=OOOO SP=FFEE BP=OOOO Sl=2000 01=3000
OS=1060 ES=1060 SS=l060 CS=1060 IP=Oll4 NV UP El PL NZ NA PO NC
1060:0114 7409 JZ OllF Con JZ se salta si Z=l; como fue NZ (Z=O sea el resultado de AX- 00 no fue cero) no se saltar
- T ..J
AX=0025 BX=4000 CX=0004 OX=OOOO SP=FFEE BP=OOOO Sl=2000 01=3000
OS=I060 ES=l060 SS=l060 CS=I060 IP=Oll6 NV UP El PL NZ NA PO NC
1060:0116 7Cl8 JL 0130 Con JL se salta si SiN; como en AX- O fue NV (V=O) y PL (S=O) o sea S= V no se saltar a 0130
- T ..J
AX=0025 BX=4000 CX=0004 OX=rOO SP=FFEE BP=OOOO SI=2000 01=3000
OS=l060 ES=1060 SS=l060 CS= 060 IP=Oll8 NV UP El PL NZ NA PO NC
1060:0118 FEC6 INC OH
- T ..J (DH pasa de 00 a 01 pues se encontr un positivo)
AX=0025 BX=4000 CX=0004 OX=OIOO SP=FFEE BP=OOOO SI=2000 01=3000
OS=l060 ES=l060 SS=1060 CS=106D 1P=011A NV UP El PL NZ NA PO NC
1060:011A 8907 MOV [BX], AX (Se ordena guarda en memoria apuntada por BX=4000 el nmero positivo 0025 hallado)
AOO BX,+02
25. OO. (As se verifica antes de ejecutar ADD BX,+02, que desde AX, en 2000/1 de memoria se escribi 0025)
- T ..J
AX=0025 BX=4002 CX=0004 DX=OIOO SP=FFEE BP=OOOO Sl=2000 01=3000
OS=l060 ES=l060 SS=1060 CS=l060 lP=OllF NV UP El PL NZA PO NC
1060:011F 83C602 ADO SI,+02
- T ..J (SI pas de 2000 a 2002)
AX=0025 BX=4002 CX=OOlOX=OlOO SP=FFEE BP=OOOO SI=2002 01=3000
DS=1060 ES=l06D SS=l06 CS=l060 IP=0122 NV UP El PL NZ NA PO NC
1060:0122 FEC9 OEC L (Se ordena hacer CLf- CL- 1 sea 4- 1)
- T ..J (CL pasa de 04 a 03)
AX=0025 BX=4002 CX=OO _ OX=OIOO SP=FFEE BP=OOOO SI=2002 01=3000
DS=l06D ES=l060 SS=l060 CS=1060 IP=Ol2~NV UP El PL NZ NA PE NC
1060:0124 75E9 JNZ OIOF NZ (Z=O) indic que CL- 1 = 4-;:;-o fue cero, y se saltar, pues JNZ ordena hacerlo si es Z=O
- T ..J (IP salta de 0124 a OIOF como ordena JNZ 010F)
AX=0025 BX=4002 CX=0003 DX=OIOO SP=FF BP=OOOO SI=2002 01=3000
DS=1060 ES=l060 SS=I060 CS=1060 IP=O F NV UP El PL NZ NA PE NC
1060:010F 8804 MOV AX,[SI[ OS (antes de ejecutar MOV AX, [SI] en memoria 2002/3 hay 0000)
- T ..J (De memoria pas hacia AX una copia de 0000 que est apuntado por SI=2002)
AX=OOOO =4002 CX=0003 OX=0100 SP=FFEE BP=OOOO Sl=2002 01=3000
DS=1060 ES=l060 SS=1060 CS=106D IP=0111 NV UP El PL NZ NA PE NC
1060:0111 300000 CMP AX, 0000 (se ordena restar AX- O= O- O para ver el valor de los flags)
- T ..J
AX=OOOO BX=4002 CX=0003 OX=OIOO SP=FFEE BP=OOOO SI=2002 Dl=3000
OS=l060 ES=1060 SS=l060 CS=1060 IP=0114 NV UP El PL ZR NA PE NC
1060:0114 7409 JZ 011F ZR (Z=l) indica que AX- O= ="o fue cero, y se saltar, pues JZ ordena hacerlo si es Z=l
- T ..J (IP salta de 0114 a 01 IF como ordena JZ 01 FF)
AX-<10<10 BX-40<12 CX-oOOJ DX-0100 Sl'-FFEE BP-00<10 Sl-lOOt DI-300<1
OS=1060 ES=I06D SS=1060 CS=I060 IP=011F NVUPEIPLZR APENC
106D:011F 83C602 AOO SI, +02
- T ..J (SI pas de 2002 a 2004)
AX=OOOO BX=4002 CX=OOlOX=OlOO SP=FFEE BP=OOOO SI=2004 01=3000
OS=1060 ES=1060 SS=106 CS=l060 IP=0122 NV UP El PL NZ NA PO NC -T -
1060:0122FEC9 OEC L CL (SeordenahacerCLf-CL-1 sea 3-1)
- T ..J (CL pasa de 03 a 02)
AX=OOOO BX=4002 CX=OO DX=OIOO SP=FFEE BP=OOOO Sl=2004 01=3000
OS=1060 ES=l06D SS=1060 CS=1060 IP=0124 NV UP El PL NZ NA PO NC
1060:0124 75E9 JNZ 010F NZ (Z=O) indica que CL - 1 = 3=1 no fue cero, y se saltar, pues JNZ ordena hacerlo si es Z=O
e Cero M,Ginzburg- Assembler desde Cero , U3-27
EJERCICIO 14 Con listas cuya cantidad!! de caracteres que las conforman no es un dato directo.
En las direcciones 1000 y 2000 comienzan dos listas de caracteres ASCII de maysculas que corresponden a nombres de
personas, las cuales pueden ser de igual o distinta longitud, siendo que cada lista termina con el caracter ASCII corres-
pondiente al Enter (00), como se ejemplifica. Determinar en cul de esas dos listas correspondientes a nombres, esta
el nombre que va primero por orden alfabetico, escribiendo en la direccion 3000 la direccin donde comienza di'cha lista.
Se supone que los nombres han sido bien tipeados, con caracteres ASCII de maysculas, y que terminan con Enter.
1000 41 (A) 2000 40 (M) 1000 41 (A) 2000 41 (A) 1000 41 (A) 2000 41 (A)
4E (N) 45 (A) 4E (N) 4C (L) 4E (N) 4E (N)
41 (A) 52 (R) 41 (A) 42 (B) 41 (A) 41(A)
00 (-l) 41 (A) 00 (-l) 41 (A) OD (-l) 48 (H)
00 (-l) 00 (-l) 49 (I)
00 (-l)
Figura 3.26.a Figura 3.26.b Figura 3.26.c
Este ejercicio, por desconocerse de entrada la cantidad n de caracteres que componen cada lista, no empezar como otros
anteriores con MOV CL, [.... ] y terminar con DEC CL y JNZ . . . . forma tpica que usamos para las estructuras tipo
FOR en alto nivel. En este caso el ciclo se repetir mientras ("while") no se detecte un final de nombre (carcter 00) o no
bien se detecte que son diferentes los cdigos ascii de dos letras que se estn comparando.
e Cero M,Ginzburg- Assembler desde Cero U3-29
En el inicio del diagrama de la figura 3.27 en BX y DX quedan los nmeros
1000 y 2000 que se usarn (uno u otro) para indicar al final del programa la
direccin de la lista que es primera por orden alfabtico, como se pide.
As en el caso de ANA y MARA deber quedar en la direccin 3000 el valor
1000, indicando que la lista comenzada en 1000 es primera alfabticamente.
Luego (pasos 3 y 4), los punteros SI y DI de cada lista se inicializan con
OFFF y 1FFF, de modo que cuando en los pasos 5 y 6 se ordene SI~ SI+ 1
y DI ~DI+ 1, en la primer vuelta del procedimiento resulte:
SI= OFFF + 1 = 1000 y DI= 1FFF + 1 = 2000. De este modo, en el caso a)
de la figura 3.26 los registros SI y DI en la primera vuelta apuntarn a los
:;e saltar cdigos ASCII de las letras A y M que estn en 1000 y 2000 en las listas
dadas. Dichos cdigos luego de los pasos 7 y 1O pasarn hacia AL y AH.
Para determinar si uno u otro de esos cdigos corresponde o no al cdigo
ASCII OD de la tecla Enter (.J), lo cual indicara que es el fin de una u otra
lista (o de ambas si tienen igual cantidad de letras), primero se ordena(pasos
8 y 11) las restas AL- OD y AH- OD, para luego (pasos 9 y 12), preguntar
si Z=l , como en el ejercicio 9. En caso que sea Z=l implica que AL= OD, o
que AH= OD, o sea que una u otra lista ha terminado.
Si se asume que cada nombre tiene al menos una letra, en la primera vuelta
dichas restas slo pueden generar Z=O, pues las listas no pueden terminar
con una sola vuelta.
Con la resta del paso 13 comienza el proceso para comparar dos letras que
estn en igual posicin en ambas listas.
Si en el paso 14 se determina que Z=1 significa que esas dos letras compara-
das son iguales (esto se supuso para la primer letra A en los casos by e) de
la figura 3.26, lo cual se detectara en ambos casos en la primer vuelta.
De ser Z=1 (figura 3.27) se ordena saltar al paso 5, con lo cual comienza una
segunda vuelta donde nuevamente se comparan los dos cdigos siguientes
para detectar si alguno de ellos (o ambos) es de fin de lista, o bien si corres-
ponden a letras distintas o iguales.
Si en la segunda vuelta las letras son iguales, como ocurre con ANA y
ANAHI implica que hasta las segundas letras hay "empate" en el orden
alfabtico pues dichas letras son N, por lo que se debe seguir con una tercer
vuelta, en la que otra vez "empatarn" . Enseguida se ver el paso siguiente.
En la segunda vuelta de ANA y ALBA en el paso 13 la resta no dar cero,
por lo que el paso 14 detectar Z=O.
parte de
Ello significa que las dos letras (N y L) no son iguales, lo cual implica que
la.
no ser necesara una tercer vuelta, y permite determinar en el paso 15, por
ser C=O, que AL> AH (ver fig. 3. 16), detectndose asi que el cdigo ASCII
(de la N) que est en AL es mayor que el cdigo (de la L) que est en AH.
Por lo tanto, si bien las dos primeras letras fueron iguales (A y A), las
,-= 0100 ..J) segundas no lo son, y por ser cdigo N > cdigo L es suficiente para deter-
minar que ALBA va primero por orden alfabtico, por lo que en la direccin
3000 debe ir la direccin 2000 que aportar DX, donde comienza ALBA
Figura 3.27 (paso 17); y as terminara el programa para el caso b).
to. MOVBX, 1000 En el caso a) de ANA y MARA ya en el paso 14 de la primera vuelta resulta
nombres de MOVDX, 2000 Z=O (AL:!:AH), y se sigue con el paso 15 que detectara C=l (AL< AH, o
.-SCII corres- MOV SI, OFFF sea: cdigo A< cdigo B), por lo que ANA va primera por orden, y su diref
bres, esta MOV DI, lFFF cin 1000 la provee BX para que se guarde en 3000 (paso 16).
1::. ' cha lista. OTRO INC SI Con ANAHI y ANA en el paso 14 de las tres primeras vueltas se detectar
Enter. INCDI Z=l.
MOV AL, [SI) Pero en la cuarta vuelta, por ser OD el cuarto cdigo de la lista de ANA (figura 3.26.c),
CMPAL,OD dicho cdigo indica que ese nombre termin, y en el paso 11 ser: AH- OD = OD- OD =O,
JZ GASI y por lo tanto Z=l. El paso 12 detectar Z=1 y ordenar saltar al paso 16, donde BX pasa a
MOVAH, [DI) las celdas 3000/lla direccin 1000 como indicacin de que ANA va antes que ANAHI.
CMPAL,OD) Si ambos nombres son idnticos, y por lo tanto de igual nmero de letras, en los pasos 8 y 9
JZ GADI de la vuelta en que primero se detecta el fin del nombre de la lista que empieza en 1000, se
CMPAL,AH saltara al paso 16 que ordena llevar 1000 (que est en BX) a la direccin 3000. Como las
JZ OTRO dos listas estn en igual orden, no importa que la primera sea siempre la que est eh 1000
JA GADI Obsrvese que como inicialmente no se conoce el nmero n de caracteres que
GASI MOV [3000),BX que componen qda lista, la secuencia no termina con DEC CL y JNZ.
INT20
GADI MOV [3000),DX
INT20
U3-30 Nl.Ginzburg- Assembler desde Cero
EJERCICIO 15 Otro caso de una lista cuya cantidad.!!. de caracteres que la componen no es un dato directo.
Dado que al tipear caracteres puede haber errores, hacer un programa que valide (verifique) si Jos cdigos
ASCII de una lista que empieza en la direccin 1000 y termina con el cdigo OD de En ter, realmente
corresponden a caracteres alfabticos, ya sean maysculas o minsculas indistintamente, y no a otros.
Asimismo contemplar la posibilidad que el carcter OD (Enter) de fin de la lista est errado o no est, en cuyo
caso controlar que un nombre pueda tener hasta 20d = 14h letras, pues caso contrario el programa podra no
terminar nunca. Ya sea que se encuentre un cdigo que no corres-
n 0000 1CX=OOOO ponda a una letra o que no est el cdigo OD, escribir OOOOh en
l
direcciones 300011. Si la lista de letras se valida, escribir FFFF en
DX --- FFFF 1DX=FFFF
esas direcciones. No se da la cantidad n de caracteres de la lista.
En el cuarto de los pasos de in icio (figura 3.28) se pone a cero el registro
AH, que ser usado para contar el nmero de cdigos ASCII que han sido
analizados, cuyo valor no puede superar 21 d = 15h como se deducir.
El procedimiento comienza (paso 5) incrementando dicho contador AH,
pues en cada vuelta se empieza a analizar un nuevo cdigo y se ordena la
resta AH -15 del paso 6 para constatar si AH = 15h = 21 d, para el caso
que ya se hayan analizado 20d cdigos y no se detect el fin de lista OD.
Como en la primer vuelta es AH= 1, en el paso 7 se detectar Z=O, o sea
AH:;i:l5, y mientras sea Z=O se sigue en cada vuelta con SI(- SI+! (paso
8) para que SI apunte al siguiente cdigo que en esa vuelta corresponde
analizar. Luego (paso 9) con ALf- [SI] se lleva hacia AL una copia del
cdigo ASCII apuntado por SI (SI=! 000 en la primer vuelta).
Si a partir de la direccin 1000 se tiene 4C (L) 69 (i) 61 (a) OD (.J), o sea
suponiendo el nombre Lia codificado en ASCII, en AL se tendra 4C en la
primer vuelta.
En general, el cdigo que est en AL puede ser:
a) OD de fin de nombre; b) de una mayscula; e) de una minscula;
d) un cdigo incorrecto, en cuyo caso se debe escribir 0000 en las
direcciones de memoria 3000/1, segn se ~ideen el enunciado.
Primero se verifica si el cdigo que lleg a AL es OD (Enter de final) .
A tal fin el paso 1O ordena AL- OD; y si en el paso 11 se detecta Z=l por
ser AL=OD, ello implica que en esta vuelta se detect dicho cdigo de fin
de nombre, y que en las vueltas anteriores se validaron todos los cdigos
analizados como correspondientes a letras maysculas o minsculas.
Por lo tanto si Z=l se ordena saltar (figura 3.28) al paso 21 para escribir
FFFF=DX en 3000/1 y luego finalizar el programa . .
En nuestro ejemplo por ser AL = 4C . OD se sigue con los pasos que
determinan si el cdigo es de una letra mayscula o minscula.
Si es una mayscula, su codificacin ASCII debe estar comprendida entre
41 (letra A) y SA (letra Z); o sea debe ser 41 < AL < 5A.
Para saber si 41 ::; AL el paso 12 ordena AL - 41, y en el paso 13 se pre-
gunta si esa resta gener C=l , lo cual implicara (fig 1.16) que AL< 41, o
sea que es un cdigo ASCII entre 00 y 40 que no es el de una mayscula.
Si bien entre 00 y 40 est OD, este cdigo no puede ser, pues para nuestro
MR:>-_!(AL<61)
---1
ejemplo antes se detect AL i OD. Tampoco no es de una letra minscula,
1 1 dado que los cdigos ASCII de stas est comprendido entre 6-(letra a) y
1 1
1 1 7 A (letra z), por lo que se trata de un cdigo ASCII que no corresponde a
1 1
1 1 ninguna letra. Entonces se ordena (figura 3.28) saltar al paso 20 para
1 1 indicar en las direcciones 3000/1 con OOOO=CX que la lista no es vlida.
1 1
1 1 Volviendo al paso 13, si en l se-detecta que C=O originado por la resta
1 : AL- 41, debe ser AL 0:: 41, (fig. 3.16) o sea 41 ::; AL. Para determinar si
el cdigo que est en AL es el de una letra mayscula (41 < AL < 5A)
falta ver si AL::; 5A. Con este fin se ordena AL- 5A (paso 14) que en el
ejemplo dado sera 4C - 5A. Si en el paso 15 se detecta que AL- 5A ge-
ner C=1 Z=l implica AL::; 5A, determinndose que es una mayscula.
Esto sucede en el ejemplo dado, pues luego de hacer AL- 5A = 4C - 5A
resultar C=l y Z=O, siendo que 4C es el cdigo de la letra mayscula L.
Por lo tanto se ordena saltar al paso 5 para analizar el cdigo ASCII
siguiente, que para el nombre Lia ser 69 de la letra i. As comenzar una
segunda vuelta similar a la primera, salvo que en el paso 9 va hacia AL
Figura 3.28 dicho cdigo 69. Igualmente como en la primer vuelta, el procedimiento
sigue por los pasos 1O a 15.
M,Ginzburg- Assembler desde Cero U3-31
ecto. En el paso 14 ser AL- 5A = 69- 5A, por lo que en el paso 15 se detecta C=O y Z=O, resultando AL> 5A, de donde se
s cdigos detectara que en AL no se tiene el cdigo de una mayscula.
_ realmente A fin de determinar si es una minscula (61 <AL < 7A) se ordenan los pasos 16 al 19 semejantes a los pasos 12 a115,
salvo los valores lmites. Si luego de hacer AL- 61 en el paso 17 se detecta que C=l, significa que AL< 61, o sea que el
cdigo que est en AL no es el de una minscula. Como de los pasos 1O al 15 se determin que AL no es OD de fin de
nombre, ni es el de una mayscula, necesariamente es un cdigo ASCII no permitido, por lo que se ordena saltar al paso
20 donde se escribe 0000 en 3000/1 (lista invlida).
Siendo en nuestro ejemplo AL=69 (letra i), al hacer AL - 61 = 69- 61 resultar C=O y Z=O, con lo cual AL~ 61 , (fig.
3. 16) o sea 61 :S AL; y falta ver si si AL :S 7 A. Con este fin se ordena AL - 7A (paso 18) que en el ejemplo dado sera
69 - 7 A. Si el paso 19 detecta que AL - 7A gener C= 1 Z= 1 implica AL :S 7 A, determinndose que es una minscula.
Esto sucede en el ejemplo dado, pues luego de hacer AL - 7A = 69 -7A resultar C=1 y Z=O, siendo que 69 es el cdigo
:ro el registro de la letra minscula i, pudindose pasar a validar el cdigo que sigue al 69 en la lista.
~ han sido
. ,_ Por ello se ordena saltar al paso 5 para analizar el cdigo ASCII siguiente, que para el nombre Lia ser 61 de la letra a .
ucir. As comenzar una tercera vuelta muy similar a la segunda, salvo que en el paso 9 va hacia AL dicho cdigo 61, que por
rontador AH, ser el de una minscula seguir por lo~ pasos 10 a 19, para volver saltar al paso 5, como sucedi en la vuelta anterior.
se ordena la En la cuarta vuelta ser AH= 4 (paso 5), y en el paso 9 hacia AL va el cdigo OD. En el paso 1O ser AL- OD = OD- OD
?3ffi el caso por lo que en el paso 11 se detectarZ=1, y se saltar al paso 21 para llevar FFFF = DX hacia 3000/1 (lista validada).
lista OD. Los pasos 10 y 11 del inicio de la 4ta vuelta, se detectar que AL= OD, y as se salta al paso 20 que valida la lista.
Z=O, o sea Si a partir de la cuarta vuelta y hasta la vuelta 20d = 14h no se encuentra el cdigo OD, al comenzar la vuelta 2ld = 15h en
r SI+ ! (paso
corresponde
el paso 7, por ser Z=1 (AH=21) se termina el programa invalidando la lista, aunque los cdigos anteriores sean de letras.
MOV CX, 0000 Obsrvese nuevamente los beneficios de usar la instruccin CMP de resta sin asig
copia del MOV DX, FFFF nacin como AL- XX, que a lo largo de una secuencia, a partir del paso 9 permi-
MOV AH, OO te restar a un mismo valor presente en AL distintos valores XX, sin que vare el cQ.
(.J), o sea MOV SI, OFFF digo ASCII que est en AL, para poder usar los flags con distintos fines, como in-
a 4Cenla OTRO INCAH dica la figura 3.28.
CMPAH, 15 En este ejercicio, como en el anterior, a diferencia de otros anteriores, por un lado
JZ ERRO no se conoce la cantidad de elementos que tienen las listas, por lo que no finalizan
INC SI con DEC CL seguido de JNZ.
MOV AL, [SI] En los ejercicos 14 y 15 el paso a una nueva vuelta depende de los valores de los
CMPAL,OD elementos de una lista, como ser de AL, mientras que en los ejercicios anteriores
JZ VALE este paso depende del nmero de elementos operados, o sea de CL.
CMPAL,41 Asimismo en los ejercicos 14 y 15 los contadores y punteros se indexan al princi-
JB ERRO pio de cada vuelta, pues la ubicacin de los pasos que ordenan indexar registros
CMPAL,5A puede implicar variaciones en los valores de los flags, que afectaran a los flags
JBE OTRO resultantes de operaciones de resta sobre los cdigos presentes por ejemplo en AL
CMPAL,61 necesarios para el procedimiento que se est realizando.
J B ERRO
CMPAL, 7A
pasos que JBE OTRO
ERRO MOV [3000J,CX VALE MOV [3000],DX
dida entre INT20 1NT20
EJERCICIO 16 Intercambio de elementos entre dos listas, y variante con ahorro de un puntero Existen
dos listas de igual cantidad de nmeros enteros (2 bytes cada uno), que empiezan en las direcciones 2000 y 3000
respectivamente. La cantidad de nmeros de ambas listas est en la direccin 1500. Comparar los nmeros correspon-
para nuestro dientes, y dejar todos los elementos menores en una lista, y los mayores en otra.
minscula, Por ejemplo (situaciones inicial y final ejemplificadas con nmeros decimales):
1 (letra a) y 2000 28 3000 12 2000 12 3000 28 (se intercambiaron los elementos correspondientes)
sponde a -5 10 -5 10 (no hubo que intercambiarlos)
20 para 35 -8 -8 35 (se intercambiaron los elementos correspondientes)
es vlida.
~ por la resta MOV CL, [1 500] Carga en CL la cantidad de nmeros de las listas MOV CL, [1500]
rrninar si MOV SI, 2000 Registro SI apunta al comienzo de una lista MOV SI, 2000
<AL < 5A) MOV DI, 3000 Registro DI apunta al comienzo de la otra lista OTRO MOV AX, [SI]
) que en el OTRO MOV AX, [SI] Carga en AX un nmero de la lista apuntada por SI MOV BX, [SI+ 1000]
AL - 5A ge- MOV BX, [DI] Carga en BX un nmero de la lista apuntada por DI CMP AX,BX
mayscula. CMP AX,BX Resta los nmeros correspondientes de ambas listas JL DEJA
= 4C- 5A JL DEJA Si AX < BX saltar a DEJA (los nmeros donde estn) MOV [SI+ 1000], AX
Jscula L. MOV [DI),AX Lleva a la lista apuntada por DI el nmero mayor MOV [SI],BX
m go ASCII MOV [SI],BX Lleva a la lista apuntada por SI el nmero menor DEJA ADD SI,2
enzar una DEJA ADD DI,2 Incrementa DI en 2 DECCL
va hacia AL ADD SI,2 Incrementa SI e{l2 JNZ OTRO
JrOCedimiento DECCL Decrementa CL INT20
JNZ OTRO Mientras Z=O, volver a OTRO Este ahorro de un registro slo puede
INT20 Fin ser hecho si las listas avanzan juntas.
U3-32 M.Ginzburg- Assembler desde Cero
EJERCICIO 17 Redondeo de nmeros con parte entera (de longitud no limitad~) y fraccionaria (un dgito)
A partir de la direccin 3000 estn codificados en ASCII los dgitos X 1X2X3 . . . X" .Y de un nmero decimal
con n dgitos Xi de parte entera y un solo dgito Y de parte fraccionaria, separadas por el cdigo ascii (2E)
del punto (equivalente a una coma), como se ejemplifica en las figura 3 .29 para N= 389,3 y N= 389,7.
Desarrollar un programa de redondeo, para que el nmero cuyos dgitos conforman un vector en memo-
ria, contine guardado a partir de la direccion 3000, pero modificado por el redondeo, segn se ejemplifi-
ca, para que la parte fraccionaria sea cero, o sea para que el
nico dgito fraccionario Y valga cero.
2FFF XX 2FFF 00 (O) 2FFF XX 2FFF 00 (O)
3000 33 (3) -7 3000 33 (3) 3000 33 (3) -7 3000 33 (3)
3001 38 (8) -7 3001 38 (8) 3001 38 (8) -7 3001 38 (8)
3002 39 (9) -7 3002 39 (9) 3002 32 (2) -7 3002 33 (3)
3003 2E (.) 3003 2E (.) 3003 2E (.) 3003 2E (.)
81=3000 (1 ra vuelta) 3004 33 (3) -7 3004 30 (O) 3004 37 (7) -7 3004 30 (O)
Para N= 382.7 (figura 3.29.b), dado que Y=7 (ascii 37) el paso 110 de la resta ser 37 35 generando C=O, o sea Y:::: 5,
por lo que el paso I11 ordenar seguir con [SI] ~ BH (112), en el cual como en I23 se, rribir O (30=BH) en la direccin
(3004) de Y que sigue apuntada por SI, resultando Y=O; y hasta este punto del program . .pasara a ser N= 382.0 .
Dado que Y:::: 5 para redondear N= X 1X2X 3 . . . Xn .Y siempre se debe sumar uno :. dgito entero Xn, que est a la
memo- izquierda del punto, cualquiera sea el valor de Xn (O :S Xn :S 9), siendo Xn = 2 en 382.0 obtenido en I12 .
' ejemplifi- El dgito Xn (figuras 3.29 y 3.31) est siempre dos nmeros hacia atrs de la direccin de Y, por lo que para localizar a
que el Xn se debe restar 2 a SI que qued apuntando a Y (SI en 3004 en este ejemplo).
Esta resta se har en dos pasos separados (I13 e I14) restando uno en cada paso, quedando en nuestro ejemplo SI=3002.
Entonces, para Y:::: 5, luego de hacer Y=O (en I12) siguen (I13 e 114) esas dos restas. As SI apunta al dgito Xn, a fin de
(O) enviar otra vez una copia de Xn hacia AL (paso Il5), para sumarle uno (AL~ AL+ 1) al cdigo ascii del dgito Xn en Il6.
.3 (3) Para los dgitos Xn del O al 8 la suma AL~ AL+ 1 genera correctamente el cdigo assii del dgito decimal siguiente:
38 (8) 30 (Od) + 1 = 31 (Id); 31 (Id)+ 1 = 32 (2d) ... 38 (8d) + 1 = 39 (9d).
.3 (3) Volviendo a N= 382.7 que en el paso ll2 pas a ser 382.0 , en I15 el cdigo 32 del dgito Xn = 2 estara en AL; y en 116
2E (.) en el registro A se tendra 32 + 1 = 33 (cdigo ascii del 3d). Luego los pasos Il7 e Ir8 (a tratar) permitiran determinar
30 (O) que Xn f. 9, y por Jo tanto I18 ordenara saltar a I25, donde se ordena reemplazar (en la direccin 3002 apuntada por SI sin
cambios desde Il4) el cdigo 32 de Xn = 2 por el cdigo 33 que est en AL, quedando Xn = 3. As 382.7 redondeado pasa
a ser 383.0; y como en 126 se enva un cero a la direccin 3FFF, el redondeo finaliza con N= 0383.0 (figura 3.29.b).
Si hubiera sido N= 0.5 en I12 pasara a ser 0.0, y en I16 por ser Xn =O (ascii 30) sera 30 4- 1 = 31. Como en IIS por ser
Z=O se detectar Xn "1 9, se saltar a I25 a fin de que el contenido de AL=31 (ascii del 1) reemplace al cdigo 30 (ascii del
O) en la direccin 3000 que sigue apuntada por SI desde ll5. As el 0.0 pasar a ser 1.0 , y luego de I26 resultara N= 01.0
Los mismos pasos sucederan con 3.9 con 394.6 que redondeados quedaran como 04.0 y 0395 .0 .
De ser Xn = 9, como ocurre con N= 389.7 que redondeado quedara 0390.0, al sumarTh uno al 9, el resultado 10 implica
que en lugar del dgito Xn = 9 debe ir un cero, y que se debe sumar uno al dgito Xn-1 d8 que est a la izquierda de Xn.
Si al ascii del9, que es 39, se le suma uno en AL~ AL+l (I16) resulta 39 + 1 = 3A. Si bien 3A no es el ascii de ningn
dgito, servir para determinar si en AL (paso I15). estuvo el cdigo 39 del9. o no (cdigos ascii del O al8).
Por tal motivo en I17 se ordena restar AL- 3A, que si genera Z=l (AL= 3A) indirectamente implica que en el paso fue
AL= 39, o sea Xn = 9, por lo que en el paso Il8 se ordena seguir con I19.
Este paso (siempre para Y :::: 5) tiene en cuenta si la parte entera termina en uno o ms 9s (como 389.7) o son todos
nueves (9.6; 999 . ... 9.5 etc.), en cuyo caso el primero de la serie de nueves estara en la direccin 3000.
2FFF XX 2FFF 30 (O) 2FFF XX 2FFF 31 (1) 2FFF XX 2FFF 31 (1)
3000 33 (3) -7 3000 33 (3) 3000 39 (9) -7 3000 30 (O) 3000 39 (9) -7 3000 30 (O)
3001 38 (8) -7 3001 39 (9) 3001 2E (.) 3001 2E (.) 3001 39 (9) ~ 3001 30 (O)
3002 39 (9) -7 3002 30 (O) 3002 36 (6) -7 3002 30 (O) 3002 2E (.) 3002 2E (.)
3003 2E (.) 3003 2E (.) 3003 35 (5) -7 3003 30 (O)
3004 37 (7) -7 3004 30 (O)
Figura 3.3l.a Figura 3.3I .b Figura 3 .3l .c
Retornando a N= 389.7 (figura 3.31.a) el 9 estaria en la direccin 3002, y en el paso I12 se tendra 389.0. En IIS una
copia del cdigo 39 del 9 que est en 3002 pasa a AL; y en ll6 se tendra 39 + 1 = 3A. Luego los pasos I17 e liS
permitirian establecer que Xn = 9; y por lo tanto I1S ordenarla seguir con I19. En este paso se hace SI- 3000 para poder
determinar si el 9 que se detect mediante II 7 e I1S es o no el primer digito que est en 3000 (en 389.7 dicho dgito es 3).
Despus del paso 115 sigue SI en 3002, por lo que en 119 es SI- 3000 = 3002-3000 f. O generndose Z=O.
En consecuencia en I20 se ordenar seguir con I21 por que el 9 antes detectado (con SI=3002) no est en 3000, o sea que
hay otro dgito a la izquierda de este 9, el cual se debe reemplazar por un cero, y sumarle uno al dgito Xn-1 (en este caso
8) que est a su izquierda. En I21 se reemplaza en 3002 (apuntada por SI) el cdigo 39 de este 9 por el cdigo 30 = BH
del dgito O, resultando as 380.0 en re<:mplazo de 389.0 obtenido en el paso I 12.
Sigue I22 para saltar incondicionalmente a I14 para que sea SI= 3002- 1 = 3001 apuntando al cdigo 38 del dgito 8; y
luego de los pasos I15 e I16 resulta AL= 38 + 1 = 39 (ascii del9). En II 7 la resta 39- 3A arrojar Z =O (lo cual implica
que el dgito X (en este caso 8) apuntado por SI=3001 no es 9. Por ser Z=O en 11S se saltar a 125 para reemplazar en 3001
fXSivamente (apuntada por SI) el cdigo 38 del 8 por el cdigo 39 del 9 que est en AL, resultando as 390.0 en reemplazo de 380.0
i::alizado los obtenido anteriormente en el paso 121. Para finalizar, como pide el enunciado, en I26 se enva un cero a la direccin
3FFF, finalizando el redondeo con N=' 0390.0 (figura 3.3l .a).
Suponiendo N= 9.6 (figura 3.31.b), el 9 estara en la direccin 3000, y despus del paso liS el cdigo 39 del 9 estara en
AL (siendo SI=3000); y en li6 se tendra 39 + 1 = 3A. Luego los pasos Il7 e I1S permitiran. detectar que en li5 fue
AL=39 (o sea Xn = 9 en 3000), por lo cual se debe seguir con II9 a fin de que se efecte SI - 3000 = 3000- 3000
generndose Z=l. Por consiguiente I20 ordenar saltar a I27 para hacer [SI] ~ BH = 30, y as el cdigo 30 del O reempla-
za al cdigo 39 del 9 en la direccin 3000 apuntada por SI, quedando 0.0 en vez de 9.0 (obtenido despus del paso I12).
En el paso I28 se hace SI = SI - 1 = 3000- 1 = 2FFF; y se finaliza con I29 en el cual en la direccin 2FFF apuntada por
SI se escribe BL = 3l(ascii del 1) en lugar del valor XX existente(figura 3.31.b), resultando en definitiva el nmero 10.0 .
De haber sido N= 99.5 (figura 3.3l.c), como con' N = 9.6 , los pasos I17 e liS permitiran detectar que en 115 fue AL=39
(o sea Xn = 9 pero ahora en 3001), por lo cual se debe seguir con Il9 a fin de que se efecte SI--' 3000 = 3001 - .3000
3.29.a). generndose Z=O. Por lo tanto 120 ord<:nar seguir con 121 para hacer [SI] ~ BH = 30, y as el cdigo 30 del O reemplaza
U3-34 M.Ginzburg - Assembler desde Cero
al cdigo 39 del 9 en la direccin 3001 apuntada por SI, quedando 90.0 en vez de 99.0 (obtenido despus del paso I12).
El paso siguiente I22 ordena saltar incondicionalmenete Uump) a Il4 para volver a hacer SI= SI- 1 = 3001- 1 resultando
SI=3000 apuntando as (figura 3.3l.c) al cdigo 39 del 9 que est en 3000, y una copia del 39 ir hacia AL en I 15.
Al concretarse los pasos Il6 a Il8 se detectar que en el paso IIS estuvo el cdigo 39 de un 9 en AL; y siendo ahora
SI=3000 en el paso Il9 la resta SI- 3000 ser 3000-3000 y Z=l. Como ocurri para N= 9.6 con el 9 que estaba en 3000
en el paso 120 se ordenar saltar a la secuencia 127 a 129 antes vista, luego de la cual en lugar del 90.0 (obtenido despus
del paso I21) sucesivamente se formarn 00.0 y 100.0 que es el redondeo de 99.5 .
Lo mismo puede generalizarse para cualquier nmero cuya parte entera est formada slo por n nueves, siendo Y 2: 5.
Del diagrama de la figura 3.30 resulta la siguiente codificacin en Assembler:
MOVBH, 30 Queda en BH el cdigo 30 del dgito O
MOVBL, 31 Queda en BL el cdigo 31 del dgito 1
MOV SI, 2FFF Inicializa SI con la direccin 2FFF anterior a 3000
OTRO INC SI Suma uno a SI (SI=3000 en la primer vuelta)
MOV AL, [SI] El cdigo del dgito X que apunta SI (XI en la primer vuelta) pasa a AL
CMPAL,2E Resta AL - 2E (cdigo ascii del punto)
JNZ OTRO Mientras cdigo que est en AL =f. 2E repetir desde OTRO hasta localizar el punto.
INC SI Si en el paso anterior fue Z=l (AL=2E) aumenta uno a SI para localizar dgito Y
MOV AL, [SI] El cdigo del dgito Y que apunta SI pasa a AL.
CMPAL,35 Resta AL- 35 (cdigo ascii de Y menos cdigo ascii del5)
JB RED! Si (C=l) cdigo ascii de Y es menor que 35 (O :::; Y:::; 5) saltar a RED 1
MOV [SI],BH Si (C=O) cdigo ascii de Y 2: 35 (Y?: 5) que quede Y=O en lugar del valor de Y.
DECSI Resta uno a SI, as apunta a 2E, cdigo ascii del punto que est a la izquierda de Y
DIZQ DEC SI Otra vez resta uno a SI, as apunta al dgito Xn que est a la izquierda del punto.
MOV AL, [SI) El cdigo del dgito Xn pasa a AL en la ler vuelta del loop que se inicia en DIZQ
INCAL Suma uno al cdigo ascii del dgito que est en AL
CMPAL,3A Resta AL- 3A (3A = 39 + 1, siendo 39 el cdigo ascii del 9)
JNZ RED2 Si Z=O va a RED2 pues el cdigo analizado no es el del 9
CMP SI,3000 Si Z=l el cdigo analizado es del 9, y con SI -3000 se detecta si el 9 est en 3000
JZ RED3 Si en SI- 3000 fue Z=l saltar a RED3, pues est el ascii del9 en 3000 (XI= 9)
MOV [SI],BH Si en SI- 3000 fue Z=O va O en vez de ese 9, y hay otro dgito a su izquierda
JMP DIZQ Saltar a DIZQ pues hay otro dgito a la izquierda del ltimo 9 hallado.
RED! MOV [SI], BH Queda Y=O cualquiera sea el valor anterior de Y, pues va en su lugar BH=30 (O)
MOV [2FFF], BH En 2FFF va el ascii 30=BH del dgito O, para que el redondeo quede OX1X2...Xn.O
INT20 Fin
RED2 MOV [SI], AL Queda en el lugar del dgito Xn el valor anterior que tena su cdigo ascii ms uno
MOV [2FFF], BH En 2FFF va el ascii 30=BH del dgito O, para que el redondeo quede OXIX2...Xn.O
INT20 Fin
RED3 MOV [SI], BH Queda en la direccin 3000 el cdigo 30=BH del O en lugar del cdigo 39 del 9
DECSI Resta uno a SI
MOV [2FFF], BL En 2FFF va el ascii 3l=BL del dgito 1, para que el redondeo quede 1XIX2...Xn.O
INT20 Fin
1
EJERCICIO 18 Tcnicas para tepetir o no la ejecucin de secuencias mediante indicadores de pasada
Se tiene una lista de nmeros enteros cuya direccin inicial es 1000, siendo que la cantidad n de nmeros que
la conforman est en la direccin 1500. Copiar en otra lista que empieza en 2000 los nmeros comprendidos
entre 20 y 40; y para cada uno de stos escribir debajo de su valor el nmero de orden que tienen en la lista
originaria. Si en sta aparecen repetidos consecutivamente nmeros iguales que estn entre 20h y 40h,
escribirlos una sola vez en la nueva lista, con el nmero de orden del primero de los nmeros repetidos.
En la inicializacin se hace DL=O. De ac en adelante ste va a ser el valor de DL mientras no se encuentre tn nmero
N de la lista que est comprendido entre 20 y 40 (20 :::; N :::; 40).
Con este fin, en el diagrama lgico de la figura 3.31 en el paso 5 se enva cada nmero N apuntado por SI hacia AX
(AX=N); y en el paso 6 se aumenta uno el contador DH que va enumerando ordenadamente los n nmeros de la lista.
Su valor se usar cuando se escriba en la otra lista apuntada por DI el nmero de orden de un nmero N cuyo valor
corresponde copiar en ella.
El paso 7 ordena la resta AX- 20 para que tomen valor los flags SZVC. Si en el paso 8 se detecta S =f. V, (AX=N < 20)
hay que saltar al paso 18 donde se hace DL=O, esta vez para indicar que si por ejemplo es N=l5 < 20 no estar entre 20 y
40. Por consiguiente el paso 19 ordena saltar incondicionalmente Uump) hacia el paso 15, que junto con el 16 y 17 permi-
ten volver al paso 5 para pedir el nmero N que sigue en la lista, mientras sea Z=O (CL =f. 0).
En caso que en el paso 8 se detecte S= V (AX=N?: 20), el nmero N puede llegar a estar entre 20 y 40.
1
Este programa fue desarrollado por la Lic. Graciela Silvia D' Agostino, profesora de la UTN Regional Haedo
- esde Cero M,Ginzburg- Assembler desde Cero U3-35
MOV CL, [1500] A la izquierda comienza la codificacin en Assembler relativa a la figura 3.32
MOV SI, 1000
MOV DI, 2000
MOV DX,O Pone en cero a DL (indicador del paso por una secuencia) y DH (contador de orden)
OTRO MOV AX, [SI) Pasa hacia AX una copia de un nmero N de la lista apuntada por SI
INCDH Cada vez que se toma un nmero nuevo de la lista se suma uno al contador de orden DH
S. CMPAX,20 Resta AX- 20 para que SZVC tomen valores
JL NOES Si S=FV resulta AX < 20 entonces saltar a NO ES
-un nmero CMP AX, 41 Resta AX- 40 para que SZVC tomen valores
JG NOES Si S=V resulta AX ?. 41 (o sea AX > 40) entonces saltar a NO ES
CMPDL,O Se hace DL- O si S-:FV, pues AX < 41 (o sea AX :540, y hasta ac ser 20 :S AX :S 40)
lista. JZ ESCR Si Z=l es DL=O (siempre DL=O en la ler vuelta) se puede copiar N en la otra lista
CMP AX, [SI-2) Si Z=O es DL=l (ya se escribi en la otra lista) hay que ver si AXactual = AXanterior
JNZ ESCR Si Z=O (AXactual -::f AXanterior) no se repiten nros iguales. Copiar AXactual en otra lista
-\..X=N < 20)
. entre 20 y ALFA ADD SI, 2 Si Z=l (AXactual = AXanterior) suma 2 a SI para apuntar siguiente nmero de la lista
DEC CL Resta uno a la cantidad de nmeros que falta analizar en la lista apuntada por SI
~ 1 7 permi- Mientras sea Z=O saltar a OTRO para considerar el nmero siguiente de la lista
JNZ OTRO
INT20
NOES MOVDL,O Pone en O a DL pues N no est entre 20 y 40
JMPALFA Saltar incondicionalmente a ALFA (contina en la siguiente pgina)
U3-36 M.Ginzburg- Assembler desde Gero M,G
ESCR MOV [DI], AX Copia en la lista apuntada por DI el nmero N comprendido entre 20 y 40 EJER(
ADDDI,2 Suma 2 a DI para preparar debajo escritura del nmero de orden de N debajo de su valor Se ti
MOV[DI],DH Escribe en la direccin apuntada por DI una copia del nmero de orden que indica DH _00 1,!
INCDI Se actualiza DI por si en AX llega otro N comprendido entre 20 y 40
natural
MOVDL, 1 DL=I indica que ya se escribi en la lista apuntada por DI, por si el siguiente N es igual
JMP ALFA de los
Salta incondicionalmente a ALFA -
de la
(Continuacin de la explicacin anterior) Si luego del primer N de valor 35, o luego de k repeticiones del mismo, el modifi
siguiente N apuntado por SI que lleg a AX es distinto (por ejemplo 29), pero est comprendido entre 20 y 40, se pasar
nuevamente por los pasos 5 al 14 (y seguir siendo DL= 1); pero en el paso 14 resultar Z=O por ser distintos.el N actual y
el anterior; y en este paso se ordenar saltar al paso 20 para escribir el valor y el nmero de orden del nuevo N que
tambin est entre 20 y 40. Asimismo en el paso 24 se ratifica que seguir siendo DL=I, hasta que en AX llegue un N
que no est comprendido entre esos valores, que har DL=O.
En definitiva con DL=I cuando en la lista apuntada por DI hay nmeros consecutivos iguales que estn entre 20 y 40, se
garantiza que mientras ello suceda slo se escribe el valor y nmero de orden del primero de ellos, o sea que se pasar
una sola vez por la secuencia que permite dicha escritura.
EJERCICIO 19: FI
Un nmero que est en la direccin 1500 agregarlo al final de una lista no ordenada de nmeros de un byte
que empieza en 2001 si dicho nmero no se encuentra en la lista. Asimismo, aumentar en uno el nmero de PO
elementos de la lista que est en la direccin 2000. A1l
MOV CL, [2000] Carga en CL la cantidad de nmero inicial de la lista
MOV BH, [1500] Carga en BH el nmero en cuestin
MOV SI, 2001 Inicializa SI para que apunte al comienzo de la lista
OTRO CMP BH, [SI] Compara el nmero que est en 1500 con uno de la lista
JZ FINE Si Z=l (los nmeros comparados son iguales), saltar a FINE
INC SI Incrementa SI
DEC CL Decrementa CL
JNZ OTRO Mientras Z=O, volver a OTRO
MOV [SI],BH Si Z=I el nmero no est en la lista, por lo que ir al final de ella
MOV CL, [2000] Carga nuevamente en CL la longitud de la lista
INC CL Incrementa la cantidad de nmeros
MOV [2000], CL Guarda en 2000 la nueva longitud de la lista
FINE INT 20 Fin
EJERCICIO 20:
Se tiene una lista de nmeros de un byte que empieza en la direccin 2001, siendo que su cantidad est en la
direccin 2000. Determinar si el nmero contenido en la direccin 1500 se halla en la lista que comienza en
la direccin 2001, siendo que la cantidad de nmeros de la lista est en la direccin 2000.
En caso que el nmero que est en 1500 sea uno de la lista (salvo el ltimo), reemplazarlo por el que le sigue,
ste por el siguiente, y as sucesivamente, de modo de recibir todos los nmeros que siguen al hallado, subindolos
una posicin. Asimismo, restarle uno a la longitud de la lista que est en la direccin 2000. O
MOV CL, [2000] Carga en CL la cantidad de numeros de la lista
MOV SI, 2001 Registro SI apunta al comienzo de la lista de datos
MOV AL, [1500] Carga en AL el nmero a contrastar contenido en 1500
OTRO CMP AL, [SI) Resta al nmero que est en AL el nmero apuntado por SI p
JZ ALFA Si son iguales (el nmero est en la lista) saltar a ALFA
INC SI Incrementa SI
DEC CL Decrementa CL
JNZ OTRO Mientras Z=O, volver a OTRO
INT20 Fin
BE
ALFA MOV BL, [2000] Carga en BL la cantidad de nmeros de la lista
DEC BL Decrementa la cantidad de nmeros de la lista
MOV (2000) , BL Guarda la nueva cantidad de nmeros de la lista
DECCL Decrementar CL que lleva la cuenta de los nmeros que faltan analizar
JZ FINE Si es el ltimo elemento de la lista saltar a FINE
POST MOV AL, [SI+1] Si no es el ltimo, cargar en AL el elemento siguiente E.JER.C
MOV [SI], AL Guarda en el lugar de un elemento, el que le sigue Se
INC SI Incrementa SI
DEC CL Decrementa CL ,
JNZ POST Mientras Z=O, volver a POST para leer el nmero siguiente
FINE INT 20 Fin
eOero M,Ginzburg- Assembler desde Cero U3-37
EJERCICIO 21:
'i'3lor Se tiene una lista de nmeros naturales de un byte, ordenados en forma creciente, a partir de la direccin
:m 2001, siendo que en la direccin 2000 est la cantidad de nmeros. En la direccin 1500 se tiene un nmero
natural de un byte. Intercalarlo segn su valor en la lista citada, reubicando una posicin ms abajo cada uno
de los nmeros de la lista que le siguen (salvo que sea el ltimo). Asimismo, incrementar en uno la longitud
de la lista, que est en la direccin 2000. Si el nmero a intercalar ya se encuentra en la lista, sta no debe
;;;;srn o, el
modificarse.
MOV CL, [2000) Carga en CL la cantidad de nmeros a analizar
MOV SI, 2001 Registro SI apunta al comienzo de la lista de datos
MOV AL, [1500] Carga en AL el nmero a intercalar
OTRO CMP AL, [SI] Resta al contenido de AL, el nmero apuntado por SI
JA PONE Si el nmero de la lista es mayor hay que intercalar, saltar a PONE
. 40, se JZ FINE Si son iguales (est en la lista) saltar a FINE
se pasar INC SI Incrementa SI
DEC CL Decrementa CL
JNZ 0107 Mientras Z=O, volver a OTRO
FINE INT 20 Fin
nn byte
ero de PONE INC CL Incrementa CL, pues hay un elemento ms
ABAJ MOV AH, [SI) Salva el nmero que apuntaba SI en AH
MOV [SI], AL Guarda el nmero a intercalar (u otro a "bajar") donde apunta SI
MOVAL,AH Lleva a AL el prximo nmero a "bajar"
INC SI Incrementa SI
DEC CL Decrementa CL
JNZ ABAJ Mientras Z=O, volver a ABAJ
MOV BL, [2000) Carga en BL la longitud de la lista
INCBL Incrementa BL
MOV [2000], BL Guarda en 2000 la cantidad de nmeros incrementada
INT20 Fin
EJERCICIO 22
La siguiente secuencia puede ser parte de un programa para verificar el estado de la memoria de un
computador. Se trata de escribir ocho "unos" en cada una de las posiciones de memoria que van de la
direccin 4000 a la 5000. Luego se debe verificar que realmente existan ocho "unos" en cada una de las
~ est
en la posiciones escritas. La direccin de las posiciones que no presenten ocho "unos" (posiciones defectuosas)
enza en deben guardarse en una lista que comienza en la direccin 2000.
MOV SI, 4000 El registro SI apunta a la direccin 4000
le sigue, MOV DI,2000 DI apunta al comienzo de la lista de direcciones
"ndolos MOV AL,FF AL se carga con 8 "unos"
OTRA MOV (SI], AL El contenido de AL pasa a la posicin apuntada por SI
INC SI Incrementa SI
CMP Sl,5001 Resta 5001 (una direccin ms que el lmite 5000) al valor de SI
JNZ OTRA Mientras SI no sea 5001 volver a O108
MOV SI,4000 El registro SI apunta otra vez a la direccin 4000 para verificar las escrituras
PROX MOV AL, (SI] El contenido de la posicin apuntada por SI pasa a AL
CMP AL,FF Resta FF al valor de AL
JZ BIEN Si Z=l, ir a BIEN
MOV (DI], SI Guarda en otra lista la direccin (dada por SI) de una celda que no tiene 8 "unos"
BIEN ADD DI, 2 Suma 2 a DI (las direcciones ocupan 2 bytes)
INC SI Incrementa SI
CMP SI, 5001 Resta 5001 (una direccin ms que el lmite 5000) al valor de SI
JNZ PROX Mientras SI no sea 5001 volver a PROX
INT 20 Fin
EJERCICIO 23
Se tiene una lista de nmeros enteros de un byte cada uno, que empieza en la direccin 2000, siendo que la
cantidad de los mismos est en la direccin 1500. Pasar los nmeros a otra lista, donde cada nmero ocupe
16 bits, de modo que a los nmeros con bit de signo O se le agreguen 8 ceros a la izquierda, y a los nmeros
con bit de signo 1 se le agreguen 8 unos a la izquierda (propagacin de signo).
U3-38 M.Ginzburg- Assembler desde Cero
-----------------------------------------------------------,
MOV CL, [1500] Carga en CL la cantidad de nmeros de la lista
MOV SI, 2000 El regi~tro SI apunta al comienzo de la lista d.;: ttu~
MOV DI, 3000 DI apunta al comienzo de la lista de resultados
OTRO MOV AL, [SI] Carga en AL un dato de la lista apuntada por SJ
CMP AL,O Compara el dato en AL contra O
JGE POSI Si es mayor o igual que cero (positivo) sJlta a l'TVO
MOVAH,FF Como es menor que cero (negativo), carga 8 uws en AH para propagar signo
ESCR MOV [DI], AX Carga en la lista apuntllda por DI el nuevo nmero de 16 bits
INC SI Incrementa SI
ADD DI,2 Suma 2 a DI (los nmeros resultantes ocupan 2 bytes)
DEC CL Decrementa CL
JNZ OTRO Mientras Z=O, volver a OTRO
INT 20 Fin
PTVO MOV AH, 00 Carga 8 ceros en AH para propagar signo
JMP ESCR Saltaa ESCR
EJERCICIO 24:
Se tiene una lista de caracteres ASCII que empieza en 2000, dentro de la Cl!al se tiene un mensaje de n
caractP.res entre el caracter 02 = STX (start oftext), y el caracter 03 = ETX (end oftext) de dicha lista.
Hallar el nmero n de caracteres del mensaje e indicarlo en la direccin 1500.
. ~ .
MOV SI, 1FFF Registro SI apunta al comienzo de la lista menos t,no
OTRO INC SI Incrementa SI
MOV AL,02 Carga 02 = STX en AL
CMPAL, [SI] Compara AL con el nmero apuntado por SI.
JNZ OTRO Si el caracter de la lista es distinto de stx, saltar a OTRO
MOV CX, -1 Pone en -1 al contador
MOV AL,03 Carga 03 = ETX en AL
INC CX Incrementa CX
PROX INC SI Incrementa SI
CMP AL, [SI] Compara AL con el nmero apuntado por SI.
JNZ PROX Mientras Z=O, volver a PROX
MOV [1500], CX Guarda en 1500 el resultado
INT20 Fin
EJERCICIO 25
Se tiene un nmero decimal codificado en ASCII, con parte entera y parte fraccionaria separadas por un
punto (codificacin 2E en ASCII). El nmero, como se indica, ocupan posiciones consecutivas de memoria,
a partir de la direccin 2001, siendo que en 2000 se indica cuntas posicione" ocupa. En caso que se trate de
un nmero entero, sin parte fraccionaria, no lleva punto.
Reemplazar los dgitos fraccionarios que estn a la derecha del punto, por el cdigo ascii del espacio (SP=20)
Ejemplo:
2000 05 2000 05
2001 34 (4) 2001 34
2002 33 (3) 2002 33
2003 2E (.) ==> 2003 2E
2004 (5) 2004 20
2005 (O) 2005 20
Antes Despus
~ gno
Los tres ejercicios siguientes tienen como objetivo relacionar la programacin en alto nivel con su traduccin
en bajo nivel, en este caso con diagramaa lgicos correspondientes a estructuras tpicas en alto nivel; y
tambin permiten sistematizar la correspondencia entre variables y direcciones de memoria
EJERCICIO 26:
Dada la siguiente codificacin en n lenguaje de alto nivel:
INTEGERS
IF 20 :S N :S 40 THEN Q=N
ELSE Q=O
-~ e de n
Suponiendo que sea traducida por un traductor tipo Compilador, que usa las direcciones 1000 y 2000 para el
tipo de variables definidas:
a) Indicar p~ra el tipo de variables definidas, cmo aparecen en memoria
b) Con vistas a traducir la codificacin planteada en alto n ivel a bajo nivel, en un diagrama lgico, del tipo
usado en ejercicios anteriores, expresar lo que dicha codificacin planteada ordena.
e) Construir el diagrama lgico '
a) Ver figura 3.33.a
b) En las direcciones 3000/1 de memoria se tiene un nmero entero N. Si 20 :S N :540 escribir una copia de
N en las direcciones 400011; caso contrario escribir un cero en estas direcciones
e) Ver figura 3.33.c
a
v't
por un
Figura 3.34.a
memoria,
~ se trate de
io (SP=20) 100~~N--
2000 -Q -
1
Figura 3.33.a
)espus
EJERCICIO 27:
Dada la siguiente codificacin en un lenguaje de alto nivel:
FOR i = 1 to n
IF 20 :S X :S 40 THEN Q[i] = X[i]
punto ELSE ' Q[i] = O
co)
U3-40 M.Ginzburg- Assembler d;:sde Cero
Suponiendo que sea traducida por un traductor tipo Compilador, que usa las direcciones 1000 y 2000 donde
empiezan el tipo de variables definidas, y la direccin 1500 para guardar la cantidad n de nmeros:
a) Indicar para el tipo de variables definidas, cmo quedan en memoria
b) Con vistas a traducir la codificacin planteada en alto nivel a bajo nivel, en un diagrama lgico, del tipo
usado en ejercicios anteriores, expresar lo que dicha codificacin planteada ordena.
e) Construir el diagrama lgico.
a) Ver figura 3.34.a
b) Se tiene una vector de enteros X[i] que empieza en 2000 conformada por n nmeros, siendo que n est en la di-
reccin 1500. Analizar cada nmero X del vector: si 20 :S X :S 40 copiar su valor X en otra lista que empieza en 3000, en
el mis-mo orden que tena en la lista que empieza en 1000; caso contrario, siguiendo dicho orden escribir 0000 en lugar
de X.
e) Ver figura 334.c. En ella como las dos listas deben progresar juntas se us SI+ 1000 para apuntar la segunda
EJERCICIO 28:
Dada la siguiente codificacin en un lenguaje de alto nivel:
m=l
n=l
FOR i = 1 to n {
IF 20 :S N :S 40 THEN { Z[m] = i;
m= m+l}
ELSE {Y[n] = i;
n = n+ 1 } }
El
Suponiendo que sea traducida por un traductor Compilador, que usa las direcciones 2000, 3000 y 4000 co~
donde empiezan el tipo de variables definidas, y la direccin 1500 para guardar la cantidad n de nmeros
enteros a analizar.
a) Indicar para el tipo de variables definidas, cmo se presentan en memoria
b) Con vistas a traducir la codificacin planteada en alto nivel a bajo nivel, en un diagrama lgico, del tipo
usado en ejercicios anteriores, expresar lo que dicha codificacin planteada ordena.
e) Construir el diagrama lgico
a) Ver figura 3.35.a
b) Se tiene una lista (vector) de enteros N[i] que empieza en 2000 conformada por n nmeros, siendo que n est en la
direccin 1500. Analizar cada nmero N del vector, y como indica la figura 3.35.a:
Si 20 :S N :S 40 escribir su nmero de orden i en otra lista que empieza en 3000, debajo del nmero de orden del ltimo
nmero que verific la condicin anterior.
Si Ni no est entre 20 y 40 escribir su nmero de orden i en otra lista que empieza en 4000, debajo del nmero de
orden del ltimo nmero que tampoco verific la condicin anterior.
En la figura 3.35.a se supone que N[!] y N[4] estn entre 20 y 40, y que no lo estn N[2] y N[3].
e) Ver figura 335.c. En sta como las listas 2 y 3 deben progresar juntas se us DI+ 1000 para apuntar la lista 3.
DISn
D03
I) ca
A
codifil
est a
lo q -
- Si
di.recci
- S
eje
y si se
M,Ginzburg- Assembler desde Cero U3-41
~e Cero
CONSIDERACIONES GENERALES PARA PROGRAMAR EN ASSEMBLER
donde
1. Tener bien en claro qu se quiere o se pide hacec.
2. Planificar todos los movimientos y operaciones a realizar mediante esquemas espaciales UCP-Memoria, como los
l tipo indicados en los ejercicios 1 a113 .
3. Realizar un diagrama lgico que simbolice lo planificado en el paso 2.
4. Suponer valores a los datos y realizar una prueba de "escritorio" para verificar el corr~cto desarrollo del diagrama
5. Llevar a cabo la codificacin Assembler del diagrama lgico obtenido en 3.
la di-
;:o Cuando se efectan las fases 2 y 3 se debe tener presente que los programas empiezan inicializando los registros elegidos
OOO, en y que en el caso de una lista o vector, si se conoce la cantidad n de nmeros que la conforman siempre es posible termi-
en lugar narlos con las instrucciones DEC CL seguida de JNZ, a fin de volver a pedir el nmero siguiente de la lista mientras sea
CL :f. O bien seguir con el almacenamiento de resultados en memoria, si el ejercicio as lo exige.
Si se conoce cmo finalizar los diagramas sobre listas, ello facilita su construccin, pues dado que la fase de inicializa-
cin de registros con valores es sencilla, la programacin debe centrarse en el desarrollo del procedimiento que el lazo
debe repetir (en grisado en los diagramas lgicos, y en negrita normal en la codificacin en Assembler).
El registro CL se usar como contador regresivo para guardar inicialmente la cantidad 11 de nmeros o elementos que
! 4000 conforman una lista o vector (siempre que 11 sea un dato conocido)
eros Los registros SI y DI sern usados como punteros, pura guardar los 16 bits de las 'irecciones de !as listas que ellos
apuntan, y si se requiere una tercer lista se usar BX como puntero. Esto es, los nico~ registros que en Assembler se
pueden poner entre corchetes son SI, DI y BX. Por ejemplo:
2rl tipo MOV AX, [SI] ; ADD AX, [BX] ; SUB AL, [DI] ; MOV [BX], DL. No existen instrucciones como MOV DX, [AX].
En programas .COM (que son los que por defecto se usan con el Debug) tambin se puede emplear el registro BP (Base
Pointer) de la UCP usado como puntero en llamados a subrutinas. Por ejemplo podra ser ADD CX, [BP].
Los registros SI y DI no pueden partirse en dos registros de 8 bits (como ser DIH o DILo SIH, etc.) lo cual s puede
hacerse con BH y BL de BX, cuando se usa a BX como acumulador (como ser en SUB BH, [SI] o en SUB BL, [SI]).
en la Las instrucciones del tipo MOV AX, [SI] ; ADD AX, [BX] ; SUB AL, [DI]; MOV [BX], DL se usan para puntear ele-
mentos de una lista.
- ltimo Cuando el corchete est a la derecha de la coma se estn leyendo (copiando) dos celdas consecutivas de memoria que
pasan a un registro como en MOV A,'(, [SI], o una sola como ocurre con MOV AL, [DI], pues AX es un registro para 2
o de bytes, mientras que AL es para un byte.
Si el corchete est a la izquierda implica que la operacin ordenada dejar el resultado en una posicin de memoria
indicada por el registro puntero involucrado, y se escribirn uno o dos bytes segn que el registro de origen sea para un
byte (por ejemplo MOV [DI], BH) o de dos (como en MOV [DI], BX ).
Tambin son posibles instrucciones como MOV [DI], SI MOV [3000], SI en la que una copia del contenido del punte-
ro SI se guarda en dos posiciones de memoria. En la primera de ellas la direccin est indicada por el puntero DI.
Si se tiene dos listas wyos punteros deben progresar juntos siempre el mismo valor, puede usarse un solo puntero, segn
se ilustra en los ejercicios 16, 26 y 27. Esto tambin podra haberse hecho en el ejercicio 7.
Lo anterior puede extenderse a ms de dos listas si se cumple para todas lo antedicho, (\:fin de ocupar menos registros.
DISTINTAS FOR.J.'v!AS DE REALIZAR UNA MISMA OPERACIN SEGN DONDE EST UNO DE LOS DATOS o
DONDE VA EL RESULTADO
1) Casos de lectura o escritura de memoria, (instrucciones con un par de corchet es (!!Q puede haber dos pares)
A continuacin se indican cuatro formas para indicar en memoria donde est un dato o dnde se guarda un resultado,
codificadas en Assembler para operaciones MOV, ADD, SUB, CMP, etc., con datos o resultados de d os bytes.
- Cuando se tiene en memoria un dato aislado, o sea que no forma parte de una lista (vector), suponiendo que el mismo
est en las direcciones 2000/1 y que se lo quiere llevar hacia el registro AX, la instruccin ser MOV AX, [2000]; y si se
lo quiere sumar con el contenido de AX y dejar el resultado en AX, la instruccin ser ADD AX, [2000] .
- Si un dato o resultado est por ejemplo en AX, y una copia del mismo se lo quiere escribir en memoria, como ser en las
direcciones 2000/1 que no forman parte de las direcciones de una lista, la instruccin ser MOV [2000] , AX.
- Suponiendo que en memoria se tiene un dato que forma parte de una lista (vector), cuya direccin est apuntada por
ejemplo por el valor del registro SI, y una copia de este dato se quiere enviar hacia AX, la instruccin ser MOV AX, [SI]
y si se quiere sumar este dato con el valor de AX y dejar el resultado en AX, la instrll\:cin ser ADD AX, [SI].
U3-42 M.Ginzburg- Assembler desde Cero
Con SI=2000, dicho dato ocupar las direcciones 2000/1 de la lista de la que forma parte.
- Si un dato o resultado est en AX, y una copia del mismo se quiere escribir en dos celdas de memoria apuntadas por SI
que forman parte de una lista (vector), la instruccin ser MOV [SI], AX. De ser SI=2000, la escritura se har en ias
direcciones 200011.
Lo anterior vale tambin si en vez de AX se usa BX, CX o DX, o si en vez de SI se usa DI o BX.
En cualquier caso se debe tener presente que luego de leer o escribir un elemento de una lista se debe actualizar (indexar)
el valor del puntero, SI, DI o BX a fin de leer o escribir el elemento siguiente si corresponde. Si interviene un registro
terminado en X, como AX, se debe sumar 2 al puntero, para localizar un elemento que est dos direcciones ms abajo.
Para los casos anteriores si el dato o resultado ocupa un byte, y si usamos el registro AH, las instrucciones sern:
MOV AH, [2000]; ADD AH, [2000]
MOV [2000], AH
MOV AH, [SI] ; ADD AH, [SI]
MOV [SI], AH
Para todas las instrucciones anteriores si se supone 2000 la direccin involucrada, en la misma se lee o excribe un byte.
Los ejemplos dados tambin permiten afirmar que en las instrucciones donde intervienen AX, BX, CX, DX los operandos
o resultados ocupan 2 bytes; mientras que si son registros terminados en H L, los mismos ocupan un byte.
NO es factible realizar MOV ( ),( 1 como ser MOV [SI], [DI] ; ni ADD ( ),[ ) como ser ADD [3000] , [DI]
CMP [SI], [3000], etc., o sea en una misma instruccin no puede haber dos pares de corchetes.
Esto es, no se puede pasar informacin de memoria a memoria, ni los dos datos a operar pueden estar en memoria.
Si se quiere efectuar esas operaciones con dos corchetes, se debe "triangular" a travs de cualquier registro disponible:
As, MOV [SI], [DI] puede hacerse como MOV DX, [DI] seguido de MOV [SI], DX si el dato es de dos bytes.
ADD [3000], [DI] puede hacerse como ADD DH, [DI] seguido de ADD [3000], DH si el dato es de un byte.
Las instrucciones que en el corchete tienen un nmero que es directamente la direccin a acceder se conocen como ins-
trucciones en modo directo; y las que en el corchete un registro provee la direccin son en modo indirecto por registro.
2) Casos de operaciones entre registros (instrucciones en modo registro)
Ocurren cuando se copia informacin de un registro a otro de la UCP, o si un dato est en un registro y el resultado va a
otro registro (que puede ser el mismo). Por ejemplo: MOV AX, SI ; ADD AL, BH; SUB AX, AX etc.
Este tipo de instrucciones se ejecutan ms rapidamente que las que tienen corchete, pues no se debe acceder a memoria.
NO deben realizarse operaciones entre registros de distinto tamao, como ser MOV AL, SI ; ADD AL, CX
No son factibles instrucciones del tipo MOV [ ), constante por ej. MOV [3500], FF o SUB [2000], 4000 etc.
Estas operaciones necesitan " triangulacin" a travs de un registro: primero MOV CH, FF y luego MOV [3500], CH
Lo planteado para JZ vale para cualquiera de las instrucciones de salto de las figuras 3.15 y 3.16 a las que siempre
conviene consultar cuando se elige una instruccin de salto condicional. Igualmente se deben tener presente las
generalizaciones respecto de las mismas que siguen al ejercicio 5.
En relacin con la eleccin del valor de los flags que intervienen en la condicin de la instruccin de salto debe tenerse en
byte.
cuenta los ejercicios 5, 6 y 9 donde puede verse la conveniencia de analizar atentamente la eleccin del valor del flag
operandos 1
de la condicin. Si se elige el valor contrario al apropiado trae aparejado una mala estructuracin de un programa
El valor (06) que acompaa al cdigo de operacin de una instruccin de salto (como era en 7406), es un nmero entero
de un byte. Este puede ser un nmero negativo que va de 80h = lOOOOOOOb = -128d hasta 11111111 b = -Id (cuando se
quiere sumar al IP un valor negativo para que se salte hacia atras, como debe ser en un lazo); o un positivo que va de
00000000 = O, hasta un mximo 7Fh = O1111111 b = 127 d (cuando se quiere saltar hacia delante).
En definitiva en un salto condicional no se puede saltar ms que 128d celdas hacia atrs de la direccin que sigue a la de
salto, o hasta 127d celdas hacia delante de dicha direccin.
Los valores lmites 80 7F que calcula el Ensamblador no pueden ser superados, pues de ser as habr indicacin de error
Por ejemplo esto sucedera si se codifica OllE JZ 0200, dado que la resta 0200-0120 superara 7F.
aXI igo de
U3-44 M.Ginzburg- Assembler desde Cero
Se tiene una lista de caracteres ASCII. Formar otra lista en la que vayan solamente elementos consecutivos iguales
de la primera lista cuyo nmero de repeticiones est comprendido entre 3 y 8 inclusive.
Se tiene una lista de nmeros enteros. Formar otra lista con los menores de 50 y los mayores de 80. Si entre estos
nmeros hay repetidos consecutivos iguales, pasar el primero de ellos a otra lista slo si el nmero de repetidos
supera 3.
Se tiene dos listas de igual longitud con nmeros enteros. Considerar los elementos correspondientes. Determinar
cul es el mayor y restarlo del menor. En otra lista guardar esta diferencia y la direccin del mayor. Si los nmeros
son iguales seguir con lo nmeros siguientes.
Encontrar la cantidad de mxima de nmeros impares que hay en una lista de n nmeros binarios enteros de dos
bytes
Se tiene 2 listas de igual cantidad de nmeros enteros. Considerar los elementos correspondientes y determinar cul
es el mayor y restarlo del menor. En otra lista guardar la direccin del mayor y el valor de la diferencia hallada. Si .
los nmeros correspondientes son iguales, seguir con los nmeros siguientes.
Se tiene una lista de n caracteres codificados en ascii. Formar otra lista en la que no haya caracteres consecutivos
iguales que vayan los comprendidos entre 30 y 60. Guardar en una tercer lista la direccin donde comenz en cada
sucesin de consecutivos el primer caracter de los repetidos, y en una direccin de memoria la cantidad de caracteres
de la segunda lista.
Se tiene una lista de n caracteres codificados en ascii. Formar otra lista en la que vayan solamente el primero de cada
grupo de caracteres consecutivos repetidos de la primera lista cuyo nmero de repeticin est entre 3 y 8.
Recorrer 2 listas de igual nmero n de caracteres codificados en ascii. Si se encuentran dos pares de caracteres
correspondientes iguales, guardarlos en dos posiCiones consecutivas de memoria.
Se tiene una lista de n nmeros enteros. Sumarle 3 a cada uno y el resultado escribirlo en otra lista. Si el resultado
genera overflow, escribir ABCD en lugar del resultado de la suma.
Se tiene una lista de n caracteres codificado en ascii. Si alguno de ellos es mayor que 40 saltear al carcter siguiente;
si es menor colocar 31 en su posicin, y si es igual que 40 sumarle 3, pasando a otra lista el resultado.
Se tiene dos listas con igual nmero n de caracteres codificados en ascii. Si elementos correspondientes de ambas o
listas valen 30, reemplazarlos en ambas listas por EE; y si valen 20 sumarle a cada uno el contenido de la posicin
anterior. En cualquier otro caso dejar las listas como estn.
Se tiene dos listas con igual nmero n de nmeros naturales, Analizar cada par de elementos correspondientes. Si a
un nmro N de la lista 1 le corresponde otro que sea N+ 1 en la lista 2, guardar en otra lista 3 el N de la lista 1, y
debajo del mismo la direccin donde se encontraba en esta lista. Asimismo contar la cantidad de estos sucesos, y si
su nmero supera 1O detener el programa.
~e Cero M,Ginzburg- Assembler desde Cero U3-45
EJERCICIO 30: uso de JBE (Jump if below or equal)
A partir de 2001 se tiene una lista de combinaciones binarias de un byte que corresponde cada una a dgitos
re, sin que hexadecimales aislados (0, 1, 2, ... F), siendo que el nmero n de combinaciones est en la direccin 2000.
instruc- Convertir cada dgito hexadecimal a su correspondiente carcter ASCII segn se ejemplifica a continuacin.
:an natura-
Los caracteres ASCII obtenidos guardarlos en otra lista que comienza en 300 l.
!decuada.
eltos; en Binario Hexa ASCII
ros. 2001 00000000 (00) 3001 00110000 (30)
2002 00000100 (04) 3002 00110100 (34)
2003 00001001 (09) > 3003 00111001 (39)
2004 00001010 (OA) 3004 01000001 (41)
la celda 00001101 (OD) 3005 01000100 (44)
2005
2006 00001111 (OF) 3006 01000110 (46)
tia que no
cer lista la Si dato < 9 es en ASCII igual a dicho dato+ 30
.z nmeros Si dato > 9 es en ASCII igual a dicho dato + 7 + 30
Por ejemplo:
ms iguales Dato= 00001010 =A
+7 = + 111
00010001
entre estos +30 = 00110000
le repetidos 01000001 = 41 en ASCII
EJERCICIO 32: uso de la instruccin JPE (Jump if parity is even =Saltar si la parid ad es par)
Se tiene una lista de caracteres ASCII a partir de la direccin 2001, siendo que su nmero n est en la direc-
cin 2000. Si la paridad de unos de cada uno de los caracteres es par, escribir 00 en la direccin 3000; y si
algn carcter presenta paridad impar de unos, escribir FFH en la direccin 3000. 01
EJERCICIO 34:
Se tiene una lista de nmeros naturales de un byte, que empieza en la direccin 2001, y se la quiere ordenar
en forma creciente. La longitud de la lista est en la direccin 2000.
El mecanismo de ordenacin que usaremos es el de "burbujeo", como se ejemplifica a continuacin Otra for
Los crculos indican comparaciones realizadas; y las flechas, los casos en que hubo infercambio de lugar entre 2 nmeros.
Inicio Primer Luego deller Segundo Luego del 2do Tercer Luego del 3er Cuarto Luego 4to
Ordenam ordenamiento ordenam. Ordenamiento ordenam ordenamiento ordenam ordenam.
~ ~
6 4 4 2 2
4
8
2 f. " 6
8
6
2
8
2
6
8 8
4 4
6
8
4
6
8
Sde Cero M,Ginzburg- Assembler desde Cero U3-47
INIC MOV DL, 1 Asume con la indicacin DL = 1 que no se produjo ningn cambio
direc- MOV CL, [2000] Carga en CL la longitud inicial de la lista
; y si MOV SI,2001 Inicializa SI para que apunte al comienzo de la lista
OTRA MOV AL, [SI] Carga en AL un dato de la lista
CMP AL, [SI+ 1] Compara e! nmero que est en AL con el siguiente
JBE INCR Si es menor o igual saltar a INCR para seguir recorriendo la lista
XCHG AL, [SI+1] Intercambia el contenido de AL con el de memoria apuntado por SI+ 1
MOV [SI], AL Guarda el nuevo contenido de AL en la direccin apuntada por SI
MOV DL,O Asume con la indicacin DL = O que hubo un intercambio
INCR INC SI Incrementa SI
DEC CL Decrementa CL
JNZ OTRA Mientras Z=O, volver a 109
CMP DL,O Compara el nmero que est en DL con 00
JZ INIC Si es 00 (Z=l) salta a 100 para iniciar un nuevo ordenamiento
INT20 Fin (recorriendo la lista no se produjeron ms intercambios)
~la suma EJERCICIO 35: uso del modo indirecto por registro con desplazamiento mediante valor de registro
con la De la direccin de memoria 2000 a la 2009 se tiene una lista con los cuadrados de los nmero binarios del O
al 9. En las direcciones 3000 y 3001 se tiene dos nmeros Ni y N2, naturales de un byte, comprendidos entre
que de O y 9 inclusive. Se necesita sumar .l os cuadrados de Ni y N2, y el resultado dejarlo en 3002 y 3003
EJERCICIO 37
Se tiene una lista de nmeros naturales de un byte, que comienza en la direccin 2001, cuya longitud se
indica en la direccin 2000. Hallar el promedio de dichos nmeros, y guardarlo en la direccin 1500
MOV CL, [2000] Carga en CL la longitud de la lista
MOV SI, 2001 SI apunta al comienzo de la lista de datos Para n
SUB AX,AX Pone AX en cero anteric
SUMA ADD AL, [SI) Suma a AL un nmero de la lista apuntada por SI En el t
ADCAH,OO Lleva en AH la suma de acarreos que ocurren cuando las sumas superan tendr
el formato de AL (Hace AH <=AH + 00 + Carry = AH + Carry) Tamb
INC SI Incrementa SI
DEC CL Decrementa CL EJERI
JNZ SUMA Mientras Z sea O, volver a SUMA Secu
MOV BL, [2000] Carga en BL la cantidad de nmeros de la lista La lis1
DIVBL Hace AL 1 BL; el cociente va a AL, y el resto a AH Ejempl
MOV [2000), AL Guarda en 2000 el resultado de la divisin (el promedio) 98 = 9l
INT20 Fin lOOlit
Se tiene a partir de la direccin 200 1 una lista de dgitos aislados codificados en ASCII, que ocupan un
nmero par de posiciones de memoria. Este nmero se indica en la direccin 2000. Convertir cada dos
dgitos ASCII consecutivos en un byte BCD empaquetado, que se almacenan a partir de la direccin 3001.
Ejemplo: OTR<
DATOS
xxxx:2000 04. 31. 32. 35. 38
RESULTADOS
xxxx:3001 12. 58.
MOV DL, [2000] Carga en DL la longitud de la lista
MOV SI, 2001 Inicializa SI para que apunte al comienzo de la lista de datos
MOV DI, 3001 Inicializa DI para que apunte al comienzo de la lista de resultados
MOV AL, [SI] Carga en AL un dato de la lista
OTRA MOV BL, [SI+1) Carga en BL el dato siguiente de la lista
AND AL,OF Pone en O los 4 bits ms altos de AL
AND BL,OF Pone en O los 4 bits ms altos de BL
MOVCL,4 Prepara CL para indicar 4 rotaciones
ROL AL,CL Rota 4 veces el contenido de AL
ORAL,BL Forma el byte empaquetado EJER<
MOV [DI], AL Guarda el byte empaquetado en la otra lista Desde
INC DI DI apunta al siguiente lugar el res
ADD SI, 2 SI se incrementa 2, pues ya se tomaron dos datos consecutivos
SUB DL,2 A la longitud se le resta 2, pues se tomaron dos datos consecutivos
JNZ OTRA Mientras Z sea O, volver a OlOA
INT 20 Fin OTI
La instruccin AND AL, OF realiza bit a bit la operacin lgica And (A) entre el valor de AL y el nmero OF, conforme
a dicha operacin And: O A O= O; O A l =O; 1 A O= O; 1 A 1 = l.
Suponiendo que en AL se tenga, como en este ejemplo 3l,' la operacin ser bit a bit: 00110001 = 31
A 00001111 = OF
00000001
Cero M,Ginzburg- Assembler desd Cero U3-49
De esta manera, mediante la "mscara" OF se enmascaran los 4 bits superiores de 31, obligndolos a ser ceros,
e est mantenindose sus 4 bits inferiores.
La instruccin -no usada en este ejemplo- ROL AL, 1 (ROtates a register Left = rotar un registro a izquierda) ordena
:ebe ir a rotar el contenido del registro AL hacia la izquierda conforme indican las flechas de la figura 3.36.a Esto es, cada bit se
mueve una posicin hacia la izquierda, siendo que el bit de la extrema izquierda se reinyecta a la derecha. La figura
3.36.b muestra el resultado en AL de ejecutar la instruccin.
El flag C toma el valor del bit que queda en el extremo izquierdo de AL (o el registro que sea).
oe
11 1 JJE!iliJJiiid
gitud se ITJ
Figuras 3.36.a y 3.36.b
Para rotar ms que una posicin, se debe poner el nmero de posiciones a rotar en el registro CL en la instruc-cin
anterior (en nuestro caso mediante MOV CL, 4) y luego escribir ROL AL, CL (si se usa AL).
En el ejemplo de la secuencia anterior, antes de ROL en AL se tena 00000001 , por lo que luego de ejecutar ROL se
tendr 00010000, resultando C =O.
Tambin existe la instruccin ROR (ROtate a register Right), de funcin semejante a ROL.
EJERCICIO 40:
Desde la direccin 2001 se tiene una lista de 11 dgitos, del O al9, codificados en BCD. Sumarlos en BCD, y
el resultado guardarlo en la direccin 1500. El nmero 11 0 = OBH est en la direccion 2000.
MOV CL, [2000] Carga en CL la cantidad de dgitos de la lista
MOV SI, 2001 Registro SI apunta al comienzo de la lista de datos
OTRO SUB AL, AL Hace cero el registro AL
ADD AL, [SI] Suma un elemento de la lista contra AL
DAA Instruccin de correccin para suma BCD
conforme
INC SI Incrementa SI
DEC CL Decrementa CL
JNZ OTRO Mientras Z no sea 1, volver a OTRO
MOV [1500], AL Guarda indicacin de paridad
INT20 Fin
U3-50 M.Ginzburg- Assembler desde Cero M,Gin
o ..lUttojoJ
loi111IQJ. e
Q___j~J J ~l.l J .-1~ ~1~ J _._.. [J
En general, para un registro de n bits, SHR desplaza un lugar hacia la derecha el contenido del registro, llevando un cero Si se '
a la izquierda. El bit de la extrema derecha pasa a ser el nuevo valor del flag C (Carry). DAS
De manera inversa, SHL AX, 1 desplaza un lugar hacia la izquierda (shift left) cada uno de los 16 bits de AX, pone un
cero en la posicin extrema izquierda, y el bit extremo izquierdo pasa a ser el valor del flag C.
As es posible multiplicar por dos en binario, mediante una sola instruccin, el contenido de AX.
EJERCICIO 42: Multiplicacin de dos nmeros enteros de 8 bits cada uno mediante IMUL
Multiplicar el nmero entero que est en la direccin 2000 por el nmero -6 0 = 111110108 = FAH
Para multiplicar dos nmeros enteros de 8 bits, mediante la instruccin IMUL, uno de ellos puede estar en cualquier
registro de 8 bits, y el otro en AL. El resultado, que puede ser un nmero de hasta 16 bits, se encuentra en el registro AX.
xxxx:OlOO MOV CL, [2000] Carga en CL uno de los nmeros enteros de 8 bits
xxxx:Ol04 MOV AL, FA Carga en AL el otro nmero entero de 8 bits
xxxx:O l 06 IMUL CL Ordena multiplicar, CL por AL, con resultado en AX
xxxx:OlOA INT 20 Fin
~ Cero M,Ginzburg- Assembler desde Cero U3-51
EJERCICIO 43: Multiplicacin de dos nmeros enteros de 16 bits cada uno mediante IMUL
esultado
Multiplicar el nmero entero que est en la direccin 2000 y 2001 por el nmero -6 0 = FFF AH
Para multiplicar dos nmeros enteros de 16 bits, mediante la instruccin IMUL, uno de ellos puede estar en cualquier
registro de 16 bits, y el otro en AX. El resultado, que puede ser un nmero de hasta 32 bits, se encuentra en los registros
DX (mitad superior), y DX (mitad inferior)
MOV BX, [2000] Carga en BX el nmero entero de 16 bits que est en 2000 y 2001
MOV AX,FFFA Carga en AX el otro nmero entero de 16 bits
IMULBX Ordena multiplicar BX por AX, con resultado en DX y AX
INT20 Fin
EJERCICIO 44: Multiplicacin de un nmero entero de 16 bits por otro de 8 bits, y uso de CBW
Multiplicar el nmero entero que est en la direccin 2000 y 2001 por el nmero -6 0 = FAH
El nmero entero de 16 bits, puede estar en cualquier registro de 16 bits, y el de 8 bits en AL. A este ltimo se le debe
propagar el signo (unidad 4), mediante la instruccin CBW (Convert byte to word), para que resulte una multiplicacin
entre dos nmeros de 16 bits.
MOV BX, (2000] Carga en BX el nmero entero de 16 bits que est en 2000 y 2001
MOVAL,FA Carga en AL el otro nmero entero de 8 bits
CBW Convierte FA (que est en AL) en FFF A que ocupa AX
IMULBX Ordena multiplicar BX por AX, con resultado en DX y AX
INT20 Fin
cualquier
gist:ro AX.
U3-52 M.Ginzburg - Assembler desde Cero M,Giru
CS, DS, SS y ES permiten cambiar de lugar programas, con tan solo cambiar el valor contenido en ellos.
Si observamos el Debug vemos que normalmente los registros CS, DS, SS y ES tienen el mismo valor.
Ello implica que los 4 segmentos citados empiezan en la misma direccin (2B 160), o sea que estn
superpuestos (figura 3.39). Esta es la forma en que los hemos estado usando, como un solo segmento de 64
KB, til cuando se tiene un programa pequeo, como son los .COM. En este segmento pueden convivir, en
reas separadas, un programa, datos, y una pila.
1
Este tema es necesario cuando prximamente se traten las interrupciones.
2
Cuando se enciende una PC, muchos procesadores actuales funcionan con la menor cantidad de recursos posibles, simulando un 8086
que utiliza slo 1 MB de la memoria total, y con los registros que conocemos de Debug, lo cual se conoce como "modo reaf', para luego
pasar al "modo protegido" cuando el sistema operativo pasa a memoria, a fin de complementar sus funciones y poder realizar
multitasking (multiprogramacin).
sde Cero M,Ginzburg- Assembler desde Cero U3-53
didcti-
15direc- 0000 00000
nponen,
64 KB 30280
(CS=3028)
FFFF
382CC
Ja cuyas
{3028 :801 C)
! van de
r 1723
ene por
.i3 tiene
00000 50480
>endien- (08=5048)
y en el 28160
-ciona el 5299A
ento es (5048 :251A)
elo tanto, m
:::.:::
lo que se 2C 883
"<!"
<o
(28 16:1723)
;ulten de A321 O
stos tres (SS=A321)
.oen del
en
"registro ~
iza en el
AA83A
{A321 :762A)
.ecucin
enomi-
egm ento
mr en el E2300
(ES=E230)
o como
p untero
'2gTnento
:ro en el FFFFF
un 8086
para luego
er realizar
U3-54 M.Ginzburg- Assembler desde Cero M,Ginzl
El registro SP, indicador de la direccin ms alta ("cima") que tiene la pila, es usado para apilar y desapilar en
forma ordenada, los contenidos de la pila. El mismo es manejado automticamente por la UC cuando ejecuta
rla, en
cada instruccin que ordena apilar o desapilar, siendo que la UC por medio del SP controla el orden de la pila.
ra a un
A su vez la SRI que llam el PGM, puede llamar a otra SR2, y sta a otra SRJ, y as se pueden encadenar varias
para llamadas sucesivas a partir de la SRJ ("neste.d ' o anidamiento de subrutinas), gebindose volver siempre a la
cipal, instruccin que sigue a la instruccin CALL que llam a la SR J.
guiente En esos casos la pila -que empez a crecer a partir de la direccin provista por el SP con el valor que tena
cuando el PGM llam a la SRl, o sea con un valor relacionado con dicho PGM- ir apilando la informacin
contenida en los registros de la UCP, referente al valor que stos tenan antes que desde cada SR se llam a otra,
o sern como ocurri cuando el PGM llam a la SRI, constituyendo as una pila nica para ese proceso.
Como cada SR termina con instrucciones que ordenan desapilar y volver a la instruccin siguiente a la que la
llam, todos los apilamientos realizados en la pila en cuestin se irn sucesivamente desapilando ordenada-
mente, hasta retornar al PGM que llam a SRJ. Entonces el SP tambin volver al valor que tena entonces.
Ms adelante al tratar el tema de las interrupciones por software y hardware, se ver que en un proceso de
llamadas y retornos durante las cuales la pila tiene "vida", almacenando direcciones y datos, tambin una
nica pila relacionada con un PGM, se usa tanto para las llamadas a SR como para las interrupciones, que
tambin son llamadas pero a subrutinas del BIOS o del SO. Esto se ejemplifica en el ejercicio 47.
robarse Para que un PGM pueda enviarle los datos que procesar la SR que llam, y que sta pueda dejarle al PGM
lir sub- los resultados que necesita (comunicacin conocida como "pasaje de parmetros"), quin program la SR
debe dejar indicado los "buzones" necesarios, los cuales pueden ser:
1) Registros de la UCP.
2) Posiciones de la pila, en las que se apilarn datos para la SR y se desapilanin resultados para el PGM.
: q uiere
ruccin
DESCRIPCION MAS DETALLADA DEL PROCESO MEDIANTE UN EJEMPLO Y EL DEBUG
m.ttina"
saltar a EJERCICIO 46.a
Se tiene una lista de n nmeros enteros cuya direccin inicial es 1000, siendo que dicha cantidad n de
emoria nmeros est en la direccin 1500. Copiar en otra lista que empieza en 2000 slo Jos nmeros comprendidos
la que entre 20 y 40; y para cada uno de stos escribir debajo de su valor el nmero de orden que tiene en la lista
tm a la originaria (ver esquema superior fig. 3.41 ). Suponer que existe una subrutina para determinar si 20h ~N~ 40h.
Este ejercicio se basa en el n 17 pero tiene menos exigencias. En la parte superior de la figura 3.41 se ejemplifica supo-
instruc- niendo que Ni no est entre 20 y 40, y que N2 s lo est, con lo cual N2 se copia en 2000/1 , y su subndice i = 2 en 2002.
Encararemos el "pasaje de parmetros'' de dos formas:
1) Usando un registro de la UCP como puente entre el programa (PGM) y la subrutind (SR).
itET en 2) ldem usando la pila que est en memoria.
de Ik+J
retomar 1) Por pasaje de parmetros a travs de registro:
El diagrama lgico de la figura 3.41 presenta las secuencias de pasos necesarios para esta alternativa, la mayora de los
cuales ya estaban en la figura 3.32.
etorno" Visin general: los pasos de la izquierda corresponden al PGM, y los de la derecha a la SR.
instruc- El proceso comienza con los pasos 1 al 9. Este ltimo en Assembler es CALL 3500 que ordena saltar a ejecutar la SR
cuyo primer paso debe ser una instruccin que est en la direccin de memoria 3500. La ltima instruc<;in de la
emoria
ejecucin de la SR, que es RET, contraria a CALL, ordena retornar a la instruccin del PGM que sigue a CALL, luego de
lo cual el PGM sigue su curso, escribiendo o no (segn corresponda) en la lista apuntada por DI, el nmero N seguido por
o cada
su nmero de orden en la lista.
Despus (mientras queden nmeros sin analizar) en el PGM se volver al paso 5 para obtener el siguiente N de la lista
~ lee)la apuntada por SI, y en el paso 9 se volver a llamar a la SR, y as de seguido hasta analizar los n nmeros de la lista
re gis- apuntada por SI.
e pila" En el PGM antes de que se llama a la SR mediante la instruccin CALL, y cada vez que ello sucede, se pasa al registro
"puente" o " buzn" CX que es el que usa como acumulador la SR, una copia del nmero N de la lista apuntada por SI, a
fin de determinar si es o no 20 ~ N ::: 40.
Una subrutina, como la que calcula la raz cuadrada de un nmero, puede ser llamada por distintos programas o desde
_pi la de diferentes puntos de un programa. La persona que desarrolla un programa llamador no tiene por qu ser la misma que
UCP, gener la SR, ni tiene por qu conocer cmo ella funciona. Slo se necesita conocer en qu registro dejar el dato(s), en
ilar. este caso CX, y en qu registro quedar el resultado del procedimiento que realiz la SR (tambin en este ejemplo en la
mitad CH de CX) para que el programa tome una copia del mismo.
lila hacia
Si se observa la SR se verifica que ella opera al registro CX (podra haber sido BX, CX DX) y que deja en CH la
indicacin acerca de si N est comprendido (indicacin 01 h) o no (indicacin 00 h) entre 20 y 40.
M,Ginz
U3-56 M.Ginzburg- Assembler desde Cero
Como b
En el primer paso del diagrama de la 11gura 3.41 se inicializa el registro CL con una copia de la cantidad n de nmeros a
hace Cf
analizar, supuesta en la direccin 1500 (ver esquema superior derecho fig 3.41 ); y en los dos pasos siguientes los regis-
tros SI y DI se inicializan para que apunten a la direccin de comienzo de cada una de las listas. El 4to. paso ordena llevar La SR
a cero el registro DH que ser usado para generar el nmero de orden que tiene en la lista cada nmero N que se analiza. contenil
Con Rl
Cada vez que se ejecuta el paso 5 llega a AX una copia
corre5p1
del nmero N cuya direccin indica SI; y cada vez que
segn
esto sucede se debe generar su nmero de orden, inore-
Si Z= l
mentado DH (paso 6: DH f- DH + 1).
deben n
As, luego de pasar hacia AX el primer N (Ni) que est
orden i 1
en 1000, al sumar uno a DH resulta O+ 1 = 1 que es el
Para ell
nmero de orden de ese N (Al inicio era DH = 0).
que indl
En el paso 7 hay que pasar a BX una copia de CX, (en
sumar _
cuya mitad CL se guard la cantidad n de nmeros de
2000, la
la lista apuntada por SI), pues CX ser modificado en
de la cu
el paso 8, dado que a CX ir una copia del nmero N
que analizar la SR, la cual tambin modificar a CX. Esto es,
Con el paso CALL SR 3500 se ordena saltar a ejecutar escri bi
la SR cuya primera instruccin est en 3500 (fig. 3.41) Una vez.
por lo
Toda SR comienza guardando (apilando en la pila) anterior
mediante instrucciones PUSH 1 todos los registros que 2003 pa
va a utilizar, menos el registro(s) elegido para hacer el
pasaje de parmetros (CX en este tipo de pasaje). Con esn
para pal
Si bien la SR planteada slo usa el registro CX, como De ser
durante su ejecucin se realizan operaciones de resta, deben 1t
variarn los valores de los flags contenidos en el regis- paso 01
tro de estado (RE) como se indica con SZVC en la El paso !
figura 3.41 , en relacin con los valores que tenan los su valor
flags, por ejemplo luego de hacer DH f- DH + l.
O sea, que implcitamente en la SR adems de CX se Para o
est usando RE, por lo que antes del retorno al PGM poder x
(paso CH - O1) los flags deben volver al valor que Pero ~
tenan antes de llamar a la SR. A tal
Por ello la SR empieza con PUSHF (Flags) equivalente ta tiene 1
a PUSH RE, antes que la SR cambie el valor de los vale e
flags, guardando en la pila al RE como qued en el resta >01
PGM. cero, >01
Igualmente, si por ejemplo la SR en vez de CH f- 00 Cuando
hubiese hecho BH f- 00 y luego CH f- BH habra que por cons
hacer PUSH BX despus de PUSH F, para guardar BX
Si al iDI
en la pila, con el valor que tom en BX f- CX. Al final CAL L~
de la SR, con POP BX dicho valor se restaura en BX. de CH e
De no ser as, al retornar al PGM se pierde el valor que
POP C~
tena BX en el mismo.
Por lo ta
Por otra parte, la SR no guarda en la pila AX ni DX,
por que no los emplea, y " no sabe" que el PGM los
est usando.
A contin
Figura 3.41
En definitiva, en el primer paso de esta SR (Pila f- RE) el nico registro cuyos contenidos se guardan en la pila en este
ejemplo es RE mediante PUSH F, los cuales sern devueltos a RE mediante POP F, correspondiente al paso RE f- Pila.
Los apilamientos que producen CALL 3500 y PUSH F sern analizados en detalle en la figura 3.42 y verificados cuando
estas instrucciones se ejecuten mediante el Debug.
El paso que en la SR ordena la resta CX - 20 sirve para que tomen valor los flags SZVC. Si en el paso siguiente se
detecta S f- V, (CX=N < 20) hay que saltar al paso donde se hace CH = 00, para indicar que si por ejemplo es N=l5 < 20
no estar entre 20 y 40. En caso que en el paso siguiente a la resta CX- 20 se detecte S=V (CX=N ~ 20), el nmero N
que est en CX puede llegar a estar entre 20 y 40.
Para ver si N ::; 40 luego se hace CX- 41 para que tomen valor los flags SZVC. Si en el paso que le sigue se detecta S=V
(por ej. si N= 55), es CX=N ~ 41 , y por lo tanto N> 40, con lo cual tambin se ordena saltar al paso que hace CH =OO.
Pero si en el rombo que sigue a CX - 41 se detecta S;f:V, debe ser CX < 41 , y por consiguiente N :5 40 (por ej. si N=35).
1
"P ush" provi ene de "empujar" las monedas en un monedero del tipo cilindro con resorte, para ir apilndolas, siendo que la accin
contraria de ir sacando cada moneda de la pila de monedas almacenadas, s~ denomina "Pop".
M,Ginzburg- Assembler desde Cero U3-57
::e Cero
Como hasta este punto por los pasos anteriores era ya 20 :S N ahora resulta 20 :S N :S 40, por lo que en el paso siguiente se
meros a hace CH =O 1 para indicar que N est entre 20 y 40. Con este paso termina el procedimiento que realiza la SR.
:tS regs-
llevar La SR mediante los pasos RE ~ Pila (POP F) e IP ~ Pila (RET). pasan de la pila hacia los registros RE e IP los
~i za. contenidos que RE e IP tenan antes del llamado a la SR, desapilndolose los mismos de la pila.
Con RET se retoma al PGM, restaurando en el IP desde la pila la direccin (O 117) de la instruccin CMP CH, O1
copia correspondiente al paso CH- 01. El rombo simboliza que la instruccin de salto que sigue a CH- 01 permite determinar
\ez que
segn el valor del flag Z que esta resta origin, si CH = 01 CH =OO.
inore- Si Z=l implica que la resta fue 01 - 01 =O, sea que la SR dej CH = 01, indicacin que 20 :S N :S 40, por lo que se
deben realizar los pasos para guardar una copia de N en la lista apuntada por DI, seguida de una copia de su nmero de
e est orden i que contiene el registro DH.
, e es el Para ello en el paso [DI] ~ AX se escribe una copia del valor de N (que sigue guardado en AX) a partir de la direccin
0). que indica DI (2000 para la primera vez que se encuentre un N entre 20 y 40). Luego mediante DI ~ DI + 2 se ordena
ex, (en sumar 2 a DI para que la escritura siguiente siga debajo del nmero N recin escrito. As, suponiendo que DI estaba en
eros de 2000, la escritura de N habr ocupado las celdas 2000 y 2001; y si se le suma 2 a DI ste pasar a 2002, direccin a partir
'cado en de la cual se uede escribir un nuevo valor sin " isar" el valor de N antes escrito.
:mero N
Esto es, si luego de cada escritura de una lista no se incrementara el registro que apunta a la ltima direccin donde se
i a CX.
escribi un valor, el prximo nmero a escribir "pisara" dicho valor que se haba escrito.
ejecutar
.g. 3.41) Una vez incrementado DI, debajo de N se escribe su nmero de orden i en la lista indicado por DH, mediante [DI] ~ DH,
por lo que luego se incrementa DI nuevamente uno, pues el contenido de DH ocupa un byte. Siguiendo con la suposicin
In pila) anterior, el contenido de DH se hubiera escrito en 2002, y luego del incremento de DI (paso DI ~DI+ 1) ste pasa a
rtros que 2003 para apuntar a la direccin donde se escribir (si aparece) otro N de la lista que est entre 20 y ~0.
hacer el
- ~)- Con este incremento de DI terminan los pasos para el caso de que N est entre 20 y 40, por lo que deben seguir los pasos
para pedir el siguiente valor de N que corresponde analizar de la lista apuntada por SI.
X., como De ser Z=O la resta fue 00- 01 -j O o sea que la SR dej CH = 00, indicacin que no es 20 :S N :S 40, por lo que no se
e resta, deben realizar los pasos recin descriptos para guardar AX =N y DX = i. Si Z=O estos pasos se "puentean" saltando al
el regis- paso CX ~ BX que sigue a los mismos, a partir del cual comienzan los pasos para obtener el siguiente N a analizar.
C en la El paso CX ~ BX es necesario para que CL vuelva a tener el valor n, pues la SR dej CH con 01 00, y CL no tiene ms
::nan los su valor inicial n luego que en el PGM se hizo CX ~ AX.
l.
ex se Para obtener el prximo N se le suma 2 al valor que tena SI, mediante el cual se localiz el ltimo N analizado, para as
aJ PGM poder pedir el N que sigue en la lista (paso SI ~SI+ 2). De no incrementarse SI siempre se pedira de 2000 el mismo N.
'2lor que Pero antes de pedir un nuevo N hay que verificar si el N que se analiz antes no fue el ltimo de la lista apuntada por SI.
A tal fin (paso CL f- CL- 1), cada vez que se analiz un nmero de esta lista se le resta uno a CL (que en la primer vuel-
ta tiene la cantidad n de nmeros de la lista) de modo que CL acte como contador regresivo. Cuando se detecta que CL
vale cero implica que se analizaron todos los n nmeros de la lista. Esta deteccin se realiza preguntando luego de dicha
resta por el valor de Z que result de ella. Mientras sea Z=O implica que el resultado de esa resta que qued en CL no es
cero, por lo que se debe saltar al paso 5 del diagrama donde se pide el siguiente N.
::'H ~ 00 Cuando se analiza el ltimo N de la lista en CL sern= 1, de modo que CL- 1 es 1 - 1 =O, resultando Z= 1 (cero si) y
ra que por consiguiente en vez de volver a pedir el siguiente N de la lista, por ser Z=l (CL=O) se termina la ejecucin del PGM.
::nlar BX Si al inicio de la SR se hubiera guardado CX mediante PUSH CX, en la pila se tendra el ltimo valor de CX antes de
_Al final CALL 3500, o sea CX =N. Al finalizar el procedimiento de la SR resulta CH=Ol CI-1=00, siendo que uno u otro valor
a en BX. de CH es determinado no bien se retorna al PGM. Pero si al inicio se hizo PUSH CX, antes de retornar se debe hacer
mlor que POP CX, con lo cual volvera a CX el nmero N que se haba guardado en la ila, pisando el valor de CH requerido.
Por lo tanto, no se puede guardar en la pila el registro o registros usado(s) usados para el pasaje de parmetros.
1{ni DX,
PGM los
en este
~ Pi la.
liS cuando
~iente se
F=1 5 < 20
' mero N
teda S=V
:H = OO.
si =35).
ECin
U3-58 M.Ginzburg- Assembler desde Cero M,Gim
-A 0100 -T (El
OCC6:0100 MOVCL, [1500] Carga en CL la cantidad n de nmeros de la lista AX=O Ofi
OCC6:0104 MOV SI, 1000 Inicializa SI= 1000 DS=O CC
OCC6:0107 MOV DI, 2000 Inicializa DI = 2000 OCC6:
-T
OCC6:010A MOV DH, 00 Inicializa DH = 00
AX= Ff
OCC6 :010C MOV AX, [SI] Lleva hacia AX una copia del nmero N apuntado por SI DS=O C(
OCC6:010E INe DH Cada vez que se toma un nmero nuevo de la lista se suma uno al contador de orden DH OCC6 :0:
OCC6:0110 MOV BX, ex Guarda en BX una copia de CX, que luego ser modificado para la SR -T
OCe6:0112 MOVeX,AX Copia en CX una copia de AX, para que luego sea el dato que procesar la SR AX=Fil
OCe6:0114 eALL 3500 Pasa a ejecutar la SR que est en 3500 DS=Oa
OCC6:0117 eMP eH, 01 Luego de que se ejecut la SR, se vuelve al PGM para restar CH- 01 OCC6: l
OCC6:011A JNZ 0124 Si de CH- 01 fue Z=O es que no es CH=Ol , o sea que no fue 20:SN:S40, saltar a 0124 -T
AX=Ffl
OCC6:011C MOV [DI], AX Copia en la lista apuntada por DI el nmero N comprendido entre 20 y 40
DS=OC(
OCC6:011E ADD DI, 2 Suma 2 a DI para preparar debajo la escritura del nmero de orden de N debajo de su valor OCC6:0l
OCC6:0121 MOV [DI], DH Escribe en la direccin apuntada por DI una copia del nmero de orden que indica DH -T
OCC6:0123 INe DI Se actualiza DI por si en AX llega otro N comprendido entre 20 y 40 AX=FF1
OCC6 :0124 MOV ex, BX Desde BX se restaura el valor que tena CX antes de llamar a la SR DS=OC(
OCC6:0126 ADD SI, 2 Si Z=l (AX = AXanterior) suma 2 a SI para apuntar siguiente nmero N de la lista OCC6:01
OCC6:0129 DEe eL Resta uno a la cantidad de nmeros que falta analizar en la lista apuntada por SI -T
OCC6:012B JNZ OlOe Mientras sea Z=O saltar a 01 OC para considerar el nmero siguiente de la lista AX=FFl
Finalizar DS=OCC
OCC6:012D INT 20
OCC6:.X
-A 3500 -E FFE-<
/
OCC6:3500 PUSHF Guarda en la pila el valor de los Flags que usaba el programa, contenidos en el registro RE OCC6: El
-T
OCC6:3501 eMPeX,20 Resta CX- 20 para que SZVC tomen valores, siendo CX =N
AX=FFl
OCC6:3504 JL 3520 Si S# V resulta CX < 20 entonces saltar a 3520 DS=O CC
OCC6:3506 eMP eX,41 Resta CX- 41 para que SZVC tomen valores OCC6:35
OCC6:3509 JG 3520 Si S=V resulta CX 2: 41 (o sea CX > 40) entonces saltar a 3520 -E FFE.-\
OCC6:350B MOVeH,Ol Si S#V (CX < 41) se hace CH = O1, para indicar que 20 :S CX :S 40 OCC6:FJ
OCC6:350D POPF Pasa de la pila a RE el valor que tenan los flags en el programa antes de llamar ala SR -T
OCC6:350E RET Pasa de la pila al IP la direccin O118 de la instruccin por la cual prosigue el programa AX=FH
DS=O CC
-A 3520 OCC6 :.15
OCC6:3520 MOVeH,OO Si S=V (CX 2: 41) (o sea CX > 40) se hace CH=OO, para indicar que no es 20 :S CX :S 40 -T .
OCC6:3522 JMP 3500 Saltar incondicionalmente a 350D AX=FFF
DS=O CO
En lo que sigue, mediante el Debug se ejecuta la codificacin Assembler correspondiente al diagrama de la figura 3.41 OCC6 :B
suponiendo que en la lista apuntada por SI estn los siguientes nO 2 nmeros: FFFFh =-Id y 0025h = 37d. -T
Durante la ejecucin aparecen comentarios, y resaltados los contenidos que se van apilando y quedan en la pila, as como AX=Fff
dnde se originan y hacia dnde van los mismos u otros de inters. Para los valores apilados se indican a qu registros DS=OCO
OCC6: r
pertenecen, o sea tambin a los que deben retomar.
-T
El ltimo valor que queda en el SP luego de que se ejecut la instruccin anterior indica siempre la direccin de la cima. AX=FFF
Mediante el comando E se leen en memoria los contenidos que guarda la pila, pulsando la barra espaciadora del teclado DS=OCO
a partir de la direccin que indica SP, a fin de lograr direcciones consecutivas crecientes desde la cima hacia abajo. OCC6::L_
-T
-E 1500
AX=FFI
OCC6:1500 00.02 (se escriben en 1500 la cantidad n = 2 de nmeros de la lista)
DS=OCO
-E 1000 OCC6:l5i
OCC6:1000 FF. FF. 25. OO. (se escriben en memoria los nmeros N!= FFFF y N2 = 0025)
-E FFEC
-R IP OCC6: Ff
IP 0100 -T (Con l
:0100 (se pone el registro IP en 0100 para que proporciones la direccin de la primera instruccin que est en 0!00) AX=FFFl
DS=OCO
-R OCC6:011
AX=OOOO BX=OOOO CX=OOOO DX=OOOO SP=FFEE BP=OOOO Sl=OOOO DI=OOOO -E FFEE
DS=OCC6 ES=OCC6 SS=OCC6 CS=OCC6 IP=OIOO NV UP El PL NZ NA PO NC T
OCC6:0100 8AOE0015 ,.... MOV CL, [1500] DS:l =02 (El valor 02 que est en 1500 se copia en CL) AX=FFFl
-T _ (El comando T ejecuta la que aparece arriba de T) DS=OCG
AX=OOOO BX=OOOO CX=OO- SP=FFEE BP=OOOO SI=OOOO DI=OOOO OCC6:011
DS=OCC6 ES=OCC6 SS=OCC6 CS=OCC6 IP=0104 NV UP El PL NZ NA PO NC -T Coc
OCC6:0104 BEOOIO MOV SI, 1000 AX=FFF1
-T -------- (El valor l 000 que lleg con la instruccin, pas a SI) DS=OCO
AX=OOOO BX=OOOO CX=0002 DX=OOOO SP=FFEE BP=O~OOO DI=OOOO OCC6: OI
DS=OCC6 ES=OCC6 SS=OCC6 CS=OCC6 IP=0107 NV UP El PL NZ NA PO NC -T
OCC6:0107 BF0020 MOV DI, 2000
T (El valor 2000 que lleg con la instruccin, MOV DI, ~asa a DI)
AX=OOOO BX=OOOO CX=0002 DX=OOOO SP=FFEE BP=OOOO , Sl=lOOO ~000
1
Cuando~
DS=OCC6 ES=OCC6 SS=OCC6 CS=OCC6 IP=OlOA NV UP El PL NZ NA PO NC (0011 00 1(
OCC6:010A 8600 MOV DH,OO C=O(NQ
Cero M,Ginzburg- Assembler desde Cero U3-59
-T (El valor 00 que lleg con la instruccin, MOV J2!._.Q,Q pasa a OH que en este caso ya estaba en 00)
AX=OOOO BX=OOOO CX=0002 DX=Q_~EE BP=OOOO Sl=lOOO DI=2000
DS=OCC6 ES=OCC6 SS=OCC6 CS=OCC6 IP=OlOC NV UP El PL NZ NA PO NC
OCC6:010C 8B04 MOV AX,[SI] DS:lO =___.EE (En la direccin 1000 de memoria se tiene FF y en 1002
-T se tiene FF, cuyas copias pasarn hacia AX)
AX= FFF - X=0002 DXk-00 SP=FFEE BP=OOOO Sl=lOOO DI=2000
DS=OCC6 ES=OCC6 SS=OCC6 CS=O C6 lP=OlOE NV UP El PL NZ NA PO NC
DH OCC6:010E FEC6 INC DH
-T 0Hpasade00a01)
AX=FFFF BX=OOOO CX=O 02 DX=_!00 SP=FFEE BP=OOOO SI=lOOO DI=2000
DS=OCC6 ES=OCC6 SS CC6 CS=OCC6 IP=OllO NV UP El PL NZ NA PO NC (Estos valores de los flags de la ejecucin de
OCC6:0110 89CB MOV BX, CX INC OH sern luego guardados en la pila)
-T CX se copia en BX)
AX=FF BX=O CX=0002 DX=0100 SP=FFEE BP=OOOO SI=lOOO DI=2000
DS=OCC6 - :=OCC6 SS=OCC6 CS=OCC6 IP=0112 NV UP El PL NZ NA PO NC
valor OCC6:0112 89C
lH -T (AX se copia en CX)
AX=FFFF BX=0002 C = FFFF DX=O!OO SP=FFEE BP=OOOO SI=lOOO Dl=2000
DS=OCC6 ES=OCC6 SS=OCC6 CS=OCC6 1P=Ol14 NV UP El PL NZ NA PO NC
OCC6:0114 E8E933 CA L 35011--..
-T
AX=FFFF BX=0002 C =FFFF DX=OlOO - FEC BP=OOOO SI=1000 DI=2000
DS=OCC6 ES=OCC6 =OCC6 CS=OCC6 IP= :~O SP 7 FFEC 1171 IP
OCC6:3500 9C USHF Estos flags se o an como RE=3202 O 01 IP
-E FFEC (1 (Con CALL la cima pasa a FFE y se guar a pila la direccin 0117 de retorno) FFEE 00
OCC6:FFEC !..Z.:..__Q1_ OO. (Con CALL la direccin d orno 0117 de CMP CH, 01 se guarda en FFEC/D de la pila)
iUO RE
-T Con PUSHF la cima pasa de FFEC a FFEA
="~P=OOOO Sl=1000 DI=2000
SP 7 FFEA ~ RE
AX=FFFF BX=0002 CX=FFFF DX=OlO --
DS=OCC6 ES=OCC6 SS=OCC6 C C6 IP=3501 NV UP El NG NZ NA PO NC B 32 RE
OCC6:3501 83F920 CM X, 20 (Se resta FFFF- 0020) FFEC 1 IP
-E FFEA Se guardan en la pila los valores de los flags que estn en RE=3202) 1 O 01 IP
OCC6:FFEA 02. 32. 17. 01. OO. FFEE 00
1SR -T
AX=FFFF BX=0002 CX=HFF DX=OlOO SP=FFEA BP=OOOO Sl=1000 Dl=2000
'l!llla
DS=OCC6 ES=OCC6 SS=OCC6 CS=OCC6 IP=3504 NV UP El NG NZ NA PO NC
OCC6:3504 7C1A JL 3520 Con JL se salta si Si-Y; como en CX- 20 fue NV (V=O) y NG (S=!) o sea Si-Y se saltar a 3520
[ ~4 0
-T
AX=FFFF BX= CX=FFFF DX=OIOO SP=FFEA BP=OOOO SI=IOOO 01=2000
DS=OCC6 =<JCC6 SS=OCC6 CS=OCC6 1P=3520 NV UP El NG NZ NA PO NC
~ 3.41 OCC6:3520 B500 MOV ~H,
-T La mitad CH de CX queda en cero)
AX=FFFF BX=0002 CX=_FF DX=OlOO SP=FFEA BP=OOOO SI=IOOO DI=2000
como
DS=OCC6 ES=OCC6 SS=OCC6 CS=OCC6 1P=32 NV UP El NG NZ NA PO NC
J
registros OCC6:3522 EBE9 JMP 350D
-T (Salta incondicionalmene de 1P=3522 a IP=3500)
=la cima. AX=FFFF BX=0002 CX=OOFF DX=OIOO SP=F A BP=OOOO Sl=IOOO 01=2000
::1 teclado DS=OCC6 ES=OCC6 SS=OCC6 CS=OCC6 IP=3. OD NV UP El NZ NA PO NC
;o. OCC6:350D 9D POPF Con POPF se restauran los valores de los flags que existan
-T Con POPF la cima pasa de FFEA a FFES........ en el PGM luego de ha~H (NG cambia a PL)
AX= FFFF BX=0002 CX=OOFF DX=OIOO SP=~ BP=OOOO SI 1000 DI=2000 . . - - -
DS=OCC6 ES=OCC6 SS=OCC6 CS=OCC6 IP=350E NV UP El p NZ NA PO NC 1 TI
OCC6:350E C3 RET SP 7 FFEC 1 IP
~HEC OOlW
OCC6:FFEC 17. 01. OO. FFEE 00
-T (Con RET la cima pasa a FFE~n .0117 pasa de la pila al IP para retornar a la instruccin CMP CH, 01 del PGM)
AX=FFFF BX=0002 CX=OOFF DX=OlOO ~FEE BP=OOOO Sl=lOOO 01=2000
DS=OCC6 ES=OCC6 SS=OCC6 CS=OCC6 IP=0117 NV UP El PL NZ NA PO NC
OCC6:0117 80FD01 CMP CH, 01 (Ordena restar CH- O1 = 00- 01 que arrojar resultado no cero)
-E FFEE .00 SP 7 FFEE 00
T
AX=FFFF BX=0002 CX=OOFF DX=OlOO SP=FFEE BP=OOOO Sl=lOOO DI=2000
DS= OCC6 ES= OCC6 SS= OCC6 CS= OCC6 IP=OIIA NV UP El NG NZ AC PE CY
OCC6:011A 7508 JNZ 012
-T Con JNZ se salta si Z=O; como Z (Z=O sea el resultado de CH- 01 no fue cero) se saltar a la direccin 0124AX=FFFF
AX=FFFF BX=O~X=OOFF DX=OIO =FFEE BP=OOOO Sl=tOOO DI=2000
f) DS= OCC6 ES= OCC S= OCC6 CS= OCC6 1 124 NV UP El NG NZ AC PE CY
OCC6: 0124 89D9 OV CX, BX
-T -- (CL de CX vuelve al valor 02 que tena antes de CALL)
1
Cuando se ejecuta PUSH F, el valor hallado que se guard en la pila (en este ejemplo 3202 h) equivale a un nmero binario
(00110010 00000010) que de acuerdo a la figura 3.49 por su ubicacin en sta se corresponde con los siguientes valores de los flags:
C=O (NC), Z=O (NZ), S=O (PL) y V=O (NV), como puede verificarse luego de ejecutar INC OH y antes de ejecutar PUSH F.
U3-60 M.Ginzburg- Assembler desde Cero M,Ginzl
AX=FFFF BX=0002 e~2 OX=OIOO SP=FFEE BP=OOOO SI=IOI DI=2000 -E FFEJ
DS= oee6 ES= oee6 SS= oee6 eS= oee6 1P=Ol26 NV UP El NG Z Ae PE ey OCC6:Fl
oee6:0126 83e602 ADD Sl,+02 -T (Con
-T (Se suma 2 a SI para tomar el siguiente N de la lista) AX=OO...:
AX=FFFF BX=0002 eX=0002 DX=OIOO SP=FFEE BP=OOOO SI=IO 1 01=2000 OS=OCC
DS= oee6 ES= oee6 SS= re6 eS= oee6 IP=Ol29 NV UP El PL NZ NA PO Ne OCC6:01
oee6:0129 FEe9 DEe eL -T (C
-T (Se resta uno a CL de CX pues ya se ha analizado un nmero de la lista y queda uno menos)
AX=FFFF BX=0002 eX=O ! DX=OIOO SP=FFEE BP=OOOO Sl=1002 01=2000 AX=~2:
OS=O C
DS=Oee6 ES=Oee6 SS=Oee6 eS=Oee6 1P=012B NV UP El PL NZ NA PO Ne OCC6:0
oee6:012B 75El JNZ 01 e Con JNZ se salta si Z=O; como fue NZ (Z=O sea el resultado de CL- 1 no fue cero) se saltar -T
-T AX=OO...:
AX=FFFF BX=0002 eX=0001 DX=O P=FFEE BP=OOOO Sl=1002 DI=2000 OS=OeC
DS=Oee6 ES=Oee6 SS=Oee6 eS=OCe6 NV UP El PL NZ NA PO Ne OeC6:01
oee6:010e 8804 MOV AX,[SI] DS1Q02=01125 (En 1002/3 de memoria se tiene 0025 que pasar a AX) -E 2000
-T OCC6:2AI
AX = 0025~X=0002 eX-0001 DX-1!00 SP=FFEE BP-0000 Sl-1002 DI=2000 -T (D
DS=Oee6 ES=Oee6 SS=Oee6 CS=O e6 1P=010E NV UP El PL NZ NA PO Ne AX=OO..:
oee6:010E FEe6 lNC DH OS=OCC
-T (El nmero de orden que est en DH pasa de 1 a 2) OCe6:01
AX=0025 BX=0002 eX=OOOl DX=O_OO SP=FFEE BP=OOOO Sl=1002 DI=2000 --T
DS=Oee6 ES=Oee6 SS=Oee6 eS=OCe6 lP=OllO NV UP El PL NZ NA PO N~ DE ACA EN MS SE REPITEN AX=OO..:
oee6:0110 89eB MOV BX, ex Los valores de estos flags equivalen a RE=3202 VAR!Or ASOS ANTERJ;RES OS=OeC
-T OeC6:01
AX=0025 BX=OOO~eX 001 DX=0200 SP=FFEE BP=OOOO Sl=1002 DI=2000 -E 2002
DS=Oee6 ES=Oee6 =Oee6 eS=Oee6 IP=Oll2 NV UP El PL NZ NA PO Ne OCC6:211
oee6:011289el MOV eX,AX -T (D
-T AX=OO-
AX=0025 BX=0001 eX=0025 DX=0200 SP=FFEE BP=OOOO Sl=1002 01=2000 DS=OCC
DS=Oee6 ES=Oee6 SS=Oee6 eS=Oee6 lP=O 114 NV UP El PL NZ NA PO Ne OCe6:0I
oee6:0114 E8E933 eALL 3500 -T
-T AX=OO...:
AX=0025 BX=OOOl eX=0025 OX=0200 SP=FFEe BP=OOOO 81=1002 01=2000 OS=OCC
OS=Oee6 ES=Oee6 SS=Oee6 es=oee6 1P=3500 NV UP El PL NZ NA PO Ne OCC6:01
oee6:3500 9e PUSHF -T
-E FFEe AX=OO.-:
oee6:FFEe !L.___!!.!_, OO. (Con CALLen la pila se volvi a guarder 0117, direccin de retorno al PGM) DS=OC(:
-T OCC6:0
AX=0025 BX=0001 eX=0025 OX=0200 SP=FFEA BP=OOOO Sl=l002 DI=2000 -T
OS=Oee6 ES=Oee6 SS=Oee6 eS=Oee6 1P=3501 NV UP El PL NZ NA PO Ne AX=OO:Z.:
oee6:3501 83F920 eMP eX,+20 DS=OCC
-E FFEA OCe6:01
oee6:FFEA 02. 32. 17. 01. OO. (Con PUSHF en la pila se guarda RE=3202 con los valores de los flags de INC OH) -T
-T AX=OOl:
AX=0025 BX=OOOI eX=0025 OX=0200 SP=FFEA BP=OOOO Sl=l002 DI=2000 DS=OCC
OS=Oee6 ES=Oee6 SS=Oee6 eS=Oee6 1P=3504 NV UP El PL NZ NA PE Ne OCC6:0l
oee6:3504 7eiA JL 3520 Con JL se salta si Sf.V; como en CX- 20 fue NV (V=O) y PL (S=O) o sea S=V no se salta
-T
Habie
AX=0025 BX=OOOl eX=0025 OX=0200 SP=FFEA BP=OOOO Sl=1002 01=2000
OS=Oee6 ES=Oee6 SS=Oee6 eS=Oee6 1P=3506 NV UP El PL NZ NA PE Ne CALL :
oee6:3506 83F941 eMP ex, +41 Como 1
-T direcci(
AX=0025 BX=0001 eX=0025 OX=0200 SP=FFEA BP=OOOO Sl=1002 01=2000
de cel
OS=Oee6 ES=Oee6 SS=Oee6 eS=OCe6 1P=3509 NV UP El NG NZ NA PE eY
oee6:3509 7F15 JG 3520 Con JG se salta si S=V; como en CX- 41 fue NV (V=O) y NG (S=I) o sea Sf.V no se salta Esto se
-T
AX=0025 BX=OOOI eX=0025 OX=0200 SP=FFEA BP=OOOO Sl=l002 DI=2000 l. Sm
OS=Oee6 ES=Oee6 SS=Oee6 eS=OCe6 1P=350B NV UP El NG NZ NA PE eY 2. Re
OCe6:350B 8501 M~V e , 01 des
-T e hace CH=O 1, indicando que 0025 est entre 20 y 40) 3. Se
AX=0025 BX=OOOI eX=_ 5 OX=0200 SP=FFEA BP=OOOO Sl=l002 DI=2000
OS=OCC6 ES=OCe6 SS=Oee6 eS=OCC6 1P=350D NV UP El NG NZ NA PE CY me
OCe6:350D 90 POPF 4. Al
-T
AX=0025 BX=OOOl CX=Ol25 OX=0200 SP=FFEC BP=OOOO Sl=l002 01=2000 La insti
OS=OCC6 ES=OCC6 SS=OCe6 CS=OCC6 1P=350E NV UP El PL NZ NA PONe plican t:
OCe6:350E e3 RET
-E FFEe l. Re
OCe6:FFEe 17. 01. OO. (El SP vuelve a su valor originario) des
-T .-- 2. Se
AX=0025 BX=0001 CX=Q!25 OX=0200 SP=FFEE BP=OOOO SI=I002 01=2000
DS=Oee6 ES=Oee6 SS=OCe6 CS=OCC6 IP=Oll7 NV UP El PL NZ NA PONe me
OCe6:0ll7 80FD01 CMP CH, 01
::Cero M,Ginzburg- Assembler desde Cero U3-61
-E FFEE
OCC6:FFEE OO.
-T (Con CMP CH, 01 se resta CH- 01, en este caso 01-01 =O debiendo resultar ZR (zero resultado, o sea Z=l)
AX=0025 BX=OOOl CX=Ol25 DX=0200 SP=FFEE BP=OOOO Sl=l002 DI=2000
DS=OCC6 ES=OCC6 SS=OCC6 CS=OCC6 IP=OllA NV UP DI PL ZR NA PE NC
OCC6:011A 7508 JNZ 0124
-T (Como fue ZR=resu ltado cero, o sea Z=l, no se saltar y se pasa a la instruccin siguiente)
AX= 025 BX=OOOl CX=Ol25 DX=0200 SP=FFEE BP=OOOO SI=l002 DI=2000
DS=O C6 ES=OCC6 SS=OCC6 CS=OCC6 IP=OllC NV UP DI PL ZR NA PE NC
OCC6:0 lC 8905 MOV [DI], AX DS:2000=6320 (valor "basura" anterior en 2000/1)
mar -T
AX=0025 X=OOOl CX=0125 DX=0200 SP=FFEE BP=OOOO SI=1002 DI=2t0
DS=OCC6 'S=OCC6 SS=OCC6 CS=OCC6 IP=OllE NV UP DI PL ZR NA P NC
OCC6:011E C702 ADD DI,+02
AX) -E 2000 (Se verifica que una copia de 0025 paso de AX a la direccin 200 de memoria apuntada por DI)
OCC6:2000 25. OO.
-T (DI se le sum 2 para no pisar en la prxima escritura lo que ya est en 2000/
AX=0025 BX=OOOl CX=0125 D _100 SP=FFEE BP=OOOO SI=l002 DI=2002
DS=OCC6 ES=OCC6 SS=OCC6 S=OCC6 IP=Ol21 NV UP DI PL NZ NA PO NC
OCC6:0121 8835 MO [DI], DH DS:2002=6l
--T
)( AX=0025 BX=OOOl C. 125 DX=0200 SP=FFEE BP=OOOO SI=l002 DI=2t2
::S DS=OCC6 ES=OCC6 S=OCC6 CS=OCC6 IP=Ol23 NV UP DI PL NZ NA P NC
OCC6:0123 47 INC DI
-E 2002
OCC6:2002 02. (Se verifica que en 2002 pas una copia de CH=2, nmero de o en del nmero que estaba entre 20 y 40)
-T (DI se le sum 1 para no pisar en la prxima escritura lo que ya est en 2002)
AX=0025 BX=OO!!.._ CX=OI25 DX=0200 SP=FFEE BP=OOOO SI=I002 DI=2003
DS=OCC6 ES=OCC6 S=OCC6 CS=OCC6 IP=Ol24 NV UP DI PL NZ NA PE NC
OCC6:0124 89D9 CX, BX
-T (CL de CX vuelve al valor 01 que tena antes de CALL)
AX=0025 BX=OOOJ CX=OOQ! DX=0200 SP=FFEE BP=OOOO SI=I002 Dl=2003
DS=OCC6 ES=OCC6 SS=OCC6 CS=OCC6 IP=0126 NV UP DI PL NlNA PE NC
OCC6:0126 83C602 ADD SI, +02
-T (SI pas a 1004, direccin que no se usar)
AX=0025 BX=OOOl CX=OOOl DX=0200 SP=FFEE BP=OOOO SI=lO__:! 01=2003
DS=OCC6 ES=OCC6 SS=Oi6 CS=OCC6 IP=Ol29 NV UP DI PL NZ NA PO NC
OCC6:0129 FEC9 DEC CL
-T (Se hizo 1 - 1 =O con lo cual CL=O y Z=l=ZR, o sea que se tomaron los n nmeros de la lista)
AX=0025 BX=OOOI CX=O _Q DX=0200 SP=FFEE BP=OOOO SI=l004 Dl=2003
DS=OCC6 ES=OCC6 SS=OCC6 CS=OCC6 IP=Ol2B NV UP EII'L ZR NA PE NC
OCC6:012B 75DF JNZ O!OC Con JNZ se salta si Z=O; como fue ZR (Z=l sea el resultado de CL- 1 fue cero) no se salta
-T
AX=0025 BX=OOOI CX=OOOO DX=0200 SP=FFEE Bl'=OOOO SI=I004 DI=2003
DS=OCC6 ES=OCC6 SS=OCC6 CS=OCC6 IP=Ol2D NV UP El PL ZR NA PE NC
OCC6:012D CD20 INT 20 (Finaliza el programa)
Habiendo ejecutado el programa con el Debug, sistematizaremos los resultados obtenidos luego de ejecutar
CALL 3500, PUSHF, POPF y RET.
Como puede observarse, luego de la ejecucin de CALL 3500 el SP pas de FFEE a FFEC, y se apil la
direccin 0117 que es la direccin 0114 (que indicaba el IP donde est CALL 3500) ms 3, que es la cantidad
de celdas que ocupa el cdigo E8E933 de CALL 3500 (siendo 0117h + 33E9h = 3500h).
Esto se esquematiza en la fig 3.42. Para hacerlo, cuando la UC ejecuta CALL realiza los siguientes 4 pasos:
l. Suma 3 al IP (IP = 0117 = 0114 + 3) antes de que pase a 3500 o sea se hace (IP f-IP + 3)
2. Resta 2 al SP (SP ~ SP- 2) resultando FFEC = FFEE- 2 para que O117 se empiece a escribir en la pila
desde FFEC. Si se escribiera O117 a partir de FFEE ocupara FFEE y FFEF en vez de apilar hacia arriba.
3. Se escribe 0117 en memoria a partir de la direccin FFEC (cima de la pila) apuntada por SP, que confor-
me a la simbologa usada en los diagramas lgicos simbolizaremos [SP] f- IP (IP = 0117)
4. Al IP pasa el valor 3500 =O 117 + 33E9 para que se pase a ejecutar la primera instruccin de la subrutina
La instruccin PUSHF al igual que PUSH AX. PUSH BX, etc., se ejecuta mediante los pasos 2 y 3 que im-
plican el apilamiento de informacin (figura 3.42), por lo que adaptaremos los anteriores a esta instruccin.
l. Resta 2 al SP (SP ~ SP- 2) resultando FFEA = FFEC - 2 para que 3202 se empiece a escribir en la pila
desde FFEA. Si se escribiera 3202 a partir de FFEB "pisara" el valor O117 antes apilado.
2. Se escribe 3202 en memoria a partir de la direccin FFEA (cima de la pila) apuntada por SP, que confor-
me a la simbologa usada en los diagramas lgicos simbolizaremos [SP] ~ RE (RE = 3202)
U3-62 M.Ginzburg- Assembler desde Cero M,Gin
Obsrvese que el valor de SP cambia automticamente mientras se ejecutan CALL y PUSH, por lo que no es
- Cadl
necesario insertar en el programa ninguna instruccin que ordene modificar el valor del SP.
menta
incren
quede
- ElS
instrut
-CuaJ
la SR
EJER
Con es
S P - FFEE L................- '
PGM 1
Figura 3.42 genera
En es.u
La ejecucin de POPF (figura 3.43) al igual que cualquier otro POP, supone devolver o restaurar el valor que nes PU
tena RE (o el registro que indica POP) en relacin con el PGM antes de la ejecucin de CALL, a fin de api len
seguir con la ejecucin del PGM con los valores de los registros como los haba dejado el PGM, salvo el seguir
registro "buzon" (CX en este caso) dada esta forma elegida de pasar parmetros.
POPF es contraria a PUSHF, o sea produce el desapilamiento de 3202 de RE que volver a RE. Como
aparece en el Debug, de NV UP El NG NZ NA PO NC se pasa a NV UP El PL NZ NA PO NC, valores que correspon-
den a RE=3202. Si bien 3202 seguir en memoria hasta que no sea "pisado", pero que no formar ms parte
de la pila cuya nueva cima es FFEC, dado que SP con POPF pas de FFEA a FFEC como indica el Debug.
Los 2 pasos de la ejecucin de POPF (vlidos para cualquier otro POP salvo el registro involucrado) son:
l. RE~ [SP] en este caso RE~ [FFEA] puesto que antes de ejecutar POPF era SP=FFEA, o sea que estaba
apuntando a 0232, valor que debe ser ledo a partir de FFEA, por lo que primero debe hacerse esta lectura
para que 3202 pase a RE (figura 3.43).
2. SP ~ SP + 2 en este caso FFEA + 2 = FFEC : a fin de desapilar hay que sumarle 2 a SP a fin de que la
nueva cima sea otra vez FFEC, de modo que 3202 no forme parte de la pila. Si se hiciera SP ~ SP + 2
antes de RE ~ [SP] se hubiera pasado a RE en lugar de 3202 el valor O117 que est a partir de FFEC.
Con RET el PGM debe reanudarse con la instruccin que sigue a CALL, cuya direccin (O 117) se guard en
la pila con la ejecucin de CALL, y los dos pasos para hacer este desapilamiento son como los de POPF:
o
l. lP ~ [SPJ en este caso IP ~ [FFEC] puesto que antes de ejecutar RET era SP=FFEC, o sea que estaba ~
apuntando a O117, valor que debe ser ledo a partir de FFEC, por lo que primero debe hacerse esta lectura
para que 0117 pase a RE (figura 3.43). . D
2. SP ~ SP + 2 en este caso FFEC + 2 = FFEE : a fin de desapilar hay que sumarle 2 a SP a fin de que la
nueva cima sea otra vez FFEE, de modo que O117 no forme parte de la pila. Si se hiciera SP ~ SP + 2
antes de IP ~ [SP] se hubiera pasado a IP en lugar de O117 el valor "basura" que est a partir de FFEE.
1
2041
j
'~~~L@=
! 1].
.: FFEC ,
o
[]
o FFED 01 .....!
SP. ~ FFEE l - -- -! []
Figura 3.43 sz
Sistematizando el llamado a una SR y el funcionamiento de la pila: []
- La pila guarda temporariamente datos en forma ordenada, mientras se ejecuta una SR o un anidamiento de []
sucesivas llamadas a SR o interrupciones.
- Los datos tienen una restriccin de acceso: slo pueden agregarse o eliminarse por un extremo de la pila o
"cima" cuya direccin la proporciona el registro SP del PGM que llam a la SR!.
- El ltimo dato colocado en la pila es el primero en quitarse, cuando se comienza a retirar datos. En ingls
esto lo expresan las siglas UFO: ''last in, first out". '
- Se usa la palabra introducir o empujar ("push") para indicar la operacin de colocar un nuevo dato en la
cima de la pila; y sacar o tirar ("pop") para sealar la operacin de retirar el dato de la cima.
ide Cero M,Ginzburg- Assembler desde Cero U3-63
o no es - Cada vez que 2 4 bytes son almacenados ("apilados") en la pila, el valo.- del SP es previamente decre-
mentado en 2 4, respectivamente. Cuando 2 4 bytes son desapilados de la cima, a posteriori ,el SP es
incrementados en 2 4, respectivamente, siendo que los mismos dejar de formar parte de la pila, aunque
queden transitoriamente en memoria. (En "modo real" se apilan o desapilan 2 bytes por vez).
- El SP controla el orden de la pila, y el SP es controlado automticamente pcr la UC durante la ejecucin de
instrucciones que afectan a la pila (como CALL, PUSH, POP y RET).
- Cuando un PGM llama a una SR debe dejar, segn se establezca, en registros o bien en la pila los datos que
la SR procesar, y tomar de registros o bien de la pila, los resultados que necesita ("pasaje de parmetros").
-T
AX=OOOO 8X=OOOO eX=0002 DX=OOOO SP=FFEE 8P=OOOO Sl=1000 DI=OOOO
forma DS=Oee6 ES=Oee6 SS=Oee6 eS=Oee6 IP=0107 NV UP El PL NZ NA PO Ne
oee6 :0107 8F0020 MOV DI, 2000
-T
AX=OOOO 8X=OOOO eX=0002 DX=OOOO SP=FFEE 8P=OOOO 81=1000 DI=2000
DS=Oee6 ES=Oee6 SS=Oee6 eS=Oee6 IP=010A NV UP El PL ZR NA PE Ne
oee6:0IOA 8600 MOV DH, 00
-T
AX=OOOO 8X=OOOO eX=0002 DX=OOOO SP=FFEE 8P=OOOO Sl=1000 Dl=2000
DS=Oee6 ES=Oee6 SS=Oee6 eS=Oee6 IP=OIOe NV UP El PL ZR NA PE Ne
oee6:010e 8804 MOV AX, [SI] DS:l000=2214
-T
AX=2214 8X=OOOO eX=0002 DX=OOOO SP=FFEE 8P=OOOO Sl=1000 Dl=2000
DS=Oee6 ES=Oee6 SS=Oee6 es=oee6 IP=OIOE NV UP El PL ZR NA PE Ne
oee6:010E FEe6 INe DH
-T
JH
AX=2214 8X=OOOO eX=0002 DX=OIOO SP=FFEE 8P=OOOO Sl=1000 Dl=2000
DS=Oee6 ES=Oee6 SS=Oee6 eS=Oee6 lP=OliO NV UP El PL NZ NA PONe
oee6 :0110 89e3 MOV 8X, AX
-T
e la SR AX=2214 8X=2214 eX=0002 DX=OIOO SP=FFEE BP=OOOO Sl=1000 Dl=2000
..=OO DS=Oee6 ES=Oee6 SS=Oee6 es=oee6 IP=0112 NV UP El PL NZ NA PO Ne
t0150 oee6:0112 50 PUSH AX
-T
AX=2214 8X=2214 eX=0002 DX=OIOO SP=FFEe BP=OOOO SI=10l0 Dl=2000
DS=Oee6 ES=Oee6 SS=Oee6 eS=Oee6 1P=Oll3 NV UP El PL NZ NA PO Ne
valor oee6:0113 E8EA33 eALL 3500
!-1 -E FFEe
oee6:FFEe 14. 22. OO.
-T
AX=2214 BX=2214 eX=0002 DX=OIOO SP=FFEA 8P=OOOO SI=IOOO Dl=2000
DS=Oee6 ES=Oee6 SS=Oee6 eS=Oee6 IP=3500 NV UP El PL NZ NA PO Ne
oee6:3500 9e PUSHF
-E FFEA
oee6 :FFEA 16. 01. 14. 22. OO.
-T
SR AX=2214 BX=2214 eX=0002 DX=Oi OO SP=FFE8 8P=OOOO Sl=1000 DI=2000
DS=Oee6 ES=Oee6 SS=Oee6 eS=Oee6 1P=3501 NV UP El PL NZ NA PONe
SR
oee6:3501 51 PUSH ex
-E FFE8
oee6:FFE8 02. 32. 16. 01. 14. 22. OO.
-T
AX=2214 BX=2214 eX=0002 DX=0100 SP=FFE6 BP=OOOO Sl=1000 Dl=2000
DS=Oee6 ES=Oee6 SS=Oee6 eS=Oee6 IP=3502 NV UP El PL NZ NA PO Ne
oee6:3502 53 PUSH BX
-E FFE8
oee6:FFE8 02. OO. 02. 32. 16. 01. 14. 22. OO.
-T
AX=2214 BX=2214 eX=0002 DX=OIOO SP=FFE4 BP=OOOO Sl=1000 Dl=2000
SR DS=Oee6 ES=Oee6 SS=Oee6 eS=Oee6 IP=3503 NV UP El PL NZ NA PO Ne
oee6:3503 8BOEEeFF MOV ex, [FFEC] DS:FFEe=2214
-E FFE4
oee6:FFE4 14. 22. 02. OO.
:<=;40 oee6:FFE8 02. 32. 16. 01. 14. 22. OO.
-T
AX=2214 BX=2214 eX=2214 DX=OIOO SP=FFE4 BP=OOOO Sl=1000 Dl=2000
DS=Oee6 ES=Oee6 SS=Oee6 eS=Oee6 IP=3507 NV UP El PL NZ NA PO Ne
oee6:3507 83F920 eMP eX,+20
-T
AX=22l4 BX=2214 eX=2214 DX=OIOO SP=FFE4 BP=OOOO Sl=lOOO Dl=2000
DS=Oee6 ES=Oee6 SS=Oee6 eS=Oee6 IP=350A NV UP El PL NZ NA PO Ne
oee6:350A 7el4 JL 3520
-T
AX=22l4 BX=22l4 eX=22l4 DX=OlOO SP=FFE4 BP=OOOO Sl=1000 Dl=2000
DS=Oee6 ES=Oee6 SS=Oee6 eS=Oee6 IP=350e NV UP El PL NZ NA PO Ne
oee6:350e 83F941 eMP ex, +41
-T
AX=2214 8X=2214 eX=2214 DX=OlOO SP=FFE4 BP=OOOO SI=lOOO Dl=2000
DS=Oee6 ES=Oee6 SS=Oee6 eS=Oee6 IP=350F NV UP El PL NZ NA PO Ne
oee6:350F 7FOF JG 3520
-T ' e
-T MEJOE
AX=0025 BX=0025 CX=0025 DX=0200 SP=FFE6 BP=OOOO 81=1002 Dl=2000 (A BX volvi desde la pila 0025) La SR d
DS=OCC6 ES=OCC6 SS=OCC6 CS=OCC6 IP=3518 NV UP El NG NZ NA PE CY " buzn"'
OCC6:3518 59 POP CX Para so
-E FFE6
despus
OCC6:FFE6 01. OO.
OCC6 :FFE8 02. 32. 16. 01. 01. OO. OO. altura mi
-T En la SR
AX=0025 BX=0025 CX=OOOI DX=0200 SP=FFE8 BP=OOOO 81=1002 DI=2000 (A CX volvi desde la pila 0001) 01 ()()
DS=OCC6 ES=OCC6 SS=OCC6 CS=OCC6 IP=3519 NV UP El NG NZ NA PE CY Indepenr
OCC6:3519 9D POPF deterrniu
-E FFE8 haba q
OCC6:FFE8 02. 32. 16. 01. 01. OO. OO.
En nuest
-T
lugar sie
AX=0025 BX=0025 CX=0001 DX=0200 SP=FFEA BP=OOOO 81=1002 DI=2000
DS=OCC6 ES=OCC6 SS=OCC6 CS=OCC6 IP=351 A NV UP El PL NZ NA PO NC Como el
OCC6:351A C3 RET ex, [Ff1
-E FFEA Para la
OCC6:FFEA 16. 01. 01. OO. OO. que SI, [
-T O sea q
AX=0025 BX=0025 CX=OOOl DX=0200 SP=FFEC BP=OOOO SI=I002 DI=2000 valor qlli
DS=OCC6 ES=OCC6 SS=OCC6 CS=OCC6 IP=OII6 NV UP El PL NZ NA PO NC (A IP volvi desde la pila 0116)
OCC6:0116 58 POP AX
A su Ve2
-E FFEC deben
OCC6:FFEC l!.!..,__lill. OO. Este nu
-T ~(Con POP AX el resultado 01 =AL pasa de la pasa de la pila hacia AX) caso: dj
AX=OOO.,..- BX=0025 CX=0001 OX=0200 SP=FFEE BP=OOOO Sl=1002 DI=2000 (De la pila volvi a AX el resultado OOQ.l) Con esta
OS=OCC6 ES=OCC6 SS=OCC6 CS=OCC6 IP=Oll7 NV UP El PL NZ NA PO NC cual el ni
OCC6:0117 3C01 CMP AL,Ol
-T PUSH F
AX=0001 BX=0025 CX=0001 DX=0200 SP=FFEE BP=OOOO 81=1002 Dl=2000
PUSH C
DS=OCC6 ES=OCC6 SS=OCC6 CS=OCC6 IP=Oll9 NV UP El PL ZR NA PE NC
OCC6:01l9 750A JNZ 0125
PUSH E
-T PUSH
AX=OOOI BX=0025 CX=0001 DX=0200 SP=FFEE BP=OOOO 81=1002 DI=2000 MOVBI
OS=OCC6 ES=OCC6 SS=OCC6 CS=OCC6 IP=OllB NV UP El PL ZR NA PE NC MOV C
OCC6:0IIB 89D8 MOV AX, BX CMP a
-T JL35
AX=0025 BX=0025 CX=OOOI DX=0200 SP=FFEE BP=OOOO SI=I002 01=2000
OS=OCC6 ES=OCC6 SS=OCC6 CS=OCC6 IP=OllO NV UP El PL ZR NA PE NC
CMP a
JG 3520
OCC6:011D 8905 MOV 1011, AX DS:2000=0025
-T
MOVBJ
AX=0025 BX=0025 CX=OOOl OX=0200 SP=FFEE BP=OOOO SI=I002 01=2000 MOV [B
DS=OCC6 ES=OCC6 SS=OCC6 CS=OCC6 IP=OilF NV UP El PL ZR NA PE NC POPBP
OCC6:011F 83C702 ADD DI, +02 POPB .
-E 2000 POP CX
OCC6:2000 25. OO. (En 2000/1 de la lista apuntada por DI esta 0025) POPF
-T RET
AX=0025 BX=0025 CX=0001 DX=0200 SP=FFEE BP=OOOO 81=1002 01=2002
DS=OCC6 ES=OCC6 SS=OCC6 CS=OCC6 IP=0122 NV UP El PL NZ NA PO NC
OCC6:0122 8835 MOV IDII, DH DS:2002=02 EJERCI
-T A partir
AX=0025 BX=0025 CX=0001 DX=0200 SP=FFEE BP=OOOO 81=1002 01=2002 direccil
OS=OCC6 ES=OCC6 SS=OCC6 CS=OCC6 IP=OI24 NV UP El PL NZ NA PO NC
OCC6:0124 47 INC DI lista a !
.-E 2002 a) Resoli
OCC6:2002 02. (En 20002 de la lista apuntada por DI esta 2, nmero de orden de N2)
-T A 01 00
AX=0025 BX=0025 CX=OOOI OX=0200 SP=FFEE BP=OOOO SI=I002 Dl=2003 xxxx: OIO
OS=OCC6 ES=OCC6 SS=OCC6 CS=OCC6 IP=Ol25 NV UP El PL NZ NA PE NC xxxx:O IO
OCC6:0125 83C602 AOO SI, +02 xxxx: OlO
-T xxxx: OlO
AX=0025 BX=0025 CX=OOOI DX=0200 SP=FFEE BP=OOOO 81=1004 01=2003
DS=OCC6 ES=OCC6 SS=OCC6 CS=OCC6 IP=0128 NV UP El PL NZ NA PO NC
xxxx:O lO
OCC6:0128 FEC9 DEC CL xxxx:OI
-T xxxx:Oll
AX=0025 BX=0025 CX=OOOO DX=0200 SP=FFEE BP=OOOO 81=1004 01=2003 xxxx:O l 1
OS=OCC6 ES=OCC6 SS=OCC6 CS=OCC6 IP=Ol2A NV UP El PL ZR NA PE NC xxxx:O i l
OCC6:012A 75EO JNZ OJOC xxxx:Ol l
-T xxxx:OI I
AX=0025 BX=0025 CX=OOOO DX=0200 SP=FFEE BP=OOOO SI=I004 01=2003 xxxx:O II
OS=OCC6 ES=OCC6 SS=OCC6 CS=OCC6 IP=Ol2C NV UP El PL ZR NA PE NC
xxxx: OI
OCC6:012C CD20 INT 20
Cero M,Ginzburg- Assembler desde Cero U3-69
MEJORAS EN LA SUBRUTINA DEL EJERCICIO ANTERIOR
La SR de la codificacin anterior tiene la limitacin que usa las direcciones fijas FFEC/D de la pila establecidas como
"buzn". Esto implica que as la pila no se puede cambiar de lugar por el sistema opertivo que administra la memoria.
Para solucionar esto, se localizan los "buzones" a partir de la direccin que tiene la cima de la pila, en nuestro caso
despus de ejecutar las instrucciones PUSH AX, CALL 3500, PUSH F, PUSH CX y PUSH BX la cima llega a su
altura mxima, cuya direccin indicada por el SP se mantiene durante todo el procedimiento de la SR.
En la SR anterior mediante MOV CX, [FFEC] se tomaba de la pila el valor N a analizar, y luego se enviaba al "buzn" el
O1 00 del resultado mediante MOV 1FFEC], BH. Despus la pila va cambiando con cada POP que se ejecuta.
Independientemente de las direcciones que ocupan en la pila los registros que ella guarda, el programador de la SR puede
determinar la cantidad de celdas que existen entre la direccin de la cima y la del "buzn", luego que se apil todo lo que
haba que apilar despus del ltimo PUSH de la SR (incluido lo que orden el PGM apilar en el "buzn" con PUSH AX).
En nuestro ejemplo (figura 3.45) puede determinarse que: direccin buzn = FFEC = FFE4 + 8, y si la pila cambia de
lugar siempre seguir siendo: direccin buzn = direccin cima+ 8
Como el registro SP siempre provee la direccin de la cima de la pila, en principio podra pensarse en reem-plazar MOV
CX, [FFEC] por MOV CX, [SP + 8], pero por seguridad esta instruccin no existe.
Para la pila existe un registro auxiliar BP ("Base Pointer", que se puede codificar en Assembler entre corchetes, al igual
que SI, DI y BX, para apuntar a direcciones de la pila, como se requiere en este caso.
O sea que es posible codificar una instruccin como MOV CX, [BP + 8], pero previamente en BP hay que copiar el
valor que tiene SP que est apuntando a la cima, mediante la instruccin MOV BP, SP como se indica ms abajo.
A su vez la utilizacin del registro BP trae aparejada la necesidad de guardarlo en la pila mediante PUSH BP, pues se
deben guardar todos los registros que va a usar la SR, dado que algunos o todos pueden estar siendo usados por el PGM.
Este nuevo apilamiento (en punteado en fig. 3.45) hace que durante el procedimiento de la SR sea siempre en nuestro
caso: direccin buzn= direccin cima+ 1O= direccin cima+ A (en el Debug los nmeros. estn en hexa: 1Od =Ah).
Con esta mejora la pila de un programa podr ser ubicada por el sistema operativo en cualquier lugar de memoria, para lo
cual el ncleo de la SR quedar en definitiva como sigue, con las nuevas instrucciones en negrita:
PUSHF
PUSHCX
PUSH BX
PUSH BP
MOVBP,SP
MOV CX, [BP +A]
CMP CX,20 FFE4 25 BL
JL3520 00 BH
CMP CX,41 01 CL
JG3520 00 CH
MOVBH,Ol 02 RE
MOV [BP+A], BH 32 RE
POPBP 16 IP
POPBX OI IP
POPCX 25 AL (Con MOV [FFEC], BX el 25 que lleg con PUSH AX
POPF 00 AH es reemplazado por O1)
RET S 00
Figura 3.45
EJERCICIO 47:
A partir de la direccin 2000 existe una lista de nmeros naturales de 2 bytes, cuya cantidad est en la
direccin 1500. Determinar la raz cuadrada de cada uno, sumarle 3, y al nmero resultante guardarlo en otra
lista a partir de la direccin 3000. Este problema se basa en el ejercicio 41
a) Resolucin por medio de pasaje de parmetros a travs de registros (en este caso se us BX)
A 0100
xxxx:OlOO MOV CL, [1500] Carga en CL la cantidad n de nmeros de la lista
xxxx:OI04 MOV SI, 2000 El registro SI apunta al comienzo de la lista de datos
xxxx:0107 MOV DI, 3000 DI apunta al comienzo de la lista de resultados
xxxx:OIOA MOV BX, [SI] Carga en BX (para la subrutina) un dato de la lista apuntada por SI
xxxx:O 1OC CALL 5000 Llama a subrutina que est en 5000 para calcular raz cuadrada
xxxx:010F MOV AX, 3 Carga en AX el valor 3
xxxx:0112 ADD AX, BX Suma 3 al resultado de la raz cuadrada dejado por la subrutina en BX
xxxx:Ol14 MOV [DI], AX Guarda el nmero resultante en la lista apuntada por DI
xxxx:0116 ADD SI, 2 Incrementa en 2 el puntero SI
xxxx:0119 ADD DI, 2 Incrementa en 2 el puntero DI
xxxx:O 11 C DEC CL Decrementa CL
xxxx:011E JNZ OlOA Mientras Z=O, volver a O1OA
xxxx:0120 INT 20 Fin
U3-70 M.Ginzburg- Assembler desde Cero M,Ginzb
A 5000 (Contintrn
xxxx:5000 PUSHF Guarda los flags (Registro de Estado) en la pila 1 xxxx: 500"
xxxx:5001 PUSHAX Guarda AX en la pila xxxx:5()(P.
xxxx:5002 PUSHCX Guarda BX en la pila xxxx: 5001
xxxx:5003 PUSHDX Guarda DX en la pila xxxx: 500l
xxxx:5004 SUBDX,DX Lleva a cero el registro DX xxxx: Oll
xxxx:5006 MOV AX,BX Carga en AX el nmero N de 16 bits (dejado en BX) cuya raz se quiere hallar xxxx: 501
xxxx:5008 MOVCX,C8 El divisor ex toma el valor CSH = 200o xxxx: 50lc
xxxx:500B DIVCX Divide por 200, y el resultado queda en AX xxxx: 50 ll
xxxx:OlOD ADDAX,2 Suma 2 como pide el algoritmo xxxx: 50l:
xxxx :5010 MOVCX,AX Lleva Al (cociente) que est en AX hacia CX (divisor) xxxx: 50I l
xxxx:5012 SUBDX,DX Lleva a cero el registro DX xxxx:50ll
xxxx:5014 MOV AX,BX Vuelve a cargar en AX el nmero N de 16 bits xxxx:s02
xxxx:5016 DIVCX Divide por Al xxxx:so_;
xxxx:5018 ADDAX,CX SumaN/Al que est en AX con Al que est en CX xxxx:50 '
xxxx:501A SHRAX, 1 Divide por 2 la suma antes hallada, para hallar A2 xxxx:SOT
xxxx:501C CMPAX,CX Compara A2 con A 1 xxxx:502.
xxxx:501E JZ 502C Si son iguales, terminar xxxx: 50
xxxx:5020 SUBCX,AX RestaA1 - A2 xxxx:502l
xxxx:5022 CMPCX, 1 Compara (A 1 - A2) contra 1 xxxx:503 1
xxxx:5025 JZ 502C Si es igual a 1, terminar xxxx:503-
xxxx:5027 CMPCX,-1 Si no es igual a 1 determina si es -1 = FFFF xxxx: 503:
xxxx:502A JNZ 5010 Si no es igual a -1 se hace otra aproximacin xxxx:50
xxxx:502C MOVBX,AX Guarda An vlida en BX xxxx: 503"
xxxx:502E POPDX Restaura DX desde la pila xxxx: 5032
xxxx:502F POPCX Restaura CX desde la pila xxxx:503!
xxxx:5030 POPAX Restaura AX desde la pila
xxxx:5031 POPF Restaura los flags en el Registro de Estado desde la pila
xxxx:5032 RET Retorna al programa principal
1
xxxx:500C PUSH AX Guarda AX en la pila (es el nmero N cuya raz se quiere hallar)'
xxxx:OlOD CALL 5000 Llama a subrutina para calcular raz cuadrada que est en 5000
xxxx:Ol!O POP AX Restaura AX desde la pila (la raz cuadrada calculada)
xxxx:0112 ADD AX, 3 Suma 3 a la raz cuadrada calculada
xxxx:0114 MOV [DI], AX Guarda el nmero resultante en la lista apuntada por DI
/1 2d=(
xxxx:Oll6 ADD SI, 2 Incrementa en 2 el puntero SI
xxxx:0119 ADD DI, 2 Incrementa en 2 el puntero DI
1
xxxx:OllC DEC CL Decrementa CL
xxxx:011E JNZ lOA Mientras Z no sea 1, volver a 1OA
xxxx:O 120 INT 20 Fin
A5000 STACK(
xxxx:5000 PUSHF Guarda los flags en la pila (designados REH y REL en la figura 3.33) Una su
xxxx:5001 PUSH AX Guarda AX en la pila (designado por sus porciones AH y AL en la fig. 3.33) 3 "anidam;
xxxx:5002 PUSH CX Guarda CX en la pila (en sus porciones CH y CL en la figura 3.33)
subrut
xxxx:5003 PUSH DX Guarda DX en la pila (en sus porciones DH y DL en la figura 3.33)
xxxx:5004 PUSH BP Guarda BP en la pila (en sus porciones BPH y BPL en la figura 3.33) en orden
xxxx:5005 MOV BP, SP Carga en BP el valor de SP, as tambin BP apunta a la cima de la pila llamado.
de sub
Si por al~
1
En general, esto es necesario hacerlo, dado que cuando se ejecute la subrutina cambiar el valor de los flags, siendo que se requiere dando l
volver a la secuencia principal con los mismos valores que tenan los flags antes del llamado a la subrutina. C-omo se ver, en cualquier operativc
tipo de interrupcin se guardan automticamente los flags, o sea el Registro de Estado, en la pila.
2
Indicado como AH y AL en la base de la pila de la figura 3.46
3
Este nuevo apilamiento de AX, o sea de N, indicado tambin como AH y AL, puede servir, por ejemplo, para hacer ..JN +N (en vez
de ..JN +3) en cuyo caso la secuencia principal se podra modificar como sigue:
CALL 5000
MOVDX,AX 1
Figura3.
POPAX comienzo
ADDAX,DX 2
S~rn 1111!
le Cero M,Ginzburg- Assembler desde Cero U3-71
BPL
BPH
}sP
CL
CH
}ex
BL
BH
}sx
AL
AH
}Ax
REL
} RE(flags)
REH
IPL IP (Direccin
IPH } de retorno)
AL
} AX (N yVN)
AH
Base
Figura 3.46
STAeK OVERFLOW
Una subrutina puede llamar a otra, sta a una tercera, y as sucesivamente. Este proceso se conoce como
"anidamiento de subrutinas". Cuando la ltima subrutina llamada termina de ejecutarse, se retoma a la
subrutina que la llam, sta a la que la llam, y as de seguido. De este modo los retornos se van sucediendo
en orden inverso al de las llamadas. El ltimo retomo ser hacia el programa principal, que efectu el primer
llamado. Conforme a lo visto, el mecanismo de operacin de la pila permite cuidar el orden en el anidamiento
de subrutinas.
Si por algn error de programacin este orden falla o no termina, la pila puede crecer de forma descontrolada,
requiere dando lugar a lo que se conoce como " stack overflow" (desborde de pila), situacin que detecta el sistema
cualquier operativo.
(en vez
1 Figura 3.46: el nmero N cuya raz se quiere hallar est en la base de la pila, y siendo que ahora BP apunta a la cima, entre sta y el
De lo anterior se desprende que las interrupciones por software son una forma de llamar al SO para que Salvo Je{J
prest:'! servicio a aplicaciones, pues ste "por su cuenta" no pasa a ser ejecutado por la UCP sino mediante Las difere
este tipo de interrupciones o cuando ocurre una interrupcin por hardware (se tratan en detalle ms adelante). zona de
tambin l
DETALLE DE LA EJECUCION DE INSTRUCCIONES INT xx (INTERRUPCION POR SOFTWARE) ("interru
Puesto que una interrupcin es una forma de llamado a subrutina, en relacin con el uso de la pila valen las
consideraciones hechas al tratar ese tema, como se ejemplificar.
EJERCIC
Subrutina que El presenn
Zona de
Vectores sirve a INT 21 Por ser
(instrucci
o<o~ 0000:0084 20 } IP ~ EA30:4C20 PUSH AX
do y se pa;
1).~\J PUSH BX
4C
rz_'\~ G) Antes que
XXXX:0104 MOV AH, 2
30
EA
)es} tros IP, C
XXXX:01 06 INT 21 El registro
XXXX:01 08 INC DL-------- @
@ do I vin
habilita Las
Cuando I =
POP BX
Este flag 1
1 POP AX
- -- contenido
EA30:hhhh IRET
o del SO, ~
FFE8 08
? FFE9 01 IP
.p
FFEA
FFEB
XX
XX
es 1
Esta zoc
explica la
/
~ FFEC 81
FFED 80 RE cada inte
2
Una ap!:
SP ---.. --------------- FFEE
provocara
Figura 3.47
~;de Cero M,Ginzburg- Assembler desde Cero U3-73
Dada la secuencia:
GM que xxxx:Ol04 MOV AH, 2
le la SR. xxxx:OI06 INT 21
xxxx:Ol08 INC DL
funcin para ejecutar una instruccin INT xx, como ser lNT 21, la UC realiza los siguientes pasos (figura 3.34):
ilor tener
l. Multiplica por 4 el nmero que acompaa a IN T. Por ejemplo, (en hexa) 21 x 4 = 84 = 0084
;or Call" 2. El resultado obtenido es la componente derecha de una direccin cuya ' ..mponente izquierda es siempre
11. SRdel 0000, esto es 0000:0084, direccin que est dentro del primer segmetito donde empieza en 00000 =
1 de ellas =0000:0000 de la memoria principal (figura 3.38) denominada "zona de vectores interrupcin" 1 .
io. Esta es la direccin donde a su vez se encuentra la direccin CS:IP de la SR que atiende a INT 21. 2
ty prote- Como a partir de la direccin 0000:0084 est la direccin (CS:IP = EA30:4C20) de la SR que sirve a
lores), INT 21, o sea (figura 3.47), que el contenido de las 4 cci,bs que empiezan en 0000:0084 apunta al co-
"abrir", zo de la SR, por lo cual ste se llama "vector interrupci,1'?.,
INTxx 3. La UC guarda en la pila (figura 3.47) el registro de estado (;;lE) conteniendo los flags. Sobre ste apila la
un PGM direccin de retomo (xxxx:0108) de la instruccin (INC DL) que sigue a INT 21. Por lo tanto, el SP pasa
cuando de FFEE a FFE8. El RE en el80286 tiene 16 bits dispuestos como sigue (figura 3.48)
~n donde Suponiendo que los fl ags tengan los valores supuestos a continuacin, el contenido del RE en hexa sera.:
x provee
lol ololo l1lo lo lo l1lo lo lo olo ol1l =0881
1 1
.J o supe-
;iones de 4. Ejecuta la SR llamada por INT 21. Las instrucciones PUSH con que empieza sta, ordenarn guardar en la
n la UCP pila el contenido de registros de la UCP. Asimismo, las instrucciones POP que estn al fmal de la SR
ordenar restaurar desde la pila los contenidos de los registros guardados rridiante las instrucciones PUSH.
tras que
raciones. 5. La ltima instruccin de la SR, que necesariamente debe ser IRET ordena retomar a la instruccin que
SO y los sigue a INT 21 en el PGM llamador (o sea a INC DL), cuya direccin xxxx:0108 est en la pila. Tambin
SO. retoma desde la pila el contenido del RE. Luego de ejecutarse IRET, el SP vuelve a su valor inicial FFEE.
para que Salvo pequeas diferencias, se observan grandes similitudes con lo visto al tratar el llamado a subrutina.
mediante Las diferencias consisten, en primer lugar, en que con INT xx ladireccin de la subrutina se halla a travs de la
elante). zona de vectores (figura 3.47). Por otro lado, con INT adems de salvarse la direccin de retomo (CS :IP),
tambin se guarda en la pila el registro RE (flags). Por ello, la instruccin de retomo se llama IRET
l"W ARE) ("interrupt return"), dado que adems del CS:IP de la direccin de retorno, ordena restaurar los flags en RE.
alen las
El registro RE adems de los valores de Jos flags SZVC contiene el valor O (El en el Debug) 1 (DI) de un flag designa-
do 1 vinculado a las interrupciones, que hasta la ejecucin de cualquier INT xx vale cero (El = Enable I) indican-do que
habilita las interrupciones por hardware durante la ejecucin de cualquier instruccin anterior a INT xx.
Cuando l =O se dice que la UCP est en "modo user", admitiendo interrupciones por hardware.
3X Este flag l durante la ejecucin de cualquier lNT xx pasa a valer 1 (DI = Disable 1), por lo que tambin cambia el
AX contenido de RE, del cual el valor del flag 1 forma parte. Como Juego de lNT xx la UCP pasa a ejecutar una SR del BlOS
o del SO, se dice que la UCP paso de modo "user" a "modo kernel!".
1
Esta zona, que cada sistema operativo escribe luego del booteo, consta de vectores que ocupan 4 posiciones de memoria, de donde se
explica la multiplicacin por 4 (en binario por 100). Como se ver al tratar interrupciones por hardware, tambin existe un vector para
cada interrupcin por IRQ, de modo que as se pueda localizar la subrutina que la atiende ..
2
Una aplicacin, no sabe dnde est localizada la SR que le va a dar servicio. Si sta tuviera direccin fija, cualquier cambio en el SO
provocara una reprogramacin de la aplicacin.
U3-74 M.Ginzburg- Assembler desde Cero M,Ginzl
La SR que atiende a INT61 consta de 5 instrucciones representativas de una SR del BIOS, sin sentido real, y termina con -E oooq
IRET, que permite retornar a la instruccin que sigue a INT61 (en este caso POPF (RE ~Pila). 0000:01
Para retornar la instruccin IRET (opuesta a cualquier INT xx) devuelve desde la pila hacia los registros IP, CS y RE trae
de la pila los valores que tenan antes de que se ejecute INT 61 (en este caso sern los que tenan mientras se ejecutaba la A cont
SR que permiten seguir con POPF y el flag I se pone en El (modo "user") para que nuevamente la UC autorice interrup-
ciones por hardware del tipo IRQ (ver ms adelante). Es imPQ
lo cual "'
ciones;]
p~ZL-ubrutina -AO JO(
OCC6:01
OCC6:0l
1 OCC6:01
OCC6:01
1 OCC6:01
OCC6:01
1 Zona de OCC6:01
vectores OCC6 :01
1 OCC6:01
~~2)1
OCC6:01
OCC6:01
OCC6:01
1 OCC6:01
1~==:
OCC6:01
OCC6:01
OCC6:01
OCC6:01
OCC6:01
OCC6:01
MEMORIA OCC6:0
-A 3500
OCC6 :3
OCC6:3
OCC6:3_
OCC6:3_
OCC6:3_
OCC6:3
-A 3520
OCC6:r:
OCC6 :3"":
En la si.,
IRET del BIO
a anal i=
Subrutina del SO AX res
o del BIOS que
-AODU :
atiende a INT 61 ODE4:50l
Figura 3.49 ODE4 :50l
ODE4:5()[
Despus el diagrama lgico (figura 3.49) sigue el mismo curso que el de la figura 3.41 , siendo que en grisado se han ODE4:5()[
dibujado los pasos nuevos, y que los pasos anteriores CALL SR 3500 y RET tambin estn en grisado. ODE4:5()[
Mediante el Debug se codificar en Assembler el diagrama de la figura 3.49, y se ejecutar para los mismos valores del
ejercicio 46.a, como sigue a continuacin. Figun
-E 1000
OCC6: 1000 OO.FF OO.FF 00.25 00.00
-E 1500
R
OCC6: 1500 00.02
AX=OOOO
Paso importante que no se puede obviar: escribir en el vector que empieza en la direccin 0000:0184 (siendo 184h DS=OCC6
= 6 1 x 4) !.a direccin ODE4:5000 (ver figura 3.50) elegida arbitrariamente para la primera instruccin de las 5 de la
OCC6:0 HH
SR que atienden a INT61, pues sino la UC no encontrar esta SR. Este vector sirve de enlace entre INT61 y la SR.
esde Cero M,Ginzburg - Assembler desde Cero U3-75
mina con -E 0000:0184
0000:0184 00.00 00.50 OO.E4 OO.OD (Sin este paso no se podr ejecutar la secuencia que sigue a continuacin
y RE trae
:cutaba la A continuacin se codifica en Assembler el diagrama de la figura 3.49, y luego se ejecutan las instrucciones.
interrup-
Es importante observar durante la ejecucin, que antes de la ejecucin de INT 61 el flag I de l RE estaba en El (Enable I),
lo cual implica que estn habilitadas las interrupciones por hardware que tengan lugar durante la ejecucin de las instruc-
ciones; y que luego de la ejecucin de INT 61 el flag I pasa a DI (Disable I) inhabilitando dicho tipo de interrupciones.
-A 0100
OCC6:0100 MOVCL, [1500] Carga en CL la cantidad n de nmeros de la lista
OCC6:0104 MOV SI, 1000 Inicializa SI= 1000
OCC6:0107 MOV DI, 2000 Inicializa DI= 2000
OCC6:010A MOVDH, 00 Inicializa DH = 00
OCC6:0IOC MOV AX, [SI ] Lleva hacia AX una copia del nmero N apuntado por SI
OCC6:010E INCDH Cada vez que se toma un nmero nuevo de la lista se suma uno al contador de orden DH
OCC6:0110 MOVBX,CX Guarda en BX una copia de CX, que luego ser modificado para la SR
OCC6:0112 MOVCX,AX Copia en CX una copia de AX, para que luego sea el dato que procesar la SR
OCC6:0114 CALL 3500 Pasa a ejecutar la SR que est en 3500
OCC6:0117 CMPCH,Ol Luego de que se ejecut la SR, se vuelve al PGM para restar CH - O1
OCC6:011A JNZ 0124 Si de CH- 01 fue Z=O es que no es CH=01, o sea que no fue 20:SN:S40, saltar a 0124
OCC6:011C MOV [DI],AX Copia en la lista apuntada por DI el nmero N comprendido entre 20 y 40
OCC6:011E ADDDI,2 Suma 2 a DI para preparar debajo la escritura del nmero de orden de N debajo de su valor
OCC6:0121 MOV [DI],DH Escribe en la direccin apuntada por DI una copia del nmero de orden que indica DH
OCC6:0123 INCDI Se actualiza DI por si en AX llega otro N comprendido entre 20 y 40
OCC6:0124 MOVCX,BX Desde BX se restaura el valor .que tena CX antes de llamar a la SR
OCC6 :0126 ADD SI, 2 Si Z=l (AX = AXanterior) suma 2 a SI para apuntar siguiente nmero N de la lista
OCC6:0129 DECCL Resta uno a la cantidad de nmeros que falta analizar en la lista apuntada por SI
OCC6 :012B JNZOIOC Mientras sea Z=O saltar a 010C para considerar el nmero siguiente de la lista
OCC6:012D INT20 Finalizar
-A 3500
OCC6:3500 PUSHF Guarda en la pila el valor de los Flags que usaba el programa, contenidos en el registro RE
OCC6:3501 CMPCX,20 Resta CX- 20 para que SZVC tomen valores, siendo CX =N
OCC6:3504 JL 3520 Si St-V resulta CX < 20 entonces saltar a 3520
OCC6:3506 CMP CX,41 Resta CX- 41 para que SZVC tomen valores
OCC6:3509 JG 3520 Si S=V resulta CX 2:41 (o sea CX > 40) entonces saltar a 3520
OCC6:350B MOVCH,Ol Si St-V (CX < 41) se hace CH = 01, para indicar que 20 :S CX :S 40
OOA7:350D INT61
OCC6:350F POPF Pasa de la pila a RE el valor que tenan los flags en el programa antes de llamar a la SR
OCC6:3510 RET Pasa de la pila al IP la direccin O117 de la instruccin por la cual prosigue el programa
-A 3520
OCC6 :3520 MOVCH,OO Si S=V (CX 2: 41) (o sea CX > 40) se hace CH=OO, para indicar que no es 20 :S CX :S 40
OCC6:3522 JMP350F Saltar incondicionalmente a 350F
En la siguiente secuencia, las instrucciones MOV y ADD quieren ser representativas de una SR del sistema operativo o
del BIOS. Se han elegido por que modifican e l registro AX que en el PGM antes de CALL 3500 contena el nmero N
a analizar, y por que tambin modifican valores de flags que haban cambiado en la SR, siendo que PUSH AX y POP
AX restauran el contenido con que AX qued antes de llamar a la SR.
-A ODE4 :5000
ODE4:5000 PUSH AX
ODE4:5001 MOV AX, 8000
ODE4:5004 ADD AX, AX
iado se han ODE4:5006 POP AX
ODE4 :5007 IRET
Ya!ores del
Figura 3.50
R
AX=OOOO BX=OOOO CX=OOOO DX=OOOO SP=FFEE BP=OOOO SI=OOOO DI=OOOO
;;ien do 184h DS=OCC6 ES=OCC6 SS=OCC6 CS=OCC6 IP=O IOO V UP El PL NZ NA PO NC
OCC6:0100 8AOE0015 MOV CL, [15001 DS: l500=02 (El valor 02 que est en 1500 se copia en CL)
~ las5dela
tl y la SR.
U3-76 M.Ginzburg- Assembler desde Cero M,Gi nzb
Se comprende que se puede usar parte de esta secuencia para visualizar por pantalla cualquier mensaje, con tal que cada
vez que se ejecuten MOV AH, 2 e INT 21 est antes en el registro DL el cdigo ASCII del prximo carcter a visualizar,
en el orden que corresponda a las letras y espacios del mensaje a visualizar.
Las instrucciones de interrupcin por software, tipo INT 21, no se pueden ejecutar en el Debug mediante el comando T,
sino que debe usarse el comando P.
La secuencia anterior puede ejecutarse de una vez con el comando G = 0100, habiendo puesto previamente IP=0100
mediante RIP
El lector interesado puede hacer la siguiente indagacin para INT 21, usando el Debug.
sigue el Siendo 21x4 = 48, mediante el comando E 0000:0048 ubicar los 4 bytes que constituyen el CS:IP de la primera
instruccin de la subrutina que atiende a INT 21.
Luego, mediante el comando U CS:IP podr ver y seguir en Assembler dicha subrutina, pulsando nuevamente cada vez
que quiera proseguir viendo en pantalla las instrucciones siguientes de la subrutina.
Otra prueba que puede reali zarse med iante E 0000:0048 es intentar re escribir el vector interrupcin de INT 21 (cosa que
un virus puede hacer)
EJERCICIO 49: Secuencia para esperar el ingreso de caracteres por teclado, cuyo nmero se indica en la
direccin 2000, los cuales a medida que van ingresando se observan en pantalla y se deben guardar a partir de
la direccin 200 l. El programa se queda esperando hasta que se han tipeado todos los caracteres. Tiene la
limitacin que al apretar la tecla Enter se vuelve al comienzo de rengln, sin saltar al rengln siguiente.
U3-78 M.Ginzburg- Assembler desde Cero M,Ginzbu
A 0100 EJERCIC
xxxx:OIOO MOV CL, (2000] Carga en CL el nmero de caracteres a tipear de dire
xxxx:0104 MOV DI, 2001 Inicializa a DI en 2001 Ejemplo:
xxxx:0107 MOV AH, 1 INT 21 con AH= ! permite entrar un caracter por teclado. El programa que- Suponi en~
da esperando hasta que se tipee el caracter, que luego aparece por pantalla
SienDL t
xxxx:0109 INT 21 Llama a subrutina del DOS que realiza lo indicado con AH=! visualice j
xxxx:OIOB MOV [DI] , AL Guarda en la lista apuntada por DI el cdigo ASCII caracter tipeado, que Cargar 3-
INT 21 deja en AL Cargar 41
xxxx:OlOD INC DI Incrementa DI Cargar 3
xxxx:O 1OE DEC CL Decrementa la cantidad de repeticiones a realizar
Cargar3 1
xxxx:OIIO JNZ 0109 Mientras Z=O, volver a 0109
Por lo tan
xxxx:O 112 INT 20 Fin valor (cua
Luego de l
EJERCICIO 50: La siguiente secuencia, sobre la base de otra desarrollada por el Sr. Germn Apestegua, ROLBX,
espera el ingreso por teclado de 8 dgitos, como ser los de un DNI. Adems, realiza una validacin que (La instrut
rechaza el ingreso de caracteres 110 numricos, producindose en tal caso un "beep" por el parlante de la
computadora. Una vez finalizada la carga de los 8 dgitos, se visualizan por pantalla nuevamente, en una
lnea, todos los dgitos ingresados, mediante la funcin 9 de INT 21. En cada d
(subrayadc
-A 0100 BX, luego
xxxx:OIOO MOV SI, 2000 Inicializa SI en 2000, comienzo de la lista a visualizar luego en pantalla
ConMO
xxxx:0103 MOVCL, 8 Inicializa CL en 8, nmero de caracteres de un DNI
AND AL,
xxxx:Ol05 MOV AH, 1 Inicializa parmetros para esperar que se tipee un carcter, que se ve en pantalla
(O y O= 0:
xxxx:0107 lNT21 Llama subrutina del BIOS. El carcter tipeado queda en AL
ADD AL
xxxx:0109 CMP AL, 30 Compara el caracter entrado por teclado con 30 (cdigo ASCII del O)
As, para
xxxx:OIOB JB 0130 Si el cdigo ASCII entrado es menor que el ASCII del O, salta a 0130
xxxx:OIOD CMPAL, 39 Compara el carcter entrado por teclado con 39 (cdigo ASCII del 9) Para cuam
xxxx:OlOF JA 0130 Si el cdigo ASCII entrado es mayor que el ASCII del9, salta a 0130 ADD AL, J
xxxx:0111 MOV [SI] , AL Guarda en memoria el carcter dej ado en AL al ejecutarse INT 21
xxxx:0113 INC SI Se prepara para guardar otro caracter tipeado en memoria xxxx:O IOO
xxxx:0114 DEC CL Resta 1 a CL por haberse tipeado uno de los 8 caracteres xxxx:0 1
xxxx :Ol16 JNZ 0105 Mientras CL no sea cero, volver a O105 xxxx:O I
xxxx:0118 MOV AL, 24 Carga 24 (cdigo de$) al registro AL
xxxx :OllA MOV [SI], AL Escribe 24 al final de la lista de caracteres tipeados (Para la prx . lNT 21)
xxxx:011C MOV SI, 2000 Vuelve SI a su valor 2000 xxxx:O 100
xxxx:OllF MOVDX, SI Carga en DX el valor de SI, como lo exige la prxima INT 21 xxxx:Ol OE
xxxx:0121 MOV AH, 9 Inicializa parmetros para que escriba en pantalla una lista de nmeros xxxx:Ol l
que empieza en direccin indicada por DX y termina con el nmero 24 xxxx:O l l
xxxx :0123 INT 21 Llama a subrutina del BIOS para que imprima la lista en memoria xxxx:O l l
xxxx:O125 INT 20 Fin xxxx:0 116
-A 0130 xxxx:O l l
xxxx:O 130 MOV DL, 07 Deja en DL el ASCII 07 (bell) para que pueda escucharse un "beep" xxxx:O l l
xxxx:0132 MOV AH, 2 Inicializa parmetros para ver (en este caso escuchar) el ASCII 07 xxxx :Ol lG
xxxx:Ol34 INT 21 Llama a subrutina del BIOS para visualizar caracteres por pantalla xxxx:O l iE
xxxx:Ol36 .TMP 0105 Vuelve a 0105 xxxx:OJ 2
EJERCICIO 51: Secuencia para esperar el tipeo de cualquier nmero de caracteres por teclado, los cuales se
visualizan en pantalla. Cuando se terminan de tipear se debe pulsar la tecla ESP . Tiene la limitacin que no
funciona correctamente la tecla Enter, pues no se puede saltar de rengln. EJERCI
de 2 bytes
xxxx:OlOO MOVAH,6 Valor en AH para que INT 21 cargue cada caracter tipeado en AL , y que aASC U. l
cada vez que ello ocurre sea Z=O, y Z= l mientras no se tipee ninguno Ellos debe
xxxx:Ol02 MOVDL, FF Se requiere cargar en DL el cdigo FF (ASCII extendido)
Llama a subrutina del BlOS para cargar en AL el caracter tipeado Para com
xxxx:Ol04 INT 21
JZ 0100 Mientras sea Z=l (no hay tipeo) volver a 0100 (loop de espera) pasar, en e
xxxx:Ol06
mquina
xxxx:0108 CMPAL,2B Compara el cdigo ASCII de la tecl a tipeada con 28 (ASCII de ESC)
xxxx:OlOA JZ 0130 Si es igual a 2B saltar a 0130 (Fin) cero. Esto
primer d_
xxxx: OlOC MOVDL,AL Si no es ESC, pasar a DL el ASCII tipeado para preparar su visualizacin
La subru
xxxx:OlOE INT21 Llama a subrutina del BIOS para visualizar el caracter tipeado
Vuelve al loop de es5era de tecla tipeada inverso a
xxxx:OllO JMP 0100
xxxx:Ol30 INT20 Fin
1 - - - - -- -- -
_ Cero M,Ginzburg- Assembler desde Cero U3-79
EJERCICIO 52: Secuencia para leer los contenidos (binarios) de dos posiciones consecutivas de memoria,
de direcciones 2000 y 2001, y mostrarlos en hexa en la pantalla en orden inverso
Ejemplo:
Suponiendo que el Debug en las posiciones 2000/1 nos muestra 41. 5A. en pantalla se debe ver 5A41
Si en DL cargamos 41 y luego ejecutamos MOV AH, 9 e INT 21 en pantalla aparecer una A en vez de 41 . Para que se
visualice 5A41 hay que realizar lo que sigue.
Cargar 35 (cdigo ASCII de 3) en DL y luego ejecutar MOV AH, 9 e INT 21
Cargar 41 (cdigo ASCII de A) en DL, y luego ejecutar MOV AH, 9 e INT 21
Cargar 34 (cdigo ASCII de 4) en DL y luego ejecutar MOV AH, 9 e INT 21
Cargar 31 (cdigo ASCII de 1) en DL y luego ejecutar MOV AH, 9 e INT 21
Por lo tanto, primero habr que generar los cdigos ASCII de cada uno de los 4 caracteres a visualizar, a partir de su
valor (cuarteto binario que ocupa la mitad de una posicin de memoria). Esto hace la secuencia abajo desarrollada.
Luego de MOV BX, [2000] 'resulta: BX= Q101101001000001 =5A41
~egua,
ROL BX, CL (con CL puesto antes en 4) efecta 4 desplazamientos: 101101001000001Q
(La instruccin ROL ordena rotate left) QI1010010000010!
in que
l10100100000101Q
te de la
101001000001010! = A415
en una
En cada desplazamiento, los bits de BX se desplazan una posicin a la izquierda, y el bit extremo izquierdo de BX
(subrayado) pasa a ser el bit extremo derecho de BX. De esta forma, el 0101 (5) que estaba en la extrema izquierda de
BX, luego de 4 desplazamientos pasa a la extrema derecha de BX.
Con MOV AL, BL resulta: AL= 00010101 = 15
AND AL, OF ordena hacer bit a bit una And ("y") entre el contenido de AL y OF And 00001111 = OF
mil a (O y O= O; O y 1 =O; 1 y O= O; 1 y 1 = 1) para hacer O el cuarteto superior de AL: 00000101 = 05
ADD AL, 30 ordena sumarle 30 a AL 00110000 = 30
As, para los cuartetos del O al 9 se forma el cdigo ASCII, en este caso 35 00110101 = 35
Para cuartetos de A hasta F ( codigo ASCII> 39) se debe sumar luego 7 = 00000111 . En este ejemplo, para la A, luego de
ADD AL, 30 el resultado sera 00111 O1O. Este sumado a 00000111 da O1000001 = 41 (cdigo ASCII de A)
xxxx:OIOO MOV BX, [2000) Carga el contenido de 2000 y 2001 en BL y BH, respectivamente
xxxx:0104 MOV CH, 4 Carga en CH el nmero de loops a repetir
xxxx:O 106 MOV CL, 4 Carga en CL la cantidad de bits a rotar en BX
xxxx:0108 ROL BX, CL Rota a izquierda 4 veces en BX
xxxx:OIOA MOV AL, BL Carga en AL el valor de BL para no destruir luego contenidos de BX
xxxx:OIOC AND AL, OF Pone en O el cuarteto superior de AL
xxxx:010E ADD AL, 30 Suma 30 para convertir el nmero de AL en ASCII (resultando de 30 a 3F)
xxxx:O 11 O CMP AL, 39 Compara con 39 (cdigo ASCII del 9)
xxxx:0112 JBE 0116 Pregunta si es< 39 en cuyo caso en AL est el cdigo ASCII (del O al9)
xxxx:0114 ADD AL, 07 Si es mayor suma 7 (por ej. 3A + 7 = 41 =cdigo ASCII de A)
xxxx:Oll6 MOV DL, AL Para el BIOS (prxima INT 21) carga el nmero de AL en DL
xxxx:OJJ8 MOV AH, 2 Inicializa parmetros para ver en pantalla el caracter ASCII que est en DL
xxxx:011A INT 21 Llama a subrutina del BIOS
xxxx:O 11 C DEC CH Decrementa cantidad de Joops a realizar
xxxx:OllE JNZ 0106 Mientras Z=O, volver a O106
xxxx:0120 INT 20 Fin
cuales se
q ue no
EJERCICIO 53: Secuencia para visualizar en pantalla como nmeros decimales a nmeros binarios naturales
de 2 bytes que estn en memoria. Para ello se requiere convertir estos nmeros binarios a dgitos BCD y stos
a ASCII. Los nmeros binarios fonna una lista que est a partir de la direccin 1000, y su longitud est en 2500.
Ellos debern verse en pantalla en decimal uno debajo del otro.
Para convertir de binario a BCD se usa el algoritmo de los restos de las sucesivas divisiones por la base a la que se quiere
pasar, en este caso diez. En el papel, cuando se pasa de base diez a base dos, las cuentas se hacen en base diez. En la
mquina las divisiones se hacen en base dos, y el divisor es 1010 (base diez en binario) y terminan cuando el cociente es
cero. Esto implica una divisin ms, para detectar cuando el cociente es menor que el divisor, siendo que su resto es el
primer dgito BCD. En base diez ste era el cociente de la ltima divisin.
C3lizacin
La subrutina que pasa a BCD realiza las divisiones de la forma vista en el ejercicio 36, y para tomar los restos en orden
inverso a su generacin usa la pila.
U3-80 M.Ginzburg- Assembler desde Cero M,Ginzb
A 0100 in terrllDlj
xxxx :0100 MOV ex, (2500] Carga en CX la longitud de la lista Se compl
xxxx:0104 MOV SI, 1000 El registro SI apunta al comienzo de la lista de datos zar un p(
xxxx:0106 MOVAX, (SI] Carga en AX un dato de la lista que apunta SI, a ser usado por subrutina
ADD SI, 2 hora, o
xxxx:0108 Incrementa en 2 el puntero SI
xxxx:010B eALL5000 Llama a subrutina para conversin y visualizacin que est en 5000 Los eve
xxxx:011E DEe ex Decrementa CX lo que el
xxxx:011F JNZ 106 Mientras Z no sea 1, volver a 106 Tambin
xxxx:0111 INT 20 Fin -cuando
y el res
A 5000
xxxx:5000 PUSHBX Guarda BX en la pila - si la insl
xxxx:5001 PUSHeX Guarda CX en la pila -si la din
xxxx:5002 PUSHDX Guarda DX en la pila Estos e e
xxxx:5003 MOV eX,O Lleva CX a cero, para ser usado como contador la SR del
xxxx:5006 MOV BX,A Carga en BX el nmero divisor 1010 = A
xxxx:5009 MOV DX,O Lleva a cero el registro DX para no afectar cada divisin de nros de 16 bits DETALl
xxxx:500C DIV BX Divide AX por BX; el resultado queda en AX y el resto en DX Habiendo
xxxx:500E PUSH DX Guarda en la pila el resto de cada divisin (dgito BCD) a ver ms
xxxx:500F INeCX Incrementa el contador de divisiones efectuadas (dgitos del nro hallados)
xxxx:5010 eMP AX,O Compara AX con cero para determinar si es la ltima divisin l. Se
xxxx:5013 JNZ 5009 Si no es cero volver a 5009 . sale
do
xxxx:5015 POPDX Toma un resto desde la pila (dgito del nmero a visualizar) le !!
xxxx:5016 MOV AH,6 Hace AH=6 para que INT 21 muestre en pantalla el dgito que est en DL
2. En
xxxx:5018 ADD DL,30 Suma 30 a DL para que el dgito BCD est en ASCII, como requiere INT 21
xxxx:500B INT 21 Interrupcin por software para sacar en pantalla el dgito que est en DL una
xxxx:500D DEe ex Decrementa CX pues ya se visualiz un dgito decimal 3. Co
xxxx:500E JNZ 5015 Si no es cero ir a 5015, pues hay ms dgitos decimales del nro a visualizar inst
ejet<
xxxx:5020 MOV AH,6 Hace AH=6 para que INT 21 entre en pantalla el ASCII que est en DL Si
xxxx:5022 MOV DL, OD Hace DL=OD (cdigo ASCII de Enter) para comenzar otro rengln
Ene
xxxx:5024 INT 21 Interrupcin por software para que en pantalla tenga lugar un Enter
xxxx:5026 MOV DL,OA Hace DL=OA (cdigo ASCII de LF que sigue a Enter para saltar de rengln no<!
xxxx:5028 INT 21 Interrupcin por software para que en pantalla tenga lugar LF (line feed) rRg
xxxx:502A POPDX Restaura DX desde la pila 4. .fu_
xxxx:502B POPeX Restaura CX desde la pila ~
xxxx:502C POPBX Restaura BX desde la pila ac~
xxxx:502D RET Retorna al programa para tomar otro nmero a ser visualizado en otro rengln 5. El
de re
INTERRUPCIONES POR HARDWARE ~
'
6. La l.
Mientras que las interrupciones por software INTxx son instrucciones que forman parte de un PGM y ~ desp
programador las ubica en puntos del programa que l decide, para solicitar servicios del SO (como ser el
1
manejo de archivos, impresiones, etc.) , las interrupciones por hardware no se programan, pues por lo general 7.
no tienen mucho que ver con un programa en ejecucin.
Pueden ocurrir o no mientras se ejecuta una instruccin del mismo, y suceden de manera inesperada. 8.
prog
Durante la ejecucin de cada instruccin de un PGM puede suceder un evento en el que el hardware necesita
que se interrumpa el PGM que se est ejecutando, y que la UCP pase a ejecutar una SR del BIOS o del SO
Este tipo e
que atiende ese tipo de evento, luego de lo cual se reanuda la ejecucin del PGM interrumpido. Por ejemplo:
a una inre
- en la placa madre hay una circuitera que a fracciones fijas de segundo solicita interrumpir el PGM que se
tiene que
est ejecutando para que se ejecute una SR del BIOS que actualiza la hora del reloj que est en pantalla.
De ser neo
- cada vez que se pulsa una tecla del teclado, se solicita interrumpir y se pase a ejecutar una SR del BIOS.
empezar c:i
- cuando otro PGMx distinto al PGM que se est ejecutando solicit antes mediante una INTxx la escritura de
un sector de un disco, quedando as autointerrumpido a la espera de que la UCP reanude su ejecucin; una Interrupc:
vez que esa escritura se lleve a cabo una seal del hardware indicar que ello ocurri, solicitando que se de su pat
activaci
1 interrupci<
En el DOS las funciones se pedan con INTxx. Desde Windows 95 la mayor parte de las funciones del sistema estn en la librera
"Kernei32.DLL" que importan casi todos los programas. DLL son siglas de Dynamic Link Library (Bibliteca de Vnculos Dinmicos).
Es un archivo ejecutable que permite compartir cdigo y otros recursos para realizar ciertas tareas y funciones bsicas que un PGM
puede tomar. La DLL se carga en memoria y se usa una sola copia para todos los programas que soliciten servicios de ella.
:sde Cero M,Ginzburg- Assembler desde Cero U3-81
interrumpa el PGM en ejecucin para que una SR del BIOS verifique si dicha escritura fue exitosa.
Se comprende que tales eventos pueden suceder en cualquier momento impredecible, y que no se puede reali-
zar un PGM que adems de su cometido, contemple si ocurri una seal que avisa que hay que actualizar la
hora, o que un PGM est pensado para el caso que otro PGM est esperando por el fin de una escritura, etc.
Los eventos anteriores se originan en perifricos y dispositivos externos a la UCP que necesitan atencin, por
lo que el tipo de interrupciones que generan son las interrupciones por hardware externas enmascarables.
Tambin en la UCP hay situaciones de error al intentar ejecutar una instruccin de un PGM, como ser:
- cuando la instruccin tiene un codigo inexistente, u ordena hacer una divisin por un nmero muy pequeo
y el resultado no entra en el formato establecido (divisin por cero).
- si la instruccin no est permitida en modo usuario
- si la direccin de algn operando corresponde a una zona prohibida o se intenta violar algn permiso de uso
Estos eventos constituyen las "interrupciones por hardware internas" o "excepciones", y dan lugar a que
la SR del SO llamada aborte la instruccin y en general el PGM que se est ejecutando.
EJER(
Dado
AX=
l. a
l. b IP
[
IP
!.e Dd
SS: SP =
llij
2. a es
2.b
[
ti:.
...J
<C
2.c
:::>
8
3.a
[ p
oa:
1- 3.b
ffi
a:
<C
4. Si ai
8 Indicar
4.a Me
~~~ ~~~
te&
~
a: ~a: 4.b C:
UJ UJ
4.c Cu:
1- 1- cali
~ ~
4.d I
4.e Cl
4.f Si e
e 4.a To
o o
o o comell.Zi!
a:
UJ
u.. UJa:u.. Los mo
a:
UJ
a:w SP f-
c.. a.. [SP] f-
Figura 3.50 SP f-
[SP] f- C
i:Sde Cero M,Ginzburg- Assembler desde Cero U3-83
l.a Las componentes son CS :IP = 3A88:2004 , y en el bus aparecer 3A880 + 2004 = 3C884
l.b IP = IP + 3 = 2004 + ~ = 2007 (IP apunta brevemente a la instruccin In+l que sigue a CALL (que ocupa~ bytes)
SP f- SP - 2 (SP = FFEA- 2 = FFE8). O sea que la nueva cima de la pila est en FFE8.
[SP] f- IP [FFE8/9] = 2007 En las direcciones FFE8/9 de la pila se guard el valor de IP.
IP f- 3500 IP = 3500 apunta a la direccin 3500 donde comienza la subrutina
l.c Del paso anterior resulta:
SS:SP = 3A88:FFE8 07 (IP)
FFE9 20 (IP)
2. Si la subrutina empieza con PUSHF (Push flags) y sigue con PUSH AX (ver esquema final) , indicar:
2.a Mediante las componentes XXXX : YYYY, dnde comienza PUSHF
i+H
2.b Qu movimientos ocurren durant.: la ejecucin de PUSH F y con qu valores quedan los registros involucrhdos.
2.c Cmo queda la pila luego de la ejecucin de PUSHF.
_a:-(.)
2.a CS:IP = 3A88:3500
2.b SP f- SP - 2 (SP = FFE8- 2 = FFE6) La nueva cima de la pila est en FFE6.
@) [SP] f- RE [FFE617] = 2900
En las direcciones FFE617 de la pila se guard el valor de RE que contiene los valores de los flags.
2.c SS:SP = 3A88:FFE6 00 (RE)
FFE7 29 (RE)
FFE8 07 (IP)
FFE9 20 (IP)
3.a Qu movimientos ocurren durant.: la ejecucin de PUSH AX y con qu valores quedan los registros involucrados.
3.b Cmo queda la pila luego de la ejecucin de PUSHF.
3.a SP f- SP- 2 (SP = FFE6- 2 = FFE4) La nueva cima de la pila est en FFE4
[SP] f-AX [FFE4/5] = 3325 En las direcciones FFE4/5 de la pila se guard el valor de AX
3.b SS:SP = 3A88:FFE4 25 (AX)
FFE5 33 (AX)
FFE6 00 (RE)
FFE7 29 (RE)
FFE8 07 (IP)
FFE9 20 (1P)
4. Si a PUSH AX sigue la instruccin INT 21 , cuyo vector interrupcin contiene las componentes CS = 8942 e IP=3320.
Indicar:
4.a Mediante las componentes XXXX:YYYY, dnde comienza INT21, y qu movimientos durante su ejecucin permi-
ten escribir la pila.
4.b Cmo queda la pila luego de los movimientos de la ejecucin de INT 21 que permitieron escribirla
4.c Cules son las acciones que fa ltan realizar para concluir con la ejecucin de INT 21 en relacin con el flag 1 y la lo-
calizacin de la subrutina del SO que atiende a INT21.
4.d Con qu instruccin termina esta subrutina, y qu movimientos ocurren durante su ejecucin
4.e Cmo queda la pila cuando finali za la ejecucin de esta subrutina del SO
4.f Si este tipo de interrupciones se puede enmascarar
4.a Todas las instrucciones PUS H e INTxx ocupan 2 bytes en memoria (ver esquema final). Puesto que PUSHF
D
comenzaba en CS:IP = 3A88:3500, PUSH AX comenzar en 3A88:3502 e INT 21 comenzar en 3A88:3504.
Los movimientos que ocurren durante la ejecucin de INT21 para apilar son los siguientes :
SP f- SP-2 (SP = FFE4- 2 = FFE2) La nueva cima de la pila est en FFE2 .
[SP] f- RE [FFE2/3] = 0029 (Como hasta ahora la UAL no hizo ninguna operacin, el valor de RE se mantiene)
SP f- SP- 2 (SP = FFE2- 2 = FFEO) La nueva cima de la pila est en FFEO.
[SPJ f-es [FFE0/1] = 3A88
U3-84 M.Ginzburg- Assembler desde Cero M,Ginzl
------------- ---
e Cero M,Ginzburg- Assembler desde Cero U3-85
IP ~ [SP] (IP = 2407) La prxima instruccin a ejecutar es In+! que sigue a CALL 3500
SP~ SP + 2 (SP = FFE8 + 2 = FFEA) La nueva cima est en FFEA desde donde comenz este ejercicio
7. Si en lugar de INT21 durante la ejecucin de POP AX se activa una linea IRQxx siendo la direccin de su vector
interrupcin 0000:0032 , y el contenido de ste 255B 3429, qu cambios ocurririan en relacion con el punto 4.
En este caso, como no existe la-instruccin INT21, en su direccion (3 504) existir otra instruccin cualquiera Ix. Luego
T2 1, du- de la instruccin POP AX la subrutina quedar interrumpida, y se pasar a ejecutar otra subrutina del SO, que finalizar
_iJitando con IRET al igual que la llamada por INT21.
D1T 21. Ahora en la cima de la pila slo se modificar el valor del IP que en lugar de ser 3506 sera 3504:
:mas que SS:SP = 3A88: FFDE 04 (IP)
FFDF 35 (IP)
-es 0000
FFEO 88 (CS)
vector
FFEJ 3A (CS)
FFE2 00 (RE)
FFE3 29 (RE)
FFE4 25 (AX)
FFE5 33 (AX)
FFE6 00 (RE)
FFE7 29. (RE)
FFE8 07 (IP)
in con
FFE9 20 (IP)
Igualmente como en INT21, el registro RE va a cambiar durante la ejecucin, pues ahora el flag 1 que forma parte del
mismo debe cambiar de 1 al O, deshabilitando (enmascarando) cualquier otra interrupcin por hardware ocurra mientras
se ejecuta la subrutina del SO que atiende a IRQxx. Asimismo, por ser flag 1 =O la CPU est en modo "kernell".
A los efectos de localizar la subrutina que atiende a IRQxx,de acuerdo con los datos del ejercicio, en la zona de vectores
:a la pila) se tendr:
0000:0032 20 (IP)
_l. 0000:0033 34 (IP)
!Jardware 0000:0034 5B (CS)
0000:0035 25 (CS)
Entonces CS:IP = 255B: 3420 es la direccin dnde empieza la subrutina del SO que atiende a INTxx.
El resto es semejante a lo tratado para INT21.
::trata de
COMPLEMENTO
MANEJO DEL PORT PARALELO (De un trabajo dellng. Rubn Lpez)
Cuando se arranca una PC, el BIOS barre las direcciones de los puertos enun determinado orden, el primer dispositivo
encontrado recibe la denominacin (denominada lgica) LPTI y as sucesivamente, guardando los valores asignados en
una lista de dispositivos que corresponder a la implementacin particular del hardware de la PC y del BIOS en cuestin,
no habiendo una garanta cierta de que dicho nombre lgico en distintas mquinas pueda corresponder a la misma
direccin fisica.
La secuencia tpica con que los dispositivos fisicos son detectados corresponde a la secuencia de direcciones hexa 3B8,
;o 2.c 378 y 278, recibiendo la denominacin lgica LPTl, LPT2 y LPT3 respectivamente, si bien tambin es muy comn que
para el mismo orden de barrido se asignen los nombres LPT3, LPTI y LPT2.
Esto nos plantea la necesidad de verificar en cada mquina, cul es la direccin fisica del puerto lgico que se desee
;o l.c utilizar. ya que desde assembler siempre accederemos a l no por su denominacin lgica sino por su direccin fisica.
Tambin es conveniente recordar que los di spositivos lgicos LPTI y LPT2, en su configuracin estndar, estn asocia-
dos a IRQ 5 e IRQ 7 respectivamente: pero estos valores pueden haber sido modificados mediante "Jumpers" configura-
e sigue bles en la placa del port. o mediante el Setup de configuracin de la PC para los ports implementados "on board".
U3-86 M.Ginzburg- Assembler desde Cero M,Gin
1) Direccin del port de datos de la interfaz "Port Paralelo" considerada como direccin base Pero 1
Una interfaz "Port Paralelo", como se estudi (Unidad 1), se encuentra conformada a su vez por tres registros o ports, cuan di
cada uno de los cuales tiene su propia direccin fsica, la cual se determina a partir de la direccin perteneciente al port de escnl
datos (tambin llamada "direccin base" o "base"). A continuacin se describen las caractersticas ms importantes de proble
cada uno de estos registros y su direccin: lectun
Port de datos: Se trata de un registro de slo salida correspondiente a las 8 lneas de datos, cuya direccin Base segn lo Para 1
expresado podr ser 3B8, 378 278. di reco
Port de status: Es un registro de slo entrada utilizado para las 5 lneas de estado (Status), cuya direccin se calcula la illSII
como Base+ 1 por 01
Port de control: Registro de tipo bidireccional utilizado para el manejo de 4 lneas de CONTROL, su direccin se efectn
obtiene como Base+ 2
Si por ejemplo el port LPTI se encuentra en la direccin 278, resulta que el port de datos tiene la direccin fsica 278h, el
port de status le corresponde la direccin 279h y el port de control se encontrar en 27 Ah.
2) Consideraciones acerca del Port de Datos:
Es muy importante tener en cuenta para el manejo del port de datos, las siguientes consideraciones:
- Si se escribe en el port de datos. la escritura se realiza en dicho registro, que guarda el valor enviado, permitiendo a
la CPU proseguir con otra tarea.
- Si se realiza una lectura del port de datos, se lee el valor de las lneas DO a D7 . correspondientes al ltimo valor
enviado al port de Datos.
3) Disposicin (PinOut) de contactos ("pines") del conector DB25 en relacin con los registros ports de la interfaz
"Port Paralelo"
La siguiente tabla describe la correspondencia que existe entre el conector DB25 y cada bit de los registros que
componen la interfaz "Port Paralelo"
Ejemplo: El siguiente programa realiza el encendido de los ocho leds en forma sucesiva, de a uno por vez, mediante un
barrido desde el bit de menor peso hacia el bit de mayor peso; concluido el barrido el programa se detiene.
MOV DX, 378 carga direccin port de datos en DX
MOV AL, 1 carga 00000001 para encender el diodo extremo
conectado al pin 2 del conector DB25
UNO OUT DX, AL escribe el dato en el port
CDEM MOV AH, 20 se prepara para repetir 20h veces la demora que
sigue, para hacer visible el encendido delled
MOV BX, FFFF inicializa contador de demora con FFFF = 65.535
DEM JMP SGTE vaca la colad~ instrucciones del pipeline de la UCP .
SGTE DEC BX decrementa el contador BX
JNZ DEM repite ncleo rutina de demora hasta que BX=O
DEC AH
JNZ CDEM repite rutina de demora hasta que AH= O
PUSH Primero ordena decrementar en dos al SP, y luego salva 2 bytes (que tpicamente estaban en un
registro) en la cima de la pila. Ejemplificada en el ejercicio 46
PUSHF Instruccin ejemplificada en el ejercicio 46
RCL Ordena la rotacin a izquierda dibujada un cierto nmero de veces, en la que se incluye al
flag C (comparar con ROL) C <-- MSB LSB
.1- t
Ejemplos: RCL BX, 1 MOVCL,4
RCLBX, CL
RCR Ordena la rotacin a derecha dibujada, en la que incluye al flag C (comparar con ROR) C --7 MSB--7
C --7 MSB LSB
t ~
REPZ =REPE
Ordena repetir una instruccin para stringsd hasta que se de una cierta condicin. A menudo usada con CMPS, para comparar dos
cadenas hasta que CX =O hasta que los elementos del string no sean iguales.
Ej: REPE CMPSB compara bytes de cadenas hasta el fin de la cadena, o hasta que bytes de las cadenas no sean iguales
RET Ordena saltar a la instruccin que sigue a la ltima CALL ejecutada. Instruccin ejemplificada en el ejercicio 46
ROL (Rotate Left) ejemplificada en el ejercicio 38.
Ordena la rotacin a izquierda dibuja, un nmero de veces
C <-- MSB ~------LSB
.1- t
ROR (Rotate Right)
Ordena la rotacin a derecha dibujada, un cierto nmero de veces
MSB LSB ~C
t _ _ _ _ _ _.L
SHL=SAL (Shift Left)
C <-- MSB LSB <-- O
Como indica el dibujo, ordena desplazar hacia la izquierda cada bit del operando un cierto nmero de posiciones (indicado por CL 1).
Conforme un bit es desplazado de la posicin menos significativa (LSB), un cero es puesto en dicha posicin, a la par que el valor del bit
que est en la posicin ms significativa (MSB) es puesto como valor del flag C. En el caso de varios desplazamientos sucesivos, el flag
C toma el valor del bit ms recientemente desplazado desde la posicin ms significativa.
Esta operacin puede usarse para multiplicar un nmero natural por dos, o una potencia de dos.
SAR
MSB ~ MSB ------~ LSB~C
Esta instruccin puede usarse para dividir un nmero signado por dos, o una potencia de dos, dado que el MSB es copiado nuevamente
como MSB, conforme el que era bit de signo es desplazado a la derecha.
SBB (Substract with borrow). Como ADC, pero para la resta.
SCASB (Sean a String Byte)
Ordena comparar un byte en AL con un byte de un string apuntado por DI en ES. Si flag D=O entonces DI ser
incrementado luego de SCASB; y si D=l entonces DI puede ser decrementado luego de SCASB
SCASW (Sean a String Word)
Ordena comparar AX con 2 bytes consecutivos de un string apuntados por DI en ES. El flag D puede usarse para
incrementar o decrementar DI en dos.
SHR Instruccin ejemplificada en el ejercicio 34, para nmeros naturales.
STC (Set Carry flag): ordena hacer C=l
STD (Set Direction flag) : ordena hacer 1 el flag D, de direccin.
STI (Set Interrupt flag):
Ordena hacer 1 el t1ag I, para habilitar las interrupciones por hardware enmascarables.
STOSB (Store Byte in String)
Ordena almacenar una copia de un byte desde AL en una locacin apuntada por DI en el ES, reemplazando un byte de un
string. Luego DI puede ser automticamente incrementado o decrementado segn que el flag D valga O 1, respectivamente
STOSW (Store Word in String)
Ordena almacenar una copia de AX en dos bytes sucesivos apuntados por DI en el ES, reemplazando 2 bytes de un string.
DI puede autoincrementarse o decrementarse en 2 mediante el flag D.
SUB Ordena restar dos operandos. Instruccin ejemplificada en el ejercicio 1
TEST Realiza una operacin AND para activar los flags, sin asignar resultados. Semejante CMP respecto de SUB.
WAIT Ordena que el procesador pase al estado IDLE, en el cual no procesa hasta que se active la entrada de interrup-
cin INTR o NMI, o hasta que la eritrada TEST resulte baja. Se usa para sincronizar al procesador con hardware exterior.
XCHG (Exchange source and destination) Ordena intercambiar el contenido de un registro con el otro, o el contenido
de un registro con contenidos de locaciones de memoria. Usada en el ejercicio 34
XLATB (Translate Byte in AL) Translada un byte de un cdigo a otro cdigo. Reemplaza un byte en AL con un byte
punteado por BX, en una tabla de memoria
XOR Ordena realizar la operacin X-OR entre cada bit de un operando fuente con cada bit del operando destino, y el
resultado colocarlo en el destino. Si se hace XOR AX, AX, el registro AX se pone en cero.
1
Si el nmero de desplazamiento es uno, ello puede especificarse colocando un uno a la derecha de la coma en la instruccin.
INTRODUCCION GENERAL A LA INFORMATICA
Unidad 3
Assembler
desde cero Principiante
+ Interrupciones Medio
Avanzado
INFORMACION PARA EL LECTOR
Todos los
niveles
ISBN 978-987-05-9704-9
9 789870 59704