# Segmentación de memoria del x86
## Direccionamiento de memoria

Los registros del 8086 son de 16 bits, por lo tanto el número de direcciones posibles a direccionar con 1 solo registro es 64 KiB. Los valores de direcciones se encuentran en el rango de 0 a FFFF. Para superar este límite se utilizan 2 registros para direccionar memoria: Uno de SEGMENTO y otro de DESPLAZAMIENTO (offset) dentro del segmento. La notación utilizada para una dirección segmentada es: SEGMENTO:DESPLAZAMIENTO. La relación entre la dirección de memoria real y la dirección segmentada es: DIR = SEGMENTO * 16 + DESPLAZAMIENTO. Al multiplicar por 16 se obtienen 4 bits más con lo que ahora se tiene un total de 1024 KiB = 1 MiB de memoria direccionable. Los valores para las direcciones reales se encuentran en el rango 0 a FFFFFh. Es importante hacer notar que una misma dirección de memoria puede ser direccionada con distintos valores de segmento y desplazamiento Ej: 100:50 = 105:0 =0:1050, trabajando en base 16.

## Modos de direccionamiento

Se entiende por modos de direccionamiento a las diferentes formas que pueden tomar los parámetros de las instrucciones del procesador. Diferentes autores clasifican en forma distinta los modos de direccionamiento del 8086. Nosotros distinguiremos fundamentalmente cuatro modos diferentes:

### Registro

Un parámetro que direcciona a un registro está utilizando el modo de direccionamiento registro. Ej: MOV AX, BX
En este ejemplo los dos parámetros direccionan un registro.

### Valor o inmediato

El modo de direccionamiento inmediato es utilizado cuando se hace referencia a un valor constante. Este se codifica junto con la instrucción. Es decir dicho parámetro representa a su valor y no a una dirección de memoria o un registro que lo contiene.
Ej: MOV AX, 500
En este ejemplo el número 500 es un parámetro inmediato.

### Directo

Se utiliza el modo directo cuando se referencia a una dirección de memoria y la misma está codificada junto con la instrucción. Ej: MOV AL, [127].
En este ejemplo el desplazamiento de la dirección de memoria se codifica junto con la instrucción y el segmento se asume a DS. Si MEMORIA es un array de bytes que representa a la memoria la instrucción anterior se puede poner como: AL := MEMORIA[ DS:127 ]

### Indirecto

Se utiliza el modo indirecto cuando se referencia a una dirección de memoria a través de uno o varios registros. Ej: MOV AL, [BX].
Aquí el desplazamiento de la dirección de memoria está contenido en el registro BX y al igual que el caso anterior como no se especifica el segmento se asume DS. Si MEMORIA es un array de bytes que representa a la memoria la instrucción anterior se puede poner como:
Al := MEMORIA[ DS:BX ]
La especificación completa de las expresiones que van dentro de los paréntesis rectos es: { BX | BP } [ + { SI | DI } ] [ + desplazamiento ] | { SI | DI } [ + desplazamiento ] | desplazamiento
Donde la expresión entre es obligatoria, la expresión entre es opcional y el signo | implica opción entre dos expresiones. Fuera del paréntesis recto se puede indicar cual es el registro de segmento usado para completar la dirección de memoria. En caso que este no se especifique siempre se asume uno por defecto.
Ejemplos: Mov Ax, [Bp + 3] Add [Bx + Si ], 4 Sub Es:[Bx + Di + 5],Dx
En la Tabla 1 se indican las combinaciones posibles entre registros índice y los segmentos así como las asignaciones por defecto.
* Datos: Q4413527