Registros del procesador 01

19
REGISTROS DEL PROCESADOR Los registros del procesador son sitios de almacenamiento rápido y temporal, se emplean para controlar instrucciones en ejecución, manejar direccionamiento de memoria y proporcionar capacidad aritmética. Los registros son espacios físicos dentro del microprocesador con capacidad de 4 bits hasta 64 bits dependiendo del microprocesador que se emplee Los registros del procesador se emplean para controlar instrucciones en ejecución, manejar direccionamiento de memoria y proporcionar capacidad aritmética. Los registros son direccionables por medio de un nombre. Los bits por convención, se numeran de derecha a izquierda, como en: ... 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 Los registros internos del procesador se pueden clasificar en 6 tipos diferentes 1. Registros de segmento 2. Registros de propósito general 3. Registros de apuntadores 4. Registros de banderas 5. Registros de Puntero de instrucción 6. Registros de Pila SEGMENTO Un segmento es un área especial en un programa que inicia en un límite de un párrafo, esto es, en una localidad de regularmente divisible entre 16, o 10 hexadecimal. Aunque un segmento puede estar ubicado casi en cualquier lugar de la memoria y, en modo real, puede ser hasta de 64K, solo necesita tanto espacio como el programa requiera para su ejecución. Un segmento en modo real puede ser de hasta 64K. Se puede tener cualquier número de segmentos; para direccionar un segmento en particular basta cambiar la dirección en el registro del segmento apropiado. Los tres segmentos principales son los segmentos de código, de datos y de la pila.

Transcript of Registros del procesador 01

Page 1: Registros del procesador 01

REGISTROS DEL PROCESADOR

Los registros del procesador son sitios de almacenamiento rápido y temporal, se emplean para controlar instrucciones en ejecución, manejar direccionamiento de memoria y proporcionar capacidad aritmética. Los registros son espacios físicos dentro del microprocesador con capacidad de 4 bits hasta 64 bits dependiendo del microprocesador que se emplee

Los registros del procesador se emplean para controlar instrucciones en ejecución, manejar direccionamiento de memoria y proporcionar capacidad aritmética. Los registros son direccionables por medio de un nombre. Los bits por convención, se numeran de derecha a izquierda, como en:

... 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

Los registros internos del procesador se pueden clasificar en 6 tipos diferentes

1. Registros de segmento 2. Registros de propósito general

3. Registros de apuntadores

4. Registros de banderas

5. Registros de Puntero de instrucción

6. Registros de Pila

SEGMENTO

Un segmento es un área especial en un programa que inicia en un límite de un párrafo, esto es, en una localidad de regularmente divisible entre 16, o 10 hexadecimal. Aunque un segmento puede estar ubicado casi en cualquier lugar de la memoria y, en modo real, puede ser hasta de 64K, solo necesita tanto espacio como el programa requiera para su ejecución.

Un segmento en modo real puede ser de hasta 64K. Se puede tener cualquier número de segmentos; para direccionar un segmento en particular basta cambiar la dirección en el registro del segmento apropiado. Los tres segmentos principales son los segmentos de código, de datos y de la pila.

Segmento de código.

El segmento de código (CS) contiene las instrucciones de maquina que son ejecutadas por lo común la primera instrucción ejecutable esta en el inicio del segmento, y el sistema operativo enlaza a esa localidad para iniciar la ejecución del programa. Como su nombre indica, el registro del CS direcciona el segmento de código. Si su área de código requiere mas de 64K, su programa puede necesitar definir mas de un segmento de código.

Segmento de datos.

Page 2: Registros del procesador 01

El segmento de datos (DS) contiene datos, constantes y áreas de trabajo definidos por el programa. El registro DS direcciona el segmento de datos. Si su área de datos requiere mas de 64K, su programa puede necesitar definir mas de un segmento de datos.

Segmento de pila.

En términos sencillos, la pila contiene los datos y direcciones que usted necesita guardar temporalmente o para uso de sus "llamadas" subrutinas. El registro de segmento de la pila (SS) direcciona el segmento de la pila.

Registros de segmento Un registro de segmento tiene 16 bits de longitud y facilita un área de memoria para direccionamiento conocida como el segmento actual.

Registro CS: El DOS almacena la dirección inicial del segmento de código de un programa en el registro CS. Esta dirección de segmento, mas un valor de desplazamiento en el registro apuntador de instrucción (IP), indica la dirección de una instrucción que es buscada para su ejecución. Para propósito de programación normal no se necesita referenciar al registro CS.

Registro DS: La dirección inicial de un segmento de datos de programa es almacenada en el registro DS. En términos sencillos, esta dirección, mas un valor de desplazamiento en una instrucción, genera una referencia a la localidad de un byte especifico en el segmento de datos.

Registro SS: El registro SS permite la colocación en memoria de una pila, para almacenamiento temporal de direcciones y datos. El DOS almacena la dirección de inicio del segmento de pila de un programa en le registro SS. Esta dirección de segmento, mas un valor de desplazamiento en el registro del apuntador de pila (SP), indica la palabra actual en la pila que esta siendo direccionada. . Para propósito de programación normal no se necesita referenciar al registro SS.

Registros ES: Alguna operaciones con cadenas de caracteres (datos de caracteres) utilizan el registro extra de segmento para manejar el direccionamiento de memoria. En este contexto, el registro ES esta asociado con el registro DI (índice). Un programa que requiere el uso del registro ES puede inicializarlo con una dirección de segmento apropiada.

Registros FS y GS: Son registros extra de segmento en los procesadores 80386 y posteriores.

Registros de propósito general Los registros de propósito general AX, BX, CX y DX son los caballos de batalla del sistema. Son únicos en el sentido de que se puede direccionarlos como una palabra o como una parte de un byte. El último byte de la izquierda es la parte "alta", y el ultimo byte de la derecha es la parte "baja". Por

Page 3: Registros del procesador 01

ejemplo, el registro CX consta de una parte CH (alta) y una parte Cl (baja), y usted puede referirse a cualquier parte por su nombre.

Registro AX: El registro AX, el acumulador principal, es utilizado para operaciones que implican entrada/salida y la mayor parte de la aritmética. Por ejemplo, las instrucciones para multiplicar, dividir y traducir suponen el uso del AX. También, algunas operaciones generan código más eficiente si se refieren al AX en lugar de a los otros registros.

Registro BX: El BX es conocido como el registro base ya que es el único registro de propósito general que puede ser índice para direccionamiento indexado. También es común emplear el BX para cálculos.

Registro DX: El DX es conocido como el registro de datos. Algunas operaciones de entrada/salida requieren uso, y las operaciones de multiplicación y división con cifras grandes suponen al DX y al AX trabajando juntos.

AX se usa siempre en multiplicaciones y divisiones y es el más eficiente para operaciones aritméticas y de movimiento de datos.

BX se usa como puntero, y junto con DS referencia posiciones de memoria. Por ejemplo, para cargar en AL el contenido de la posición de memoria número 9:

MOV AX,0 MOV DS,AX MOV BX,9 MOV AL,[BX]

CX se usa principalmente como contador en los bucles. Estos son tan frecuentes que existe una instrucción especial, LOOP, que comprueba su valor, volviendo al principio del bucle si es distinto de cero:

MOV CX,10 BUCLE: instrucciones

LOOP BUCLE

DX es el único registro que puede usarse para acceder a puertos. Por ejemplo, para escribir 62H en la direccion de puerto 1000H:

MOV AL,62H MOV DX,1000H OUT DX,AL

Registro de Apuntador de Instrucciones

Page 4: Registros del procesador 01

El registro apuntador de instrucciones (IP) de 16 bits contiene el desplazamiento de dirección de la siguiente instrucción que se ejecuta. El IP esta asociado con el registro CS en el sentido de que el IP indica la instrucción actual dentro del segmento de código que se esta ejecutando actualmente. Los procesadores 80386 y posteriores tienen un IP ampliado de 32 bits, llamado EIP.

En el ejemplo siguiente, el registro CS contiene 25A40H y el IP contiene 412H. Para encontrar la siguiente instrucción que será ejecutada, el procesador combina las direcciones en el CS y el IP: Segmento de dirección en el registro CS: 25A40H Desplazamiento de dirección en el registro IP: + 412H Dirección de la siguiente instrucción: 25E52H

Registros Apuntadores Los registros SP (apuntador de la pila) Y BP (apuntador de base) están asociados con el registro SS y permiten al sistema acceder datos en el segmento de la pila.

Registro SP: El apuntador de la pila de 16 bits esta asociado con el registro SS y proporciona un valor de desplazamiento que se refiere a la palabra actual que esta siendo procesada en la pila. Los procesadores 80386 y posteriores tienen un apuntador de pila de 32 bits, el registro ESP. El sistema maneja de forma automática estos registros.

En el ejemplo siguiente, el registro SS contiene la dirección de segmento 27B3[0]H y el SP el desplazamiento 312H. Para encontrar la palabra actual que esta siendo procesada en la pila, la computadora combina las direcciones en el SS y el SP:

Registro BP: El BP de 16 bits facilita la referencia de parámetros, los cuales son datos y direcciones transmitidos vía pila. Los procesadores 80386 y posteriores tienen un BP ampliado de 32 bits llamado el registro EBP.

Registros Índice Los registros SI y DI están disponibles para direccionamiento indexado y para sumas y restas.

Registro SI: El registro índice fuente de 16 bits es requerido por algunas operaciones con cadenas (de caracteres). En este contexto, el SI esta asociado con el registro DS. Los procesadores 80386 y posteriores permiten el uso de un registro ampliado de 32 bits, el ESI. SI se usa como puntero. Su nombre proviene de Source Index, y se usa principalmente con instrucciones de cadena:

CLD MOV AX,0 MOV DS,AX MOV SI,20 LODSB

Page 5: Registros del procesador 01

Carga en AX el valor de la posición 20 de memoria. SI se incrementa en una unidad. En combinación con LOOP permite leer posiciones sucesivas de memoria.

Registro DI: El registro índice destino también es requerido por algunas operaciones con cadenas de caracteres. En este contexto, el DI esta asociado con el registro ES. Los procesadores 80386 y posteriores permiten el uso de un registro ampliado de 32 bits, el EDI. DI también se usa como puntero. Permite escribir en posiciones sucesivas de memoria cuando se usa con instrucciones de cadena:

CLD MOV DX,0 MOV ES,DX MOV DI,2048 STOSB

Escribe el contenido de AL en 0000:2048. Mientras que DI usa a ES como segmento, SI usa a DS.(Nota: STOSW y el trabajo STOSD de la misma manera, pero que almacenan la palabra en AX o la palabra doble en EAX en lugar del byte en AL, y el incremento o decremento de los registros de direccionamiento de 2 o 4 en vez de 1.)

Registro de Banderas De los 16 bits del registro de banderas, nueve son comunes a toda la familia de procesadores 8086, y sirven para indicar el estado actual de la maquina y el resultado del procesamiento. Muchas instrucciones que piden comparaciones y aritmética cambian el estado de las banderas, algunas cuyas instrucciones pueden realizar pruebas para determinar la acción subsecuente. En resumen, los bits de las banderas comunes son como sigue:

OF (Overflow, desbordamiento): Indica desbordamiento de un bit de orden alto (mas a la izquierda) después de una operación aritmética.

DF (dirección): Designa la dirección hacia la izquierda o hacia la derecha para mover o comparar cadenas de caracteres.

IF (interrupción): Indica que una interrupción externa, como la entrada desde el teclado, sea procesada o ignorada.

TF (trampa): Permite la operación del procesador en modo de un paso. Los programas depuradores, como el DEBUG, activan esta bandera de manera que usted pueda avanzar en la ejecución de una sola instrucción a un tiempo, para examinar el efecto de esa instrucción sobre los registros de memoria. SF (signo): Contiene el signo resultante de una operación aritmética (0 = positivo y 1 = negativo).

Page 6: Registros del procesador 01

ZF (cero): Indica el resultado de una operación aritmética o de comparación (0 = resultado diferente de cero y 1 = resultado igual a cero).

AF (acarreo auxiliar): Contiene un acarreo externo del bit 3 en un dato de 8 bits para aritmética especializada. PF (paridad): Indica paridad par o impar de una operación en datos de 8 bits de bajo orden (mas a la derecha). CF (acarreo): Contiene el acarreo de orden mas alto (mas a la izquierda) después de una operación aritmética; también lleva el contenido del ultimo bit en una operación de corrimiento o de rotación. Las banderas están en el registro de banderas en las siguientes posiciones:

Registros de PILA La pila es un área de memoria importante y por ello tiene, en vez de uno, dos registros que se usan como desplazamiento (offset) para apuntar a su contenido. Se usan como complemento al registro y son:

SP- Stack Pointer: Se traduce como puntero de pila y es el que se reserva el procesador para uso propio en instrucciones de manipulado de pila. Por lo general, el programador no debe alterar su contenido.

BP- Base pointer: Se usa como registro auxiliar. El programador puede usarlo para su provecho.

Claro que estos nombres y tipos de registros son estándar, ya que cada fabricante puede utilizar otros registro que reemplacen a estos o los auxilien, aun así, los fabricantes que usan otros registro tienen la misma función que los anteriormente mencionados

Page 7: Registros del procesador 01

Ejemplo

Registros de uso general del 8086/8088:

Tienen 16 bits cada uno y son ocho:

1. AX = Registro acumulador, dividido en AH y AL (8 bits cada uno). Usándolo se produce (en general) una instrucción que ocupa un byte menos que si se utilizaran otros registros de uso general. Su parte más baja, AL, también tiene esta propiedad. El último registro mencionado es el equivalente al acumulador de los procesadores anteriores (8080 y 8085). Además hay instrucciones como DAA; DAS; AAA; AAS; AAM; AAD; LAHF; SAHF; CBW; IN y OUT que trabajan con AX o con uno de sus dos bytes (AH o AL). También se utiliza este registro (junto con DX a veces) en multiplicaciones y divisiones.

2. BX = Registro base, dividido en BH y BL. Es el registro base de propósito similar (se usa para direccionamiento indirecto) y es una versión más potente del par de registros HL de los procesadores anteriores.

3. CX = Registro contador, dividido en CH y CL. Se utiliza como contador en bucles (instrucción LOOP), en operaciones con cadenas (usando el prefijo REP) y en desplazamientos y rotaciones (usando el registro CL en los dos últimos casos).

4. DX = Registro de datos, dividido en DH y DL. Se utiliza junto con el registro AX en multiplicaciones y divisiones, en la instrucción CWD y en IN y OUT para direccionamiento indirecto de puertos (el registro DX indica el número de puerto de entrada/salida).

5. SP = Puntero de pila (no se puede subdividir). Aunque es un registro de uso general, debe utilizarse sólo como puntero de pila, la cual sirve para almacenar las direcciones de retorno de subrutinas y los datos temporarios (mediante las instrucciones PUSH y POP). Al introducir (push) un valor en la pila a este registro se le resta dos, mientras que al extraer (pop) un valor de la pila este a registro se le suma dos.

6. BP = Puntero base (no se puede subdividir). Generalmente se utiliza para realizar direccionamiento indirecto dentro de la pila.

7. SI = Puntero índice (no se puede subdividir). Sirve como puntero fuente para las operaciones con cadenas. También sirve para realizar direccionamiento indirecto.

8. DI = Puntero destino (no se puede subdividir). Sirve como puntero destino para las operaciones con cadenas. También sirve para realizar direccionamiento indirecto.

Cualquiera de estos registros puede utilizarse como fuente o destino en operaciones aritméticas y lógicas

Indicadores (flags)

Page 8: Registros del procesador 01

Hay nueve indicadores de un bit en este registro de 16 bits. Los cuatro bits más significativos están indefinidos, mientras que hay tres bits con valores determinados: los bits 5 y 3 siempre valen cero y el bit 1 siempre vale uno (esto también ocurría en los procesadores anteriores).

CF (Carry Flag, bit 0): Si vale 1, indica que hubo "arrastre" (en caso de suma) hacia, o "préstamo" (en caso de resta) desde el bit de orden más significativo del resultado. Este indicador es usado por instrucciones que suman o restan números que ocupan varios bytes. Las instrucciones de rotación pueden aislar un bit de la memoria o de un registro poniéndolo en el CF.

PF (Parity Flag, bit 2): Si vale uno, el resultado tiene paridad par, es decir, un número par de bits a 1. Este indicador se puede utilizar para detectar errores en transmisiones.

AF (Auxiliary carry Flag, bit 4): Si vale 1, indica que hubo "arrastre" o "préstamo" del nibble (cuatro bits) menos significativo al nibble más significativo. Este indicador se usa con las instrucciones de ajuste decimal.

ZF (Zero Flag, bit 6): Si este indicador vale 1, el resultado de la operación es cero.

SF (Sign Flag, bit 7): Refleja el bit más significativo del resultado. Como los números negativos se representan en la notación de complemento a dos, este bit representa el signo: 0 si es positivo, 1 si es negativo.

TF (Trap Flag, bit 8): Si vale 1, el procesador está en modo paso a paso. En este modo, la CPU automáticamente genera una interrupción interna después de cada instrucción, permitiendo inspeccionar los resultados del programa a medida que se ejecuta instrucción por instrucción.

IF (Interrupt Flag, bit 9): Si vale 1, la CPU reconoce pedidos de interrupción externas enmascarables (por el pin INTR). Si vale 0, no se reconocen tales interrupciones. Las interrupciones no enmascarables y las internas siempre se reconocen independientemente del valor de IF. DF (Direction Flag, bit 10): Si vale 1, las instrucciones con cadenas sufrirán "auto-decremento", esto es, se procesarán las cadenas desde las direcciones más altas de memoria hacia las más bajas. Si vale 0, habrá "auto-incremento", lo que quiere decir que las cadenas se procesarán de "izquierda a derecha".

OF (Overflow flag, bit 11): Si vale 1, hubo un desborde en una operación aritmética con signo, esto es, un dígito significativo se perdió debido a que tamaño del resultado es mayor que el tamaño del destino.

Page 9: Registros del procesador 01

Registros de datos AX BX CX DX

Punteros de pila SP BP

Registros índice DI SI

Registros de segmento CS DS ES SS

Registro de flags

Los registros de datos, como su nombre indica, contienen generalmente datos.

AX es a menudo llamado acumulador, más por motivos históricos que por otra cosa.BX se puede usar como registro base en algunos modos de direccionamiento, es decir, para apuntar a posiciones de memoria con él.CX es usado por algunas instrucciones como contador (en ciclos, rotaciones..)DX o registro de datos; a veces se usa junto con AX en esas instrucciones especiales mencionadas.

Cada registro de estos está dividido a su vez en dos registros de 8 bits, que pueden ser leídos o escrito de manera independiente:

AX = AH | AL BX = BH | BLCX = CH | CL DX = DH | DL

Page 10: Registros del procesador 01

Si AX contiene 00FFh, AH=00h (su parte alta) y AL=FFh (su parte baja); si lo incrementamos en 1, AX pasa a valer 0100h (lógicamente), y con ello AH=01h, AL=00h. Si en lugar de incrementar en 1 AX lo hacemos con AL (byte inferior), AH se quedará como estaba y AL será FFh+01h=00h, es decir, AX=0000h (vamos, que cuando se manipula una parte del registro la otra no se ve afectada en absoluto) Ah, por si alguno lo dudaba, H viene de high y L de low.

Uno puede mover los datos de unos registros a otros con prácticamente total libertad. También podremos realizar operaciones sobre ellos, como sumar el contenido de BX y DX para guardar el resultado en DX, y cosas así. La primera restricción al respecto (y bastante razonable) es que los operandos tendrán que ser del mismo tamaño (no podremos sumar BX con DH, por ejemplo).

Para explicar los registros que hacen referencia a memoria hay que contar brevemente qué es la segmentación.

Uno puede pensar que lo lógico y maravilloso para apuntar a una dirección de memoria es colocar dicha dirección en un registro,. Eso es muy bien para registros grandes pero da la casualidad de que con 16 bits tenemos 2^16=64k posiciones. Hombre, en aquellos tiempos estaba muy bien para según qué cosas, y aquí tampoco vamos a manejar mucha más memoria, pero tampoco es plan. La solución por la que optó Intel fue usar dos registros de 16 bits (cosa que seguramente ya imaginabas), pero no dispuestos consecutivamente, como podría pensarse:

Segmento: Desplazamiento:

xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx <- Dirección de 32 bits

De esta manera -que, repito, no es la que se usa realmente- se podrían recorrer 2^32 posiciones de memoria. Con el registro llamado de segmento apuntamos al "bloque", esto es, las líneas de mayor peso, y con el de desplazamiento nos movemos dentro de 64k. El problema reside en que si nuestra estructura de datos se encuentra al final de uno de estos bloques (un vector, por ejemplo), y queremos recorrerla linealmente, lo podremos hacer así solamente hasta llegar a la posición FFFFh del segmento apuntado, pues para seguir avanzando es necesario incrementar el registro de segmento en 1 llegados a ese punto (y continuar ya normalmente incrementando el desplazamiento desde 0000h). Resulta que una característica más que deseable -por no decir imprescindible- de un programa es que sea reubicable, es decir, que lo podamos cargar en cualquier zona de la memoria, principalmente porque el sistema operativo nos lo coloca donde puede, y cada vez en un sitio distinto.

Intel dispuso los registros de la siguiente manera:

Segmento: Xxxxxxxxxxxxxxxx0000+Desplazamiento (u offset) 0000xxxxxxxxxxxxxxxx

-----------------------------------Dirección de 20 bits xxxxxxxxxxxxxxxxxxxx

Así pues para obtener la dirección real se multiplica el registro de segmento por 16, y se suma al de desplazamiento (esto lógicamente no lo tenemos que hacer nosotros, hay un circuitillo por ahí para

Page 11: Registros del procesador 01

eso) Existen además parejas segmento-offset que apuntan a la misma posición de memoria (no podría ser de otro modo, si estamos recorriendo 2^20 posiciones con 32 bits). De la manera propuesta ahora, cuando queremos manejar una estructura de no más de 64k (esto nos lo limitan los registros que son de 16 bits, con lo que no hay más vuelta de hoja), podremos apuntar con el registro de desplazamiento al bloque donde lo ubicaremos (alineado en un múltiplo de 16 bytes, claro) y nos moveremos por dentro de este segmento alterando el offset.

Recordemos además que todo procesador de esta familia que funcione en modo real (o virtual) se comporta como un 8086 más o menos rápido en cuanto a direccionamiento de memoria, por lo que bajo MSDOS siempre estaremos limitados de esta manera.

De la suma de segmento y offset puede suceder que, para segmentos altos, exista un bit de carry a 1. Los 286 y superiores pueden aprovechar esto para acceder a la llamada "memoria alta", 64k situados por encima de los 2^20=1024k iniciales. No será nuestro caso, pues nos limitaremos a manejar la memoria a la vieja usanza. De hecho únicamente poblaremos los primeros 640k (la famosa memoria convencional) pues en las posiciones de los segmentos A000h y superiores se mapea la memoria de vídeo, la expandida... Pero bueno, de momento con 640k vamos sobrados.

Ahora casi todos los registros cobran ya sentido; los registros de segmento apuntan al segmento, y los de índice indican el desplazamiento dentro del segmento. Los registros de índice se pueden usar como registros de datos sin problemas para sumas, movimiento de datos... no así los de segmento, que tienen fuertes limitaciones. Cuando se diga "un registro" como operando de una instrucción, eso incluye en principio cualquier registro menos los de segmento.

El par CS:IP indica la dirección de memoria donde está la instrucción que se ejecuta. Los nombres vienen de Code Segment e Instruction Pointer. A esta parejita sólo la modifican las instrucciones de salto, así que podemos olvidarnos -un poco- de ella. Cada vez que se ejecuta una instrucción, el contador IP se incrementa para apuntar al código de la operación siguiente; las instrucciones de salto cargan CS:IP con la dirección adonde queremos saltar, para que se ejecute el código a partir de ahí.

SS:SP apuntan a la pila. Como en todo micro que se precie, tenemos una pila adonde echar los valores de los registros que queremos preservar para luego, las direcciones de retorno de las subrutinas. La pila crece hacia abajo, es decir, cuando metemos algo en la pila el puntero de pila se decrementa, y cuando lo sacamos se incrementa. Siempre se meten valores de 16 bits. Significan Stack Segment y Stack Pointer, claro. Por lo general SS no se toca, y SP quizá pero poquito, ya que hay instrucciones específicas para manejar la pila que alteran SP indirectamente. Digamos que uno dice "tiro esto a la pila" o "saco lo primero que haya en la pila y lo meto aquí" y el micro modifica SP en consecuencia. BP es un puntero Base, para indicar también desplazamiento, que se usa en algunos modos de direccionamiento y especialmente cuando se manejan subrutinas. La pila se estudiará en mayor profundidad en el tema VI.

DS y ES son registros de segmento adicionales, el primero llamado de datos (Data) y el segundo Extra. Con ellos apuntaremos a los segmentos donde tengamos nuestros datos (ya que del código se encarga CS), esto es, nuestras variables. Estos los manipularemos mucho más que los anteriores cuando programemos en modo real.

DI y SI son registros índice, es decir, sirven para indicar el offset dentro de un segmento. Acabarás harto de tanto usarlos. En las instrucciones de cadena DI se asocia por defecto a DS, y SI a ES.

Page 12: Registros del procesador 01

Aunque el sistema de segmentación pueda parecer muy engorroso (bueno, es que a este nivel realmente lo es, y mucho) en realidad es vital. El modo protegido del 386+ (386+ por "386 y superiores") emplea segmentación, pero aprovechando 32 bits. En entornos multitarea hay que estructurar cada programa con su(s) bloque(s) de código y de memoria, cada uno con su nivel de acceso (por ejemplo si estás guarreando con la memoria te interesa que sólo enredes con la de tu programa, para no sobreescribir otros procesos en curso por accidente, o parte del sistema operativo incluso); lo que sucede es que ahora es una mierda porque esta segmentación es muy limitada. Sirva esto para evitar la cantinela segmentación=mala que le puede haber pasado a uno por la cabeza a estas alturas de película. Tras este pequeño paréntesis, sigamos.

El registro de flags está formado por varios bits cada uno con significado propio, que son modificados por las operaciones que realizamos:

Bit 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

Flag -- -- -- -- OF DF IF TF SF ZF -- AF -- PF -- CF

Aunque es un registro de 16 bits sólo algunos de ellos tienen significado. Los otros adquieren valores indeterminados, y se dice que son bits reservados; un programa no debe tocarlos, pues aunque un equipo dado puede que no los use, otros micros podrían manipularlos internamente, con resultados impredecibles.

CF Carry Flag o indicador de acarreo. Normalmente indica si "nos llevamos algo" despues de haber sumado o restado.

OF Overflow Flag o indicador de desbordamiento. Si después de una operación el resultado no cabe en el tamaño del registro, se pone a 1.

ZF Zero Flag o indicador de cero. Si el resultado da 0 se pone a 1.

SF Sign Flag o indicador de signo. Si el resultado es negativo se pone a 1.

PF Parity Flag o indicador de paridad. Con algunas operaciones lógicas o aritméticas se pone a 1 si el resultado es par.

AF Auxiliary Flag o indicador auxiliar. Se usa para operaciones BCD (si es que éstas valen para algo)

DF Direction Flag o indicador de dirección. Se usa en operaciones llamadas "de cadena", indicando el sentido (ascendente o descendente) en que se recorre la memoria. (Este flag es más divertido de lo que parece.)

IF Interrupt Flag o indicador de interrupciones. Cuando se pone a 1 se permiten las interrupciones, a 0 se ignoran; se dice que se enmascaran. Hay no obstante algunas muy especiales que pasan del flag; por ejemplo, si arrancas (físicamente, me refiero; coger con la mano y zás!) una tarjeta de RAM con el trasto encendido, la interrupción que salta -alerta roja, inmersión, inmersión, auuuuu- pasa de este flag olímpicamente (algo así no se puede pasar por alto bajo ninguna circunstancia).

TF Trap Flag o indicador de trampa (para ejecución paso a paso, como en los depuradores; podemos olvidarnos de él)

Page 13: Registros del procesador 01

No conviene aturullarse demasiado a cuenta de los flags, pues a medida que se vayan viendo las instrucciones que los usen se irán comentando con más calma. Resumen: es un registro que contiene 1) indicadores de los resultados de algunas operaciones y 2) modificadores del comportamiento del procesador.

- Bueno, vale, tengo un 386

Y con 386 incluyo el 486, Pentium, K5, K6.. Salvando las pijaditas añadidas, funcionan todos más o menos igual (a nivel de código máquina, claro).

Ahora los registros de datos son EAX,EBX,ECX,EDX funcionando de manera idéntica a los anteriores, sólo que de 32 bits. Si queremos acceder a la parte baja de 16 bits, nos referiremos normalmente a AX,BX.. y si queremos hacer lo propio con las dos partes que componen la parte baja de 16 bits, hablaremos de AH,AL,BH.. todo exactamente igual. Se añaden además registros de segmento adicionales (de 16 bits, como los otros), FS y GS. De igual manera se extienden a 32 bits BP (a EBP), DI (a EDI) y SI (a ESI). Llamando a unos u otros modificaremos los 16 bits inferiores, o los 32 bits del registro completo. Cuando trabajemos en modo real, los segmentos de 64k nos limitarán el valor de offset a 65535; esto significa que si nos empeñamos en usar los registros extendidos en MSDOS, tendremos que asegurarnos de que la parte alta (los 16 bits superiores) esté a 0.

Registros de datos EAX EBX ECX EDX

Punteros de pila ESP EBP

Registros índice EDI ESI

Registros de segmento CS DS ES FS GS SS

Registro de flags

En modo protegido (windows/unix) los registros que indiquen offset podrán tomar cualquier valor, siempre que el par segmento:offset apunte a la zona de nuestro programa. De este modo con un mismo registro de segmento podremos, teóricamente, modificando solamente el offset, recorrer 4Gb de memoria respecto a la dirección base del segmento.

Además, y esto es especialmente importante, la dirección efectiva de CS:EIP, por ejemplo, ya no se calcula como 16*CS+EIP. Ahora el registro de segmento no indica una posición de memoria múltiplo de 16, sino el índice dentro de una tabla (conocida como tabla de descriptores de segmento) donde está contenida toda la información de los segmentos, como cuánto ocupan, quién tiene permiso de acceso, qué tipo de permiso... La dirección base de ese segmento, será una dirección de, posiblemente, 32 bits, que a nosotros de momento no nos incumbe. El sistema te ubicará el segmento de código (y con segmento me refiero a ese bloque de memoria con sus permisos, etc) en una posición cualquiera de memoria y le asignará un número correspondiente a un elemento de esa tabla, que guardará en CS. Cuando nos queramos referir a él usaremos el valor de CS con que nuestro programa ha arrancado. Lo mismo sucederá para los datos y la pila. Como los segmentos pueden ser de hasta 4Gb, código, datos y pila irán cada uno en un segmento, de modo que nuestro programa no

Page 14: Registros del procesador 01

tendrá que modificar los registros de segmento para nada. No es así en MSDOS, que siendo de 64k, es frecuente tener que repartir el código y los datos entre varios segmentos.