LA INSTRUCCIÓN LEA
La instrucción LEA es útil para inicializar un registro con una dirección de desplazamiento. De hecho, un nombre más descriptivo para esta instrucción sería "Load Offset Address, carga una dirección de desplazamiento". El formato general para LEA es
[etiqueta:] L E A { r e g i s t r o / m e m o r i a }
Un uso común de LEA es para inicializar un desplazamiento en el registro BX, DI o SI para indexar una dirección de memoria. Haremos mucho de esto a lo largo de este libro. Aquí está un ejemplo: D A T A B L K D B S A V B Y T E D B 2 0 D 0 P (?) L E A BX, D A T A B L K ,-Carga la d i r e c c i ó n del d e s p l a z a m i e n t o M O V S A V B Y T E , [BX] /Mueve el p r i m e r b y t e de D A T A B L K
Una operación equivalente a LEA o MOV con desplazamiento, se codifica así:
M O V BX, O F F S E T D A T A B L K /Carga la d i r e c c i ó n del d e s p l a z a m i e n t o
LAS INSTRUCCIONES INC Y DEC
INC y DEC son instrucciones adecuadas para aumentar y disminuir en 1 los contenidos de regis- tros y localidades de memoria. El formato general para INC y DEC es
[etiqueta:] I N C / D E C { r e g i s t r o / m e m o r i a }
Note que esas instrucciones sólo necesitan de un operando. Dependiendo del resultado, la opera- ción apaga o prende las banderas O F , SF y Z F , a las que las instrucciones de salto condicional pueden verificar para menos, cero o más.
INSTRUCCIONES DE MOVIMIENTO EXTENDIDO
Los programas anteriores movieron datos inmediatos a un registro, movieron datos de una locali- dad de memoria definida a un registro, movieron contenidos de registros a memoria y movieron el contenido de un registro a otro. En todos los casos, la longitud de los datos estaba limitada a uno o dos bytes y ninguna operación movió datos de un área de memoria directamente a otra área de memoria. Esta sección explica cómo mover datos que exceden los dos bytes. Otro método, el uso de instrucciones de cadenas de caracteres, es estudiado en el capítulo 12.
En el programa de la figura 6-2, el segmento de datos contiene dos campos de nueve bytes definidos como N A M E 1 y N A M E 2 . El objetivo del programa es mover el contenido de NAME1 a N A M E 2 :
1 0 0 I n s t r u c c i o n e s y d i r e c c i o n a m i e n t o d e l p r o c e s a d o r Capítulo 6 p a g e 6 0 , 1 3 2 T I T L E P 0 6 M O V E ( E X E ) O p e r a c i o n e s d e m o v i m i e n t o e x t e n d i d o s . M O D E L S M A L L . S T A C K 6 4 . D A T A N A M E 1 D B ' A B C D E F G H I ' Ñ A M E 2 D B ' J K L M N O P Q R ' . C O D E B E G I N P R O C F A R M O V A X , ® d a t a I n i c i a r e g i s t r o s M O V D S , A X d e s e g m e n t o M O V E S , A X M O V C X , 0 9 I n i c i a c i ó n p a r a m o v e r 9 c a r a c t e r e s L E A S I , N A M E l I n i c i a c i ó n d e d i r e c c i o n e s p a r a N A M E 1 L E A D I , N A M E 2 Y Ñ A M E 2 B 2 0 : M O V A L , [ S I ] O b t e n e r c a r á c t e r d e N A M E 1 , M O V [DI] , A L M o v e r l o a Ñ A M E 2 INC SI I n c r e m e n t a r s i g u i e n t e c a r á c t e r e n N A M E 1 INC DI I n c r e m e n t a r , a s i g u i e n t e p o s i c i ó n , e n N A M E 2 D E C CX D e c r e m e n t a r c o n t a d o r d e i t e r a c i o n e s J N Z B 2 0 ¿ C o n t a d o r d i f e r e n t e d e c e r o ? S i , i t e r a r M O V A X , 4 C 0 0 H • S a l i d a a D O S INT 2 1 H B E G I N E N D P E N D B E G I N
Figura 6-2 Operaciones de movimiento extendido
N A M E l : A B C D E F G H I I I I I I I I I I N A M E 2 : J K L M N O P Q R
Ya que cada uno de los campos es de nueve bytes, se necesita más de una instrucción MOV. El programa contiene varias características nuevas.
A fin de pasar N A M E l a NAME2, la rutina inicializa el registro CX a 9 (la longitud de los dos campos) y utiliza los registros índice SI y DI. Dos instrucciones LEA cargan las direcciones de desplazamiento de N A M E l y N A M E 2 en SI y DI como sigue:
L E A S I , N A M E l ; C a r g a d e s p l a z a m i e n t o s L E A D I , N A M E 2 ; d e N A M E l y Ñ A M E 2
El programa utiliza las direcciones de los registros SI y DI para mover el primer byte de N A M E l al primer byte de N A M E 2 . Los corchetes alrededor de SI y DI en los operandos de MOV signi- fican que la instrucción es para usar el desplazamiento en el registro dado, a fin de accesar la localidad de memoria. Así
M O V A L , [SI]
significa "Utilice el desplazamiento en SI ( N A M E l + 0 ) para mover el byte referenciado al regis- tro A L " . Y la instrucción
Alineación de direcciones
101
M O V [DI] , A L
significa "Mueva el contenido de AL al desplazamiento referenciado por D I ( N A M E 2 + 0 ) " . El programa tiene que repetir estas dos instrucciones MOV nueve veces, una vez para cada carácter en los campos respectivos. Para este fin, utiliza una instrucción que aún no hemos explicado: JNE (Salta si no es igual).
Dos instrucciones INC incrementan los registros SI y DI en 1, _y DEC decrementa el CX en 1. DEC también pone a 1 o a 0 la bandera de cero (ZF), dependiendo del resultado en CX; si el contenido no es cero, aún existen caracteres por mover, y JNE regresa a la etiqueta B20 para repetir las instrucciones M O V E . Y como el SI y DI han sido incrementados en 1, el siguiente MOV hace referencia a NAME1 +1 y N A M E 2 + 1 . El ciclo continúa de esta manera hasta que ha movido nueve caracteres en total, hasta mover NAME1 + 8 a NAME2 + 8.
(Tal vez quiera teclear este programa, ensamblarlo y enlazarlo y utilizar DEBUG para rastrearlo. Observe el resultado en los registros, el apuntador de instrucción y la pila. Utilice D DS:0 para ver los cambios en NAME2.)
L A I N S T R U C C I Ó N I N T
En ejecución, una instrucción INT interrumpe el procesamiento y accesa la tabla de servicios de interrupción en memoria baja para determinar la dirección de la rutina solicitada. Después, la operación transfiere al DOS o al BIOS para una acción especificada y regresa a su programa para continuar el procesamiento. Con más frecuencia, una interrupción tiene que realizar los pasos complejos de una operación de entrada o salida. Las interrupciones necesitan de un camino que facilite la salida de un programa y, tras una terminación exitosa, el regreso al programa. Para este objetivo, INT realiza lo siguiente:
• Decrementa en 2 el apuntador de la pila y mete en la pila el contenido del registro de banderas.
• Limpia (pone a 0) las banderas de interrupción y de trampa (IF y TF). • Decrementa en 2 el apuntador de la pila y mete en la pila el registro CS.
• Decrementa en 2 el apuntador de la pila y mete en la pila el apuntador de instrucción. • Hace que la operación solicitada sea realizada.
Para regresar de una interrupción, la rutina emite un IRET (regreso de interrupción), el cual saca los registros de la pila y regresa a la instrucción inmediata posterior al INT en su programa. Ya que el proceso anterior es automático por completo, sus únicas preocupaciones son definir una pila suficientemente grande, para las operaciones necesarias de agregar y remover información de ella y utilizar las operaciones INT adecuadas. A partir del capítulo 9, haremos uso considerable de la instrucción INT.
A L I N E A C I Ó N D E D I R E C C I O N E S
Como el 8086 y el 80286 tienen un bus de datos de 16 bits (una palabra), ejecutan (trabajan) más rápido si accesan palabras que empiezan en una dirección (palabra) con número par. Considere una situación en la que los desplazamientos 0012H y 0013H contienen la palabra 63 A7H. El
1 0 2 I n s t r u c c i o n e s y d i r e c c i o n a m i e n t o d e l p r o c e s a d o r Capítulo 6
procesador puede accesar la palabra completa en el desplazamiento 0012H de forma directa a un registro. Pero la palabra pudo empezar en una dirección con número impar, tal como 0013H:
Contenido de memoria: Desplazamiento: XX 63 A7 XX I 0012 1 0014 0013 0015
En este caso, el procesador tiene que realizar dos accesos. Primero, accesa los bytes en 0012H y 0013H y envía el byte de 0013H (63) al registro A L . Después accesa los bytes en 0014H y 0015H y envía el byte de 0014H (A7) al registro AH. Ahora el AX contiene A763H.
Usted no tiene que realizar ninguna programación especial para localidades pares o impares, ni tiene que saber si una dirección es par o impar. La operación de acceso invierte de forma automática una palabra de memoria en un registro, de manera que retome su orden correcto.
El 80386 y procesadores posteriores tienen un bus de datos de 32 bits. De acuerdo con esto, se prefiere la alineación de elementos referenciados en direcciones que sean divisibles entre cuatro (una dirección de palabra doble). (Técnicamente, los procesadores 486 y Pentium prefieren ali- neación en un límite de 16 bytes [párrafo].)
El lenguaje ensamblador tiene una directiva ALIGN que se puede usar para alinear elemen- tos en límites. Por ejemplo, ALIGN 2 alinea en un límite de palabra y ALIGN 4 alinea en un límite de palabra doble. También, como el inicio del segmento de datos siempre está en un límite de párrafo, podría organizar sus primeros datos con valores de palabras dobles, después con valores de palabra y por último con valores de byte. Sin embargo, el 80386 y procesadores posteriores ejecutan a velocidad tan rápida que usted probablemente nunca notará los efectos de forzar el alineamiento.