1 MODOS DE DIRECCIONAMIENTO DE LA MEMORIA
MODOS DE DIRECCIONAMIENTO A LA MEMORIA DEL PROGRAMA Los modos de direccionamiento a la memoria del programa, usan las instrucciones JMP (Salto) y CALL (Llamada), las cuales consisten de tres formas:
Directo Relativa Indirecta
Direccionamiento directo a la memoria del programa. Este tipo de direccionamiento es el que usaban las maquinas antiguas para todos los saltos y llamadas. La principal característica de las instrucciones de memoria directo es que almacenan la dirección con el código de operación. Por ejemplo, si un programa salta a la localidad de memoria 10 000H para la siguiente instrucción, la dirección 10 000H es almacenada a continuación del código de operación en la memoria. La figura 1.1 muestra la instrucción JMP de salto directo y los 4 bytes requeridos para almacenar la dirección 10 000H. Código de operación
EA
Desplazamiento bajo
00
Desplazamiento alto
Segmento bajo
Segmento alto
00
00
10
Figura 1.1: la instrucción de 5 bytes JMP [10 000H], es seguido por la dirección de desplazamiento (0000H) y después por la dirección de segmento de código (1000H). El salto directo se le relaciona con el nombre de salto lejano, debido a que puede saltar a cualquier localidad de memoria o cualquier instrucción. La única instrucción que utiliza el direccionamiento directo de memoria es la instrucción CALL de intersegmento (un salto de intersegmento es un salto a cualquier localidad de memoria dentro del sistema de memoria). Una dirección de memoria, llamado una etiqueta se refiere a la localidad que es llamada a donde se salta en lugar de la dirección numérica real. Cuando se utiliza una etiqueta con las instrucciones JMP o CALL, la mayoría de los ensambladores seleccionan la mejor forma de direccionar el programa.
Direccionamiento relativo a la memoria del programa. Este tipo de direccionamiento no está disponible para muchos microprocesadores antiguos, pero para el microprocesador 80286 si lo está. El termino relativo significa “relativo al apuntador de instrucción IP”. Un ejemplo de esto es, si una instrucción JMP salta los dos siguientes bytes de memoria, la dirección con relación al apuntador de instrucción es un 2 que se suma al apuntador de instrucción. Esto revela la dirección de la siguiente instrucción del programa. Un ejemplo de esta instrucción se muestra en la siguiente figura 1.1:
2 MODOS DE DIRECCIONAMIENTO DE LA MEMORIA
10000 10001 10002 10003 10004
EB 02 -
JMP [2]
Figura 1.1: la instrucción JMP [2] salta sobre los siguientes dos bytes en el programa. En este ejemplo, el programa continúa en la localidad 10004H. La instrucción JMP es de un byte, el desplazamiento es de 1 byte o de 2 bytes que se suman al apuntador de instrucción. El desplazamiento de 1 byte es usado en saltos cortos, el desplazamiento de 2 bytes es usado con saltos y llamadas próximo. Ambas instrucciones son considerados saltos intrasegmento (un salto intrasegmento es un salto a cualquier parte dentro del segmento de código actual). Las instrucciones JMP y CALL tienen un desplazamiento de 8 o 16 bits lo que permiten moverse hacia atrás o hacia adelante. Cuando la distancia es demasiado lejos para un desplazamiento de 2 bytes, algunos ensambladores realizan un salto directo. Los valores de desplazamiento se enlistan a continuación: 8 bits (corto) tiene un valor entre +127 y -128 bytes. 16 bits (cercano) tiene un valor entre ±32 KB. En resumen el direccionamiento relativo a programa permite que las instrucciones JMP o CALL se dividan ±32KB hacia adelante o hacia atrás, dentro del segmento de código.
Direccionamiento indirecto de la memoria de programa. A continuación se muestra una tabla, figura 1.3 en las cuales enlista algunas instrucciones de salto del programa indirectas aceptables, las cuales pueden ser de 16 bits (AX, BX, CX, DX, SP, BP, DI o SI), cualquier registro relativo ([BP], [BX], [DI], [SI]), y cualquier registro relativo con un desplazamiento. Figura 1.3: Lenguaje ensamblador JMP AX JMP CX JMP NEAR PTR [BX]
JMP NEAR PTR [DI+2]
JMP TABLE[BX]
JMP ECX
Operación Salta a la localidad del segmento de código actual direccionada por el contenido de AX. Salta a la localidad del segmento de código actual direccionada por el contenido de CX. Salta a la localidad del segmento de código actual direccionada por el contenido de la localidad de memoria del segmento de datos direccionada por BX. Salta a la localidad del segmento de código actual direccionada por el contenido de la localidad de memoria del segmento de datos direccionada por DI más 2. Salta a la localidad actual del segmento de código direccionada por el contenido de la localidad de memoria del segmento de datos direccionada por TABLE más BX. Salta a la localidad actual del segmento de código direccionada por el contenido de ECX (ECX instrucción de 32 bits).
3 MODOS DE DIRECCIONAMIENTO DE LA MEMORIA
En los microprocesadores 80386 y posteriores se puede utilizar un registro extendido para la dirección indirecta de un salto o llamada de subrutina relativos, un ejemplo es la instrucción JMP EAX. Si un registro de 16 bits forma la dirección de la instrucción JMP, el salto es cercano: Ejemplo: 1234 1235
JMP BX BX = 1000H El microprocesador salta a la dirección de desplazamiento 1000H en el segmento de código actual.
Si un registro relativo mantiene la dirección, el salto también es considerado como indirecto: Ejemplo: 1000 1001 1002
JMP [BX] [BX], se refiere a la localidad de memoria que está dentro del segmento de datos en la dirección de desplazamiento contenida por BX. BX=Cualquier número de 16 bits utilizado como la dirección de desplazamiento en el salto de intrasegmento. A este tipo de salto se le llama salto indirecto-indirecto o doble-indirecto.
La figura 1.4 muestra una tabla de salto que es almacenada empezando en la localidad de memoria TABLE. Esta tabla de salto es referenciada por el programa del ejemplo 2.1 Ejemplo 2.1 ; uso del direccionamiento indirecto por un salto 0000 BB 0004 MOV BX, 4 ; dirección de L0C2 0003 FF A7 23A1 R JMP TABLE [BX] ; saltar a L0C2 En este ejemplo, el registro BX es cargado con un 4, de tal manera que cuando se combina en la instrucción JMP TABLE [BX] con TABLE, la dirección real es el contenido de la segunda entrada en la tabla de salto. Figura 1.4 TABLE
DW DW DW DW
L0C0 L0C1 L0C2 L0C3
Direcciones de cuatro programas diferentes (cada dirección es un desplazamiento de 2 bytes).
Una tabla de salto que se usa para permitir al programa elegir diferentes direcciones de salto para valores distintos en el registro BX.
4 MODOS DE DIRECCIONAMIENTO DE LA MEMORIA
MODOS DE DIRECCIONAMIENTO DE LA PILA (STACK) La pila es una parte importante en todos los microprocesadores, ya que contiene temporalmente datos y almacena direcciones de retorno para subrutinas. La dirección de la pila es de tipo LIFO (último en entrar, primero en salir) en el microprocesador. Los datos son introducidos en la memoria pila con la instrucción PUSH y extraídos con la instrucción POP. La instrucción CALL usa el stack para guardar la dirección de retorno para subrutinas y una instrucción RET (retorno) para remover la dirección de retorno del stack.
Figura 3.1: las instrucciones PUSH y POP. (a) PUSH BX coloca el contenido del registro BX en el stack direccionado por el SP + SS x 10H. (b) POP CX extrae datos del stack en la localidad direccionada por SP + SS x 10H y los coloca en el registro CX.
5 MODOS DE DIRECCIONAMIENTO DE LA MEMORIA
La memoria stack 80286 es mantenida por medio de dos registros: Apuntador de pila (SP o ESP). Registro de segmento de pila (SS). Cuando una palabra de datos es empujada a la pila [véase la figura 3.1 (a)], los 8 bits más significativos (AH, BH, etc.) son colocados en la localidad direccionada por SP-1. Los 8 bits menos significativos (AL, BL, etc.) son colocados en la localidad direccionada por SP-2. El SP es decrementado por 2, de tal manera que la siguiente palabra de datos es almacenada en la siguiente localidad de memoria de la pila disponible [véase figura 3.2]. El SP siempre apunta a un área de la memoria localizada dentro del segmento de la pila. Para formar la dirección de memoria de la pila en modo real es necesario realizar la suma de SP + SS x 10H. . . .
. . .
. . .
. . .
. . .
. . .
SS
. . .
SP=SP . . .
. . .
. . .
. . .
SS Figura 3.2: SP es decrementado por 2 por cada palabra de dato introducida.
1234
SP=SP-2
Cuando los datos son extraídos de la memoria [véase la figura 3.1 (b)], los 8 bits menos significativos son extraídos de la localidad direccionada por SP; los 8 bits más significativos son extraídos de la localidad direccionada por SP+1. El registro SP se incrementa en 2 [véase la figura 3.3]. SP . . .
. . .
. . .
. . .
. . .
SS
. . .
1234 SP=SP-2
. . .
. . .
. . .
. . .
SS
. . .
SP=SP+2
Figura 3.3: SP es incrementado en 2 después de haber extraído cada palabra de dato. Observe que PUSH y POP siempre almacenan o recuperan palabras de datos, nunca bytes. Los datos pueden ser extraídos de la memoria de pila hacia cualquier registro de 16 bits o registro de
6 MODOS DE DIRECCIONAMIENTO DE LA MEMORIA
segmento, excepto CS. La razón consiste en que con ello sólo se cambia una parte de la dirección de la siguiente instrucción. A continuación se listan algunas instrucciones PUSH y POP. Lenguaje ensamblador POPF POPFD PUSHF PUSHFD PUSH AX POP BX PUSH DS PUSH 1234H POP CS PUSH WORD PTR [BX] PUSHA POPA PUSHAD POPAD POP EAX PUSH EDI
Operación Extrae una palabra de la memoria de pila y la coloca en las banderas. Extrae una palabra doble de la memoria de pila y la coloca en el registro EFLAG. Copia las banderas sobre pila. Copia el registro EFLAG sobre pila. Copia AX a la pila. Extrae una palabra de la pila y la coloca en BX. Copia DS a la pila. Copia un 1234H a la pila. Instrucción ilegal. Copia una palabra de la localidad de memoria el segmento de datos direccionada por BX, en la memoria de pila. Copia las palabras contenidas en AX, BX, CX, DX, SP, BP, DI y SI en la pila. Extrae datos de la pila y los coloca en SI, DI, BP, SP, DX, CX, BX y AX. Copia las palabras dobles contenidas en EAX, ECX, EDX, EBX, ESP, EBP, EDI y ESI en la memoria de pila. Extrae datos de la memoria de pila y los coloca en ESI, EDI, EBP, ESP, EBX, EDX, ECX y EAX. Extrae datos de la memoria de pila y los coloca en EAX. Copia EDI en la memoria de pila.
En los microprocesadores 8086/8088 las instrucciones PUSHA y POPA no están disponibles. La función de estas instrucciones es copiar o extraer todos los registros a excepción del CS, de la memoria de pila.