Está en la página 1de 55

UNIDAD 3-MODOS DE DIRECCIONAMIENTO

Objetivo:
- Cubrir las tres clases de modos de direccionamiento que tienen los Microprocesadores de Intel.
La primera clase es el modo de direccionamiento de datos. En esta explicacin se usar la instruccin MOV (mueve datos), la cual permite transferir datos del tipo byte o palabra entre dos registros o entre registros y memoria en el 8086 al 80286 y mover bytes, palabras o palabras dobles en el 80386 y posteriores. La segunda clase es el modo de direccionamiento de memoria de programa. Para explicar este modo se usarn las instrucciones CALL y JUMP, las cuales permiten modificar el flujo de un programa. La tercera clase es el modo de direccionamiento de memoria de stack, para el cual se usarn como base en la explicacin las instrucciones de PUSH y POP.

3.1 Modos de direccionamiento de datos


Por su flexibilidad, una de las instrucciones ms comnmente usadas en los programas es la instruccin MOV, es por esto que proporciona una buena base para la explicacin de los modos de direccionamiento de datos. En la Figura 3-1 se muestra la instruccin MOV y define la direccin del flujo de datos. La fuente es el operando que est a la derecha y el destino es el operando que est a izquierda despus del mnemnico MOV. Esta direccin de flujo se aplica a todas las instrucciones. La coma en una instruccin separa al destino de la fuente. Solo se permiten las transferencias de memoria a memoria con la instruccin MOVS.

Figura 3-1 Instruccin con fuente, destino y direccin de flujo de datos

En la instruccin MOV AX,BX de la Figura 3-1 la palabra contenida en el registro fuente (BX) es transferida al registro destino (AX). La fuente nunca cambia. El registro de banderas no se afecta por la mayora de instrucciones de transferencia de datos. Tanto la fuente como el destino se denominan operandos.

En la Figura 3-2 se muestran todas las variaciones del modo de direccionamiento de datos que usan la instruccin MOV. Esas variaciones se explicarn a continuacin.

Figura 32 Modos de direccionamiento de datos en el 8086 al Core2

3.1.1 Direccionamiento por o de registro


Direccionamiento por registro transfiere una copia de un byte o palabra de un registro fuente o de una localidad de memoria a un registro destino o localidad de memoria. Por ejemplo, la instruccin MOV CX,DX copia la palabra del registro DX al registro CX. En el 80386 se puede transferir una palabra doble. Por ejemplo, la instruccin MOV ECX,EDX copia una palabra doble del registro EDX al registro ECX. En el Pentium 4 trabajando en modo de 64 bits, se puede usar cualquier registro de 64 bits. Por ejemplo, la instruccin MOV RDX,RCX transfiere una copia de una palabra cudruple (quadword) de RCX a RDX. Este modo de direccionamiento es la forma ms comn de direccionar datos una vez que se han aprendido los nombres de registros y es el ms fcil de aplicar. En este modo de direccionamiento se pueden usar los registros: de 8 bits AH, AL, BH, BL, CH, CL, DH y DL; de 16 bits AX, BX, CX, DX, SP, BP, SI y DI; en el 80386 y posteriores los registros de 32 bits EAX, EBX, ECX, EDX, ESP, EBP, EDI y ESI; y en el Pentium 4 los registros RAX, RBX, RCX, RDX, RSP, RBP, RDI, RSI y R8 a R15. Algunas instrucciones MOV, PUSH y POP usan los registros de segmento CS, ES, DS, SS, FS, y GS). No se deben mezclar registros de 8 bits con registros de 16 o 32 bits o registros de 16 bits con registros de 32 bits lo cual no esta permitido y marcar error al ensamblar el programa. Tampoco mezclar registros de 64 bits con registros de otro tamao.

En la Tabla 3-1 se muestran algunas variaciones de movimiento de registros, ya que es prcticamente imposible mostrar todas las combinaciones que son muchas. Por ejemplo, solo el subconjunto de instrucciones MOV de 8 bits tiene 64 variaciones. No est permitida la instruccin MOV segmento-a-segmento. Normalmente no se cambia el contendido del registro CS con una instruccin MOV ya que la direccin de la siguiente instruccin sera impredecible.

Tabla 3-1 Ejemplos de instrucciones de direccionamiento por registro

En la Figura 33 se muestra la operacin de la instruccin MOV BX,CX. El contenido del registro fuente no cambia y s el contenido del registro destino. Esta instruccin copia 1234H de CX a BX, borrando el contenido original (76AFH) de BX. El contenido del registro o localidad de memoria destino cambia para todas las instrucciones, excepto en las instrucciones CMP y TEST. Ntese que MOV BX,CX no afecta los 16 bits ms significativos del registro EBX.

Figura 33 Ejecucin de MOV BX, CX justo antes de que cambie BX. Solo los 16 bits de ms a la derecha de EBX cambian

El siguiente ejemplo muestra un segmento de programa o secuencia de instrucciones ensambladas que copian varios datos entre registros de 8, 16 y 32 bits. La ltima instruccin se ensambla sin error pero causa problemas al ejecutarla, ya que si se cambia solo el contenido de CS sin cambiar IP, el siguiente paso en el programa es desconocido y causa que el programa se pierda.

3.1.2 Direccionamiento inmediato


El direccionamiento inmediato transfiere una copia del dato inmediato a un registro o localidad de memoria. El dato fuente puede ser un byte o una palabra, y en el 80386 al Core2 una palabra doble (doubleword). Por ejemplo, la instruccin MOV AL,22H copia el byte 22H al registro AL. En el 80386 y posteriores se puede transferir un dato inmediato doubleword a un registro o localidad de memoria. Por ejemplo, la instruccin MOV EBX, 12345678H copia la palabra doble 12345678H en el registro de 32 bits EBX. Se llama inmediato porque despus del cdigo de operacin de la instruccin se especfica inmediatamente el dato. El dato es una constante ya que cuando se transfiere un dato de un registro o memoria es un dato variable. En la Figura 34 se muestra la operacin de la instruccin MOV EAX, 13456H. Esta instruccin copia 13456H en el registro EAX. El dato fuente sobre-escribe el dato destino.

Figura 3- 4 Operacin de MOV EAX, 3456H. Copia el dato inmediato (13456H) en EAX

En lenguaje ensamblador de algunos fabricantes se necesita que el smbolo # preceda a un dato inmediato, como por ejemplo en la instruccin MOV AX,#3456H. Los ensambladores ASM de Intel, MASM (MACRO assembler) de Microsoft y TASM (Turbo assembler) de Borland, que son de los ms comunes, no usan el smbolo # para datos inmediatos. El dato inmediato en la instruccin MOV puede ser una palabra o quadword de 64 bits cuando el Microprocesador opera en 64 bits.

El dato inmediato se puede indicar en varias formas. La H indica un dato hexadecimal. Si el dato hexadecimal inicia con una letra, el ensamblador requiere que el dato inicie con un 0. Por ejemplo, para representar el dato F2 en hexadecimal, en ensamblador debe usarse 0F2H. En algunos ensambladores (no en MASM y TASM), un dato hexadecimal se representa con una h, por ejemplo, la instruccin MOV AX,#h1234. Los datos decimales no requieren cdigos especiales o ajustes, por ejemplo, 100 decimal en la instruccin MOV AL,100. Un carcter o caracteres en cdigo ASCII pueden representarse encerrados entre comillas sencillas (apstrofes-), Por ejemplo, la instruccin MOV BH,A, mueve el cdigo ASCII de la letra A (41H) al registro BH. Para representar datos binarios se usa la letra B despus del dato inmediato. La Tabla 32 muestra algunos ejemplos de la instruccin MOV en los que se usan datos inmediatos.

Tabla 32 Ejemplos de direccionamiento inmediato usando la instruccin MOV

En el siguiente ejemplo se muestran varias instrucciones inmediatas que inicializan los registros de 16 bits AX, BX y CX con 0000H. A continuacin estn instrucciones que usan direccionamiento por registro para copiar el contenido de AX en los registros SI, DI y BP. Es un programa pequeo pero completo que usa un modelo de MASM para poder ensamblarse y ejecutarse. La declaracin o directiva .MODEL TINY (pequeo) le indica al ensamblador que ensamble el programa en un solo segmento de cdigo para que se pueda ejecutar como un programa de comando (.COM).

La declaracin .CODE indica el inicio del segmento de cdigo. La directiva .STARTUP indica el inicio del programa. La directiva .EXIT causa que el programa termine y salga al sistema operativo (DOS). Finalmente, la directiva END indica en fin del archivo del programa Este programa se puede ensamblar con MASM y ejecutarse con CodeView (CV) de Microsoft para ver su ejecucin. Las ltimas versiones de TASM aceptan programas de MASM sin cambio alguno. Para crear el programa fuente puede usarse el programa EDIT de DOS, NotePad de Windows o cualquier editor de texto.

Cada declaracin en programa en ensamblador tiene cuatro partes o campos como se muestra en la siguiente figura. El campo de ms a la izquierda se llama etiqueta (label) y se usa para asignar un nombre simblico a la localidad de memoria donde se almacena el cdigo de operacin de la instruccin. Todas las etiquetas deben iniciar con una letra o uno de los siguientes caracteres especiales: @, $, - o ?. Su longitud puede ser de 1 a 35 caracteres. El siguiente campo se llama campo del cdigo de operacin o mnemnico de la instruccin, por ejemplo, el mnemnico MOV. El siguiente es el campo del o de los operandos, el cual contiene informacin usada por el mnemnico. Por ejemplo, en la instruccin MOV AL,BL, los operandos son AL y BL. Las instrucciones tienen cero o hasta tres operandos. El ltimo campo es el campo de comentarios y siempre inicia con punto y coma (;).

Al ensamblar el programa se genera un archivo de listado con la extensin .LST que en el extremo izquierdo muestra nmeros hexadecimales que representan la direccin de offset y cdigos de operacin de las instrucciones o datos, son el cdigo de mquina o datos. Por ejemplo, en el penltimo ejemplo, para la instruccin MOV AX,0 el ensamblador la coloca en la localidad de memoria con offset de 0100H. Su cdigo hexadecimal es B8 0000H. El B8 es el cdigo de operacin de la instruccin y el 0000 es el valor cero del dato en 16 bits.

Algunos programas del tipo Visual permiten instrucciones en ensamblador. En el siguiente ejemplo se muestra una funcin que incluye el mismo cdigo de un programa en ensamblador. Esta funcin adiciona 20H a la variable temp.

3.1.3 Direccionamiento directo de datos


Direccionamiento directo mueve un byte o una palabra entre una localidad de memoria y un registro, esta instruccin no soporta la transferencia memoria-a-memoria, excepto con la instruccin MOVS. Por ejemplo, la instruccin MOV CX,LIST copia la palabra almacenada en la localidad de memoria LIST al registro CX. En el 80386 y posteriores se puede direccionar una localidad de memoria de tamao doble palabra. Por ejemplo, la instruccin MOV ESI,LIST copia un nmero de 32 bits almacenado en cuatro bytes consecutivos en memoria a partir de la localidad LIST al registro ESL. En este modo de direccionamiento hay dos formas bsicas: (1) direccionamiento directo y (2) direccionamiento con desplazamiento.

3.1.3.1 Direccionamiento directo Se aplica en una instruccin MOV para transferir datos entre una localidad de memoria y los registros AL (8 bits), AX (16 bits) o EAX (32 bits). La direccin se forma adicionando el desplazamiento a la direccin del segmento de datos usado por defecto o a la direccin del segmento de datos alterno.

Otro ejemplo es la instruccin MOV AL,DATA, la cual carga AL con el contenido de la localidad de memoria DATA (1234H) ubicada en el segmento de datos. DATA es un nombre simblico o etiqueta de una localidad de memoria y el 1234H es la direccin de esa localidad de memoria. Algunos ensambladores permiten que esta instruccin sea escrita de la siguiente forma: MOV AL,[1234H], donde [1234H] es la direccin de una localidad de memoria y algunos ensambladores necesitan que la instruccin anterior sea representada como MOV AL, DS:[1234H] para indicar que la localidad de memoria se encuentra en el segmento de datos.

En la Figura 35 se muestra cmo la instruccin MOV AL,[1234H] transfiere una copia del byte localizado en la direccin de memoria 1234H al registro AL. La direccin efectiva de la localidad de memoria se forma sumando 1234H (direccin de offset) y 10000H (direccin del segmento de datos multiplicada por 10H).

Figura 35 La instruccin MOV AL,[1234H] cuando DS=1000H

En la Tabla 33 se muestran algunas instrucciones que usan el direccionamiento directo. Ya que estas instrucciones se usan frecuentemente en muchos programas, Intel decidi hacerlas instrucciones especiales con un cdigo de mquina de 3 bytes. Para reducir el tamao de los programas. El cdigo de mquina de las otras instrucciones que mueven datos de una localidad de memoria a un registro, llamadas instrucciones de direccionamiento con desplazamiento, es de 4 o ms bytes.

Tabla 33 Instrucciones de direccionamiento directo usando EAX, AX y AL y RAX en modo de 64 bits

3.1.3.2 Direccionamiento con desplazamiento El direccionamiento con desplazamiento es casi idntico al direccionamiento directo, excepto que el cdigo de mquina de la instruccin es de 4 bytes en lugar de 3. En el 80386 y posteriores puede ser de hasta 7 bytes si el registro es de 32 bits y el desplazamiento es tambin de 32 bits. En la siguiente figura se muestra un ejemplo en el que se puede comparar la operacin de las instrucciones MOV AL,DS:[1234H] y MOV CL, DS:[1234H]. Ambas instrucciones realizan bsicamente la misma operacin, excepto que en la segunda el destino es CL en lugar de AL, lo cual trae como consecuencia que el cdigo de mquina de la primera sea de tres bytes y el de la segunda de 4 bytes. Aunque se puede usar cualquier segmento, en la mayora de los casos los datos se almacenan en el segmento de datos, por lo que se especifica DS: antes del [offset].

En la Tabla 34 se indican algunas instrucciones MOV que usan el modo de direccionamiento con desplazamiento. No se indican todas las variaciones de la instruccin MOV porque son muchas. Los registros de segmento pueden almacenarse en o cargarse desde memoria.

Tabla 34 Ejemplos de direccionamiento directo de datos usando desplazamiento

En el ejemplo siguiente se muestra un programa que accede informacin localizada en el segmento de datos. Ntese que la declaracin .DATA informa al ensamblador donde inicia el segmento de datos. El tamao del modelo se especifica como SMALL para poder incluir un segmento de datos. El modelo de tipo SMALL permite usar un segmento de datos y un segmento de cdigo. Se usa a menudo cuando el programa utiliza datos en memoria. Un programa del tipo SMALL es como un archivo de programa .EXE. Ntese tambin que el programa asigna localidades de memoria en el segmento de datos usando las directivas DB y DW. La declaracin .STARTUP no solo indica el inicio del cdigo, si no que tambin carga el registro de segmento de datos con la direccin del segmento de datos.

3.1.4. Direccionamiento indirecto


El direccionamiento Indirecto transfiere un byte o palabra entre un registro y una localidad de memoria direccionada por un registro ndice o un registro base. Los registros ndice y base son BP, BX, DI y SI. Por ejemplo, la instruccin MOV AX,[BX] copia el dato de una palabra de la localidad offset indexada por BX del segmento de datos al registro AX. En el 80386 y posteriores se transfiere un byte, una palabra o una palabra doble entre un registro y una localidad de memoria direccionada por EAX, EBX, ECX, EDX, EBP, EDI o ESI. Por ejemplo, la instruccin MOV AL,[ECX] carga AL de la direccin offset seleccionada por ECX en el segmento de datos. En otras palabras, este modo de direccionamiento permite transferir un dato localizado en una localidad de memoria direccionada por un offset contenido en los registros BP, BX, DI o SI. Por ejemplo, si el registro BX contiene 1000H, la instruccin MOV AX,[BX], copia la palabra almacenada en la direccin cuyo offset es 1000H en el segmento de datos al registro AX. Si el Microprocesador opera en modo real y DS=0100H, la instruccin direcciona la palabra almacenada en los bytes de memoria 2000H y 2001H y los transfiere al registro AX, como se muestra en la Figura 3-6.

Figura 36 La instruccin MOV AX,[BX] cuando BX=1000H y DS=0100H. Ntese que el contenido de la localidad 2000H se mueve a AL y el contenido de 2001H a AH. Los smbolos [ ] indican direccionamiento indirecto en lenguaje ensamblador.

En la Tabla 3-5 se muestran algunas instrucciones comnmente usadas que usan direccionamiento indirecto. Si se usan en un Pentium 4 o Core2 que trabaja en modo de 64 bits, se utiliza cualquier registro de 64 bits para contener la direccin de 64 bits.

Tabla 35 ejemplos de direccionamiento por registro indirecto

Por defecto se usa el segmento de datos con el direccionamiento indirecto o con cualquier otro modo de direccionamiento que use BX, DI o SI para direccionar memoria. Se usa por defecto el segmento de stack o pila si se utiliza el registro BP para direccionar memoria. Para el 80386 y posteriores se usa el segmento de stack por defecto con el registro EBP y el segmento de datos si se usan los registros EAX, EBX, ECX, EDX, EDI y ESI.

En algunos casos es necesario especificar el tamao del dato. Las directivas del ensamblador BYTE PTR, WORD PTR, DWORD PTR o QWORD PTR sirven para indicar el tamao del dato en memoria direccionado por un apuntador (PTR). Por ejemplo, la instruccin MOV AL, [DI], mueve un byte, pero la instruccin MOV [DI],10H, puede ser ambigua. Esta instruccin puede direccionar una localidad de memoria de un byte, de una palabra de una palabra doble o de una palabra cudruple. El ensamblador no puede determinar el tamao del operando destino. En cambio la instruccin MOV BYTE PTR [DI],10H indica claramente la localidad de memoria de un byte direccionada por DI. De manera similar, la instruccin MOV DWORD PTR [DI],10H indica tambin claramente el tamao doble palabra de la localidad de memoria. Las directivas BYTE PTR, WORD PTR, DWORD PTR y QWORD PTR solo se usan con instrucciones que direccionan una localidad de memoria por medio de un apuntador o registro ndice con dato inmediato y con otras pocas instrucciones que se cubrirn ms adelante.

Por ejemplo, supngase que se necesite crear una tabla con 50 elementos tomados a partir de la localidad de memoria 0000:046C. La localidad 0000:046C almacena un contador del sistema operativo DOS actualizado por el reloj de tiempo real de una computadora personal. En la Figura 3-7 se muestra la tabla y el registro BX usado para acceder secuencialmente cada localidad de la tabla. Para realizar esta tarea, se carga en el registro BX la direccin de inicio de la tabla usando una instruccin MOV inmediata. A continuacin se puede usar el direccionamiento indirecto para almacenar los 50 elementos secuencialmente como se mostrar en el ejemplo siguiente.

Figura 37 Un arreglo (TABLE) que contiene 50 bytes direccionado indirectamente por el registro BX

A continuacin, se muestra un programa donde se carga el registro BX con la direccin de inicio de la tabla e inicializa un contador, localizado en CX, con 50. La directiva OFFSET le indica al ensamblador que cargue BX con la direccin de offset de la localidad de memoria DATAS, no con el contenido de DATAS. Por ejemplo, la instruccin MOV BX,DATAS copia el contenido de la localidad de memoria DATAS en BX, mientras que la instruccin MOV BX,OFFSET DATAS copia la direccin de offset de DATAS en BX. Cuando se usa la directiva OFFSET con la instruccin MOV, el ensamblador calcula la direccin de offset y despus usa una instruccin MOV inmediata para cargar la direccin en el registro de 16 bits indicado.

Una vez inicializados el contador y apuntador, se ejecuta un ciclo repeatuntil CX=0. Los datos son ledos de la localidad 46CH del segmento extra con la instruccin MOV AX,ES:[046CH] y almacenados en localidades de memoria indicadas indirectamente por la direccin de offset ubicada en el registro BX. A continuacin, se incrementa en uno BX dos veces para direccionar la siguiente palabra de la tabla. Finalmente, se repite la instruccin LOOP 50 veces.

La instruccin LOOP decrementa en uno el contador en CX; si CX no es cero, la instruccin LOOP salta a la localidad de memoria AGAIN. Si CX es cero, no hay salto y termina la secuencia de instrucciones. Este ejemplo copia los ltimos 50 valores del reloj en el arreglo de memoria DATAS, los cuales sern casi todos el mismo valor ya que el reloj cambia 18.2 veces por segundo.

3.1.5 Direccionamiento base-ms-ndice


El direccionamiento base-ms-ndice transfiere un byte o palabra entre un registro y una localidad de memoria direccionada por un registro base (BP o BX) ms un registro ndice (DI o SI) en el 8086 al 80286. Por ejemplo, la instruccin MOV [BX+DI],CL copia el byte contenido en CL a la localidad de memoria del segmento de datos direccionada por BX ms DI. En el 80386 y posteriores, dos registros cualquiera (EAX, EBX, ECX, EDX, EBP, EDI o ESI) se pueden combinar para generar la direccin de memoria. Por ejemplo, la instruccin MOV [EAX+EBX ],CL copia el byte del registro CL en la localidad de memoria del segmento de datos direccionada por EAX ms EBX. Este modo de direccionamiento es similar al modo de direccionamiento indirecto visto anteriormente, ya que tambin direcciona datos en memoria indirectamente. En el 8086 al 80286 el registro base (BP o BX) comnmente contiene la direccin de inicio de un arreglo en memoria, mientras que el ndice (DI o SI) contiene la posicin relativa de un elemento del arreglo. Recurdese que cuando BP direcciona datos en memoria, la direccin efectiva es generada por el registro de segmento de stack ES (stack segment register) y BP.

3.1.5.1 Ubicacin de datos con direccionamiento base-ms-ndice En al Figura 38 se muestra la forma de cmo los datos son direccionados por la instruccin MOV DX,[BX+DI] cuando el Microprocesador trabaja en modo real. En este ejemplo, se asume que BX=1000H, DI=0010H y DS=0100H lo cual apunta a la direccin de memoria 02010H. Esta instruccin transfiere una copia de la palabra ubicada en la localidad 02010H al registro DX.

Figura 38 Ejemplo del modo de direccionamiento base-ms-ndice con la instruccin MOV DX,[BX+DI]. Se accede la localidad de memoria 02010H ya que DS=0100H, BX=100H y DI=0010H

La Tabla 36 muestra algunas instrucciones que usan el direccionamiento base-ms-ndice. El ensamblador de Intel (ASM) requiere que este modo de direccionamiento se indique como [BX][DI] en lugar de [BX+DI]. La instruccin MOV DX,[BX+DI] es la instruccin MOV DX,[BX][DI] para un programa escrito en el ensamblador ASM. En los ejemplos usados en estas notas se usar la primera forma y la segunda forma se puede usar en varios ensambladores, incluyendo el MASM de Microsoft. Las instrucciones como MOV DI,[BX+DI] se ensamblaran pero no se ejecutarn correctamente.

Tabla 36 Ejemplos de direccionamiento base-ms-ndice

3.1.5.2 Ubicacin de arreglos de datos con direccionamiento basems-ndice Un uso comn del modo de direccionamiento base-ms-ndice es para direccionar elementos en un arreglo en memoria. Supngase que se necesita acceder a los elementos de un arreglo localizado en el segmento de datos en la localidad de memoria ARRAY. Para hacer esto, se puede cargar el registro BX (base) con la direccin de inicio del arreglo y el registro DI (ndice) con el nmero de elemento a acceder. La Figura 39 muestra el uso de BX y DI para acceder un elemento de un arreglo de datos.

Figura 39 Ejemplo del modo de direccionamiento base-ms-ndice. Se direcciona un elemento (DI) de un ARRAY (BX)

A continuacin se muestra un ejemplo que mueve el elemento o posicin 10H (16 decimal) del arreglo, al elemento 20H (32 decimal). Ntese que el nmero de elemento del arreglo, o posicin en el arreglo, es cargado en DI, para direccionar a ese elemento. Ntese tambin cmo ha sido inicializado el contenido de ARRAY tal que el elemento 10H (16 decimal) contiene 29H.

3.1.6 Direccionamiento relativo de registro


El direccionamiento relativo de registro mueve un byte o palabra entre un registro y una localidad de memoria direccionada por un registro ndice o base ms un desplazamiento. Por ejemplo, en las instrucciones MOV AX,[BX+4] y MOV AX,ARRAY[BX], la primera carga AX con el contenido de localidad del segmento de datos cuya direccin se forma por BX ms 4. En la segunda se carga AX con el contenido de la localidad ARRAY+BX del segmento de datos. En el 80386 y posteriores, se usa para direccionar a memoria cualquier registro excepto ESP. Por ejemplo, en las instrucciones MOV AX,[ECX+4] y MOV AX,ARRAY[EBX], en la primera instruccin se carga AX con el contenido de la localidad del segmento de datos formada por ECX ms 4. En la segunda instruccin se carga AX con el contenido de la localidad del segmento de datos ARRAY ms el contenido de EBX. Este modo de direccionamiento es similar a los modos de direccionamiento de desplazamiento y base-ms-ndice vistos anteriormente. En el modo de direccionamiento relativo de registro, el dato en un segmento de memoria es direccionado sumando el desplazamiento al contenido de un registro base o un ndice (BP, BX, DI o SI).

La Figura 310 muestra la operacin de la instruccin MOV AX,[BX+1000H]. En este ejemplo se asume que BX=0100H y DS=0200H, de manera que la direccin generada es la suma de DS x 10H, BX y el desplazamiento 1000H, la cual apunta a la localidad 03100H. Recurdese que BX, DI o SI direccionan o apuntan al segmento de datos y BP al segmento de stack. En el 80386 y posteriores, el desplazamiento puede ser un nmero de 32 bits y el registro puede ser cualquier registro de 32 bits excepto el registro ESP.

Figura 3-10 Operacin de MOV AX,[BX+1000H], cuando BX=0100H y DS=0200H

Recurdese que el tamao de un segmento en modo real es de 64 Kbytes.

En la Tabla 37 se muestran algunas instrucciones que usan el modo de direccionamiento relativo de registro. El desplazamiento es un nmero que se suma al registro indicado dentro de [ ], como por ejemplo en la instruccin MOV AL,[DI+2], o es un nmero que se resta a un registro, como por ejemplo la instruccin MOV AL,[SI1]. Un desplazamiento puede ser tambin una direccin de offset indicada al frente de [ ], como en la instruccin MOV AL,DATA[DI]. Ambas formas de desplazamiento pueden aparecer simultneamente como en la instruccin MOV AL,DATA[DI+3]. Ambas formas de desplazamiento suman la base y el registro ndice indicado dentro de los smbolos [ ]. En los Microprocesadores 8086 a 80286 el valor del desplazamiento est limitado a un numero signado de 16 bits, en el rango de +32,767 (7FFFH) y 32,768 (8000H); en el 80386 y posteriores, se puede usar un desplazamiento de 32 bits con rangos de (7FFFFFFFH) y (80000000H).

Tabla 37 Ejemplos de direccionamiento relativo de registro

3.1.6.1 Ubicacin de arreglos de datos con direccionamiento relativo de registro Es posible ubicar arreglos de datos con direccionamiento relativo de registro, tal como se hace con direccionamiento base-ms-ndice. En la Figura 311, se ilustra lo anterior con el mismo ejemplo usado en el direccionamiento base-ms-ndice. El desplazamiento de ARRAY se suma al registro ndice DI para generar la referencia a un elemento del arreglo.

Figura 311 Direccionamiento relativo de registro usado para acceder un elemento de ARRAY. El desplazamiento direcciona el inicio de ARRAY, y DI accede un elemento

El siguiente ejemplo muestra cmo este modo de direccionamiento puede transferir el contenido del elemento del arreglo 10H al elemento 20H. Ntese el parecido de este ejemplo con el anterior, la diferencia principal es que en este ejemplo, no se usa el registro BX para direccionar en memoria a ARRAY y en su lugar ARRAY se usa como un desplazamiento realizndose la misma tarea.

ANTERIOR

3.1.7 Direccionamiento base relativo-ms-ndice


El direccionamiento base relativo-ms-ndice transfiere un byte o palabra entre un registro y una localidad de memoria direccionada por una base, un registro ndice y un desplazamiento. Por ejemplo, las instrucciones MOV AX,ARRAY[BX+DI] y MOV AX,[BX+DI+4], cargan AX con el contenido de una localidad de memoria del segmento de datos. La primera instruccin usa una direccin formada sumando ARRAY, BX y DI y la segunda instruccin sumando BX, DI y 4. En el 80386 y posteriores, MOV EAX, ARRAY[EBX+ECX] carga EAX desde la localidad de memoria del segmento de datos formada por la suma de ARRAY, EBX y ECX. Este modo de direccionamiento es similar al modo de direccionamiento base-ms-ndice, pero este adiciona un desplazamiento al registro base y al registro ndice para formar una direccin de memoria. Este modo de direccionamiento se puede usar para direccionar un arreglo de dos dimensiones en memoria.

3.1.7.1 Ubicacin de datos con base relativo-ms-ndice Es uno de los modos de direccionamiento poco usados. En la Figura 312 se muestra cmo son referenciados los datos con la instruccin MOV AX,[BX+SI+100H]. El desplazamiento de 100H se adiciona a BX y SI para formar la direccin de offset dentro del segmento de datos. Si se asume que BX=0020H, SI=0100H y DS=1000H, la direccin efectiva para esta instruccin es 10130H, la suma de los registros y un desplazamiento de 100H. Este modo de direccionamiento es un poco complejo por lo que se usa poco en programas.

Figura 312 Direccionamiento base relativo-ms-ndice usando MOV AX,[BX+SI+100H]. Ntese que DS=1000H.

En la Tabla 3.8 se muestran algunas instrucciones que usan direccionamiento base relativo-ms-ndice. En el 80386 y posteriores, la direccin efectiva se genera por la suma de dos registros de 32 bits ms un desplazamiento de 32 bits.

Tabla 38 Ejemplo de instrucciones base relativo-ms-ndice

3.1.7.2 Ubicacin de arreglos con direccionamiento base relativo-msndice Supngase que se tiene en memoria un archivo con registros y que cada registro contiene varios elementos. El desplazamiento direcciona al archivo, el registro base direcciona un registro y el registro ndice direcciona un elemento de un registro. En la Figura 313 se muestra este de direccionamiento un poco complejo.

Figura 313 Direccionamiento base relativo-ms-ndice usado para acceder a FILE que contiene mltiples registros (REC)

El siguiente ejemplo proporciona un programa que copia el elemento 0 del registro A en el elemento 2 del registro C usando el modo de direccionamiento base relativo-ms-ndice. En este ejemplo, FILE contiene cuatro registros y cada registro contiene 10 elementos. Ntese como se usa la declaracin THIS BYTE para definir las etiquetas FILE y RECA en la misma localidad de memoria.

3.1.7 Direccionamiento de ndice con escalacin o escalado


El direccionamiento de ndice con escalacin solo est disponible en el 80386 al Pentium 4. Puede usar uno o dos registros de 32 bits para acceder a memoria. Cuando usa dos registros (un registro base y un registro ndice), el segundo registro es modificado por el factor de escalacin 2x, 4x u 8x para generar la direccin de memoria del operando. Por ejemplo, la instruccin MOV EDX,[EAX+4*EBX] carga EDX con el contenido de una localidad de memoria del segmento de datos direccionada por EAX ms cuatro veces EBX. El escalar o factor de escalacin permite acceder un dato de una palabra (2x), de una palabra doble (4x) o de una palabra cudruple (8x) de un arreglo en memoria. El factor de escalacin 1x tambin existe pero normalmente est implcito en la instruccin y no aparece. Por ejemplo, la instruccin MOV AL,[EBX+ECX] es un ejemplo donde el factor de escalacin es uno. Esta instruccin puede expresarse tambin como MOV AL,[EBX+1*ECX]. Otro ejemplo es la instruccin MOV AL,[2*EBX] la cual usa solo un registro escalado para direccionar memoria.

En la Tabla 39 se muestran algunos ejemplos del modo de direccionamiento de ndice escalado. Hay tambin una cantidad grande de combinaciones de este modo de direccionamiento. La escalacin tambin se aplica en instrucciones que usan un registro indirecto simple para acceder memoria. La instruccin MOV EAX,[4*EDI] es una instruccin escalada que usa un registro para acceder memoria indirectamente. En el modo de 64 bits se puede usar una instruccin como la siguiente: MOV RAX,[8*RDI].

Tabla 39 Ejemplos de direccionamiento de ndice escalado

En el ejemplo siguiente se muestra una secuencia de instrucciones que usan direccionamiento de ndice con escalacin para acceder un arreglo de datos de tamao palabra llamado LIST. Ntese que la direccin de offset LIST se carga al registro EBX con la instruccin MOV EBX,OFFSET LIST. Una vez que EBX apunta al arreglo LIST, los elementos (localizados en ECX) 2, 4 y 7 de este arreglo, de tamao palabra cada uno, se igualan, usando un factor de escalacin de 2 para acceder cada uno de ellos. El programa almacena el contenido del elemento 2, en los elementos 4 y 7. Ntese tambin que se usa la directiva .386 para seleccionar el Microprocesador 80386. Esta directiva debe seguir a la declaracin .MODEL para que el ensamblador procese instrucciones del 80386 para el sistema operativo DOS. Si se usa el Microprocesador 80486 debe usarse la directiva .486 despus de la declaracin .MODEL. Si se usa el Microprocesador Pentium usar .586 y si se usan los Pentium Pro, Pentium II, Pentium III, Pentium 4 o Core2 usar la directiva .686. Si aparece la directiva de seleccin del Microprocesador antes de la declaracin .MODEL, el Microprocesador ejecuta instrucciones en el modo protegido de 32 bits, las cuales debe ejecutar en Windows.

3.1.8 Direccionamiento relativo RIP


El direccionamiento relativo RIP solo est disponible en el Pentium 4 y Core2. Este modo permite acceder a cualquier localidad en la memoria sumando un desplazamiento de 32 bits al contenido de un apuntador de instruccin de 64 bits. Por ejemplo, si el registro RIP=1000000000H y el desplazamiento de 32 bits es 300H, la localidad accedida es 1000000300H.

El registro apuntador de instruccin (instruction pointer), normalmente se direcciona o se referencia en los programas usando un *, como por ejemplo *+34, lo cual indica 34 bytes adelante la instruccin del programa que se est decodificando. El programa ensamblador disponible en Visual C++ no tiene una forma de usar este modo de direccionamiento o cualquier otro de 64 bits. Microsoft Visual C++ actualmente no soporta desarrollo con cdigo en ensamblador de 64 bits. Intel si tiene un compilador para ensamblar todo el cdigo hecho para 64 bits.

3.1.9 Estructuras de datos


En muchas ocasiones es necesario usar una estructura de datos en un programa, con la cual se especifica cmo la informacin se almacena en un arreglo en memoria. El definir una estructura de datos sirve para que sta pueda usarse como una plantilla. El inicio de la estructura se identifica por la directiva STRUCT y termina con la directiva ENDS. En el siguiente ejemplo se muestra la definicin de una estructura de datos tpica que se usa tres veces. Ntese que el nombre de la estructura aparece en las directivas STRUC y ENDS. Esta estructura define cinco campos de informacin. El primer campo es de 32 bytes y contiene un nombre. El segundo campo es de 32 bytes y contiene el nombre de la calle. El tercer campo es de 16 bytes y contiene la ciudad. El cuarto campo de 2 bytes es para el estado y el quinto campo de 5 bytes es para el cdigo postal (ZIP en ingls). Una vez que ha sido definida la estructura (INFO), puede ser inicializada como se muestra. Se muestran tres ejemplos de uso de INFO. Ntese que los strings son encerrados con apstrofes y el campo completo encerrado con los smbolos < y > al usar la estructura para definir datos.

Al direccionar los datos de la estructura debe usarse el nombre de la estructura y el nombre del campo para seleccionar un campo de la estructura. Por ejemplo, para direccionar la calle (STREET) en NAME2, se usa el operando NAME2.STREET, donde el nombre de la estructura es seguido por un punto y despus se encuentra el nombre del campo.

En el siguiente ejemplo se muestra una secuencia de instrucciones que limpia: el campo de nombre de la estructura NAME1, el campo de direccin de la estructura NAME2 y el campo ZIP de la estructura NAME3. Posteriormente sern cubiertas en este curso la funcin y operacin detalladas de las instrucciones de este programa.

3.2 Modos programa

de

direccionamiento

memoria

de

Este modoe de direccionamiento se usa en las instrucciones JMP (jumpsalto) y CALL y tiene tres formas: directo, relativo e indirecto.

3.2.1 Direccionamiento directo a memoria de programa


Este modo es el que usaban muchos Microprocesadores antiguos en todas las instrucciones JUMP y CALL. Tambin se usa en lenguajes de alto nivel como en las instrucciones GOTO y GOSUB del BASIC. El Microprocesador tambin usa este modo de direccionamiento pero no tanto como el relativo y el indirecto. Las instrucciones que usan el direccionamiento directo a memoria de programa almacenan la direccin en el cdigo de operacin de la instruccin. Por ejemplo, si un programa salta a la localidad de memoria 10000H, la direccin 10000H se almacena o est contenida en el cdigo de operacin en memoria. En la Figura 314 se muestra el cdigo de operacin de la instruccin JUMP para el salto directo inter-segmento y los 4 bytes requeridos para almacenar la direccin 10000H. La instruccin JMP carga al CS con 1000H y al IP con 0000H para saltar a la localidad de memoria 10000H. Un salto inter-segmento es un salto a cualquier localidad de memoria dentro de toda la memoria del sistema. Al salto directo tambin se le llama far jump (o lejano) porque puede saltar a cualquier localidad de memoria. En modo real, un far jump puede saltar a cualquier localidad dentro del primer Mbyte de memoria cambiando CS e IP.

Figura 314 Cinco bytes en lenguaje de mquina de la instruccin JMP [10000H]

En modo protegido el far jump puede acceder a un nuevo descriptor de segmento de cdigo localizado en una tabla de descriptores, permitindole saltar a cualquier localidad en el rango de direcciones de 4 GBytes en el 80386 y Core2. En el modo de 64 bits del Pentium 4 y Core2, un salto (jump) o llamada (call) puede ser a cualquier localidad de memoria del sistema. Todava se usa el registro CS pero no para la direccin del salto o llamada, si no como un apuntador a un descriptor que describe los derechos y nivel de privilegio de acceso al segmento de cdigo.

La otra instruccin que usa direccionamiento directo a memoria de programa es la instruccin CALL la cual es inter-segmento, en la cual se especifica una direccin de memoria, llamada etiqueta, en lugar de una direccin numrica. Cuando se usa una etiqueta con la instruccin CALL o JMP, la mayora de los ensambladores seleccionan el mejor modo de direccionamiento para el programa.

3.2.2 Direccionamiento relativo a memoria de programa


Este modo de direccionamiento no est disponible en Microprocesadores antiguos solo en la familia de Intel. El trmino relativo significa relativo al apuntador de instruccin (IP). Por ejemplo, si una instruccin JMP salta a los siguientes 2 bytes de memoria y la direccin de salto es en relacin al apuntador de instruccin al cual se le suma 2. En la Figura 3-15 se muestra un ejemplo de una instruccin JMP relativa. Ntese que la instruccin JMP es de 1 byte con 1 o 2 bytes para el desplazamiento que se le suman al apuntador de instruccin. Se usa un desplazamiento de 1 byte para saltos cortos (short jumps) y un desplazamiento de 2 bytes para saltos cercanos (near jumps). Ambos saltos se consideran intra-segmento (un salto intrasegmento es un salto a cualquier parte del segmento de cdigo actual).

Figura 315 La instruccin JMP [2], la cual salta 2 bytes de memoria despus de la instruccin JMP En el 80386 y posteriores, el desplazamiento puede ser de 32 bits, permitindoles usar direccionamiento relativo a cualquier localidad dentro de sus segmentos de cdigo de 4 GBytes. Las instrucciones JMP y CALL contienen un desplazamiento signado de 8 o 16 bits que permiten una referencia hacia adelante o hacia atrs en memoria. Todos los ensambladores calculan automticamente la distancia del desplazamiento y seleccionan el tamao de 1, 2 o 4 bytes. Si la distancia es muy grande para un desplazamiento de 2 bytes en los Microprocesadores 8086 al 80286, algunos ensambladores usan un salto directo. Un desplazamiento de 8 bits (short) tiene un rango entre +127 y 128 bytes. Un desplazamiento de 16 bits (near) tiene un rango entre +/- 32 KBytes. En el 80386 y posteriores se puede usar un desplazamiento de 32 bits con un rango de +/- 2 GBytes. El desplazamiento de 32 bits solo puede usarse en modo protegido.

3.2.3 Direccionamiento indirecto a memoria de programa


El Microprocesador permite varias formas de direccionamiento indirecto a memoria de programa para las instrucciones JMP y CALL. En la Tabla 3-10 se listan algunas instrucciones de este tipo, las cuales pueden usar: cualquier registro de 16 bits (AX, BX, CX, DX, SP, BP, DI o SI); cualquier registro relativo ([BP], [BX], [DI] o [SI]) y cualquier registro relativo con un desplazamiento.

Tabla 310 Ejemplos de direccionamiento indirecto a memoria de programa

En el 80386 y posteriores, se puede usar tambin un registro extendido para contener la direccin o direccionamiento indirecto de un JMP o CALL relativos. Por ejemplo, la instruccin JMP EAX salta a la localidad direccionada por el registro EAX. Si un registro de 16 bits contiene la direccin de una instruccin JMP, el salto es del tipo near (cercano). Por ejemplo, si el registro BX contiene 1000H y se ejecuta la instruccin JMP BX, el programa salta a la direccin offset 1000H del actual segmento de cdigo. Si un registro relativo es el que contiene la direccin, el salto tambin es considerado un salto indirecto. Por ejemplo. La instruccin JMP [BX] se refiere a la localidad de memoria dentro del segmento de datos y la direccin de offset contenida en el registro BX. Esta direccin de offset es

un nmero de 16 bits que se usa como un offset en el salto intra-segmento. A este tipo de salto algunas veces se le llama indirecto-indirecto o dobleindirecto. En la Figura 3-16 se muestra una tabla de saltos almacenada iniciando en la localidad de memoria TABLE.

Figura 3-16 Tabla de saltos almacenada iniciando en la localidad de memoria TABLE

Esta tabla de saltos se usa en el programa siguiente, donde el registro BX es cargado con un 4, que al combinarse con TABLE en la instruccin JMP TABLE[BX], se obtiene como direccin efectiva el contenido de la segunda entrada de 16 bits de la tabla de saltos.

3.3 Modos de direccionamiento a memoria de stack


El stack o pila tiene un papel importante en todos los Microprocesadores. El stack contiene datos temporales y almacena la direccin de regreso o retorno usada en procedimientos y sub-rutinas. La memoria de stack es del tipo LIFO (last-in, first-out), lo cual determina la forma en que los datos son almacenados y removidos del stack. Los datos son colocados en el stack con una instruccin PUSH y removidos con una instruccin POP. La instruccin CALL tambin usa el stack para almacenar la direccin de retorno y la instruccin RET (return) para remover la direccin de retorno del stack. El stack es apuntado por dos registros: el apuntador de stack (stack pointer-SP o ESP) y el registro de segmento de stack (SS).

Cuando un dato tamao palabra se almacena en el stack (ver Figura 3-17a), los 8 bits de alto orden son colocados en la localidad direccionada por SP-1. Los 8 bits de bajo orden son colocados en la localidad direccionada por SP-2. El SP es decrementado a continuacin, de manera tal que la siguiente palabra se almacena en la siguiente localidad disponible en el stack. El registro SP/ESP siempre apunta a un rea de memoria localizada dentro del segmento de stack. El registro SP/ESP se suma a SSx10H para formar la direccin de memoria en el stack en el modo real. En modo protegido, el registro SS contiene un selector que accede un descriptor para la direccin de la base del segmento de stack.

Figura 317 Instrucciones PUSH y POP: (a) PUSH BX coloca el contenido de BX en el stack; (b) POP CX remueve el dato del stack y lo coloca en CX. Se muestran ambas instrucciones despus de su ejecucin

Siempre que se saca un dato del stack (Figura 3-17b), los 8 bits de bajo orden son removidos de la localidad direccionada por SP. Los 8 bits de alto orden son removidos de la localidad direccionada por SP+1. El registro SP se incrementa en 2. La Tabla 3-11 muestra algunas instrucciones POP disponibles en el Microprocesador. PUSH y POP manejan palabras, nunca bytes en los Microprocesadores 8086 al 80286. En el 80386 y posteriores se permite transferir palabras y palabras dobles entre el stack. Los datos pueden sacarse del stack a cualquier registro o registro de segmento excepto el registro CS, esto es porque cambiara parte de la direccin de la siguiente instruccin del programa y modificara el flujo del programa. Las instrucciones PUSHA y POPA almacenan o recuperan del stack todos los registros menos los registros de segmento. Estas instrucciones no estn disponibles en los Microprocesadores antiguos 8086/88.

En la Tabla 3-11 se muestra el orden seguido para la transferencia y recuperacin de registros del stack con las instrucciones PUSHA y POPA. El 80386 y posteriores tambin permiten que los registros extendidos sean manejados con el stack y el Pentium 4 y Core2 no tienen instrucciones PUSHA y POPA en su conjunto de instrucciones

Tabla 311 Ejemplo de instrucciones PUSH y POP

El siguiente ejemplo muestra un programa que almacena el contenido de AX, BX y CX en el stack. El primer POP recupera el valor de CX que se almacen en el stack y lo carga en AX. El segundo POP almacena el valor original de BX en CX. El ltimo POP almacena el valor de AX en BX.