Microprocesadores

Informática. Computación. Hardware. Componentes del ordenador. Procesador 8086. Características. Instrucciones. Ensambaldor

  • Enviado por: Eduardo Crespo
  • Idioma: castellano
  • País: España España
  • 101 páginas
publicidad

TEMA 1. CARACTERÍSTICAS DEL 8086.

ORGANIZACIÓN DE LA MEMORIA.

ALU de 16 bits.

En el 8086 tenemos DBUS de 16 bits.

Celdillas de memoria de 8 bits.

No se emplean celdillas de memoria de 16 bits debido a que:

  • Una CPU no puede acceder directamente a media celdilla, sino que debe acceder como mínimo a una celdilla completa.

  • Es conveniente para muchas cosas trabajar byte a byte, por ejemplo con caracteres ASCII (8 bits).

  • Si las celdillas fuesen de distinto tamaño en distintos micros debido a que estos tienen DBUSes de diferente tamaño, sería problemático, pues cada uno direccionaría de una forma diferente.

Fig. 1 Esquema de buses del 8086.

Memoria Direcciones Pares

A0 D0-D7

A1-A19

D8-D15

Decodificador

Direcciones Memoria Direcciones Impares

BHE

D0-D15

A0-A19 = Líneas del ABUS (Bus de Direcciones)

D0-D15 = Líneas del DBUS (Bus de Datos)

BHE = Byte High Enable

Ej: Llega al bus de direcciones una dirección PAR: 8 4 A 7 C h 1000 0100 1010 0111 1100

Siguiente dirección IMPAR: 8 4 A 7 D h 1000 0100 1010 0111 1101

Se diferencian en A0

La señal A0 del ABUS va por otro cable (no por el que van las señales A1 - A15) debido a que un número par y su siguiente sólo se diferencian en ese A0.

Posibilidades:

Dirección A0 BHE Situación.

PAR

(A0=0)

0

0

Se accede a WORD (16 bits):

Dirección PAR por D0-D7

Siguiente dirección (IMPAR) por D8-D15

0

1

Se accede a BYTE (8 bits):

Dirección PAR por D0-D7

{La siguiente dirección (IMPAR) no produce señal pues la puerta triestado lo impide.}

IMPAR

(A0=1)

1

0

Acceso a BYTE (8 bits):

Dirección IMPAR por D8-D15

1

1

NO SE USA (se inhabilitan las 2 puertas triestado).

TIPOS DE DATOS.

Enteros Sin Signo

Binario Natural:

Tamaños BYTE, WORD y DOUBLE WORD

BCD 8421

Empaquetado (Tamaño Byte)

Desempaquetado (Tamaño Byte)

Enteros Con Signo

Convenio de CA2

Tamaños BYTE, WORD y DOUBLE WORD.

BYTE 8 bits

WORD 16 bits

DWORD 32 bits

BCD Empaquetado: 1000 1010

8 5 (85 decimal)

BCD Desempaquetado: x x x x 0 1 1 0

Sin significado Cifra BCD (6 en decimal)

El BCD desempaquetado, que a priori parece poco efectivo, sirve p.e. cuando tenemos un código alfanumérico (ASCII, EBCDIC...), puede surgir la cuestión: el código 0 ASCII, tiene el valor 30h, el 1 ASCII tiene el 31h, etc...

ASCII

0 0011 0000

  • 0011 0001

...

... 0011 1001

Es una manera de que el micro haga operaciones directamente con valores ASCII.

PARTICULARIDADES:

  • Solapamientos: Diferentes direcciones lógicas pueden apuntar a la misma dirección física.

Ej:

348Ah : 5FDEh = 3A87Eh

3A87h : 000Eh = 3A87Eh

3A80h : 007Eh = 3A87Eh

Dirección Lógica Dirección Física

  • El Segmento es un valor que no puede especificarse de manera directa en una instrucción, sino que debe hacerse mediante los REGISTROS DE SEGMENTO (el segmento debe estar previamente colocado en un registro de segmento).

  • Cuando un offset se desborda (pasa de FFFFh al siguiente), pasa a la primera posición del mismo segmento (0000h), es decir, es cíclico. El acarreo del offset no modifica el segmento.

  • Si tengo un segmento que empieza casi al final de la memoria (es decir, queda menos de 64 KB), el segmento continuaría al principio de la memoria.

ALINEAMIENTO DE DATOS E INSTRUCCIONES.

Para leer una WORD que empiece en dirección par, comienza en esa dirección par y lee 2 bytes (un word) de una vez.

Para leer una WORD que empiece en dirección impar, lee los 2 bytes en 2 veces, primero un byte y luego el siguiente.

Si el WORD comienza en dirección par, se dice que está ALINEADA a word:

84A7Ch Par WORD Alineada

84A7Dh Impar

Si el WORD comienza en posición impar, no está alineada:

84A7Dh Impar WORD No Alineada

84A7Eh Par

DIRECCIONES DE MEMORIA.

Dirección Física: La que usa el Hardware (número de 20 bits que circula por el ABUS, que va desde

el 00000h hasta el FFFFFh).

Dirección Lógica: La que se maneja desde el programa. En el programa, para referenciar una posición

de memoria física, lo haremos mediante la técnica de Segmentación, usando para ello dos números de 16 bits: segmento y offset.

Segmentación:

Segment : Offset

Tanto el Segmento como el Offset son números de 16 bits que nos sirven para realizar una transformación de direcciones:

DIR_FISICA = ( 16*Segmento + Offset )

10h

Ej:

Dir. Lógica 348Ah : 5FDEh

Dir. Lógica Dir. Física

10h*348Ah = 348A0h 348Ah : 5FDEh 3A87Eh

5FDEh = 5FDEh

3A87Eh Dir. Física

Segmento:

Una dirección de segmento indica un área de memoria de 64 KB (Segmento de memoria), que comienza en la dirección física 10h*Segmento (es decir, 16d*Segmento).

Advertencia: Segmento de memoria < > Segmento de ensamblador.

Offset:

El Offset es la dirección relativa (desplazamiento) con relación al principio del Segmento.

Ej:

Memoria

0000h : 0000h

Offset

348Ah : 0000h = 348A0h 0000h

Segmento ...

de 64 KB

Memoria ...

348Ah : FFFFh = 348Ah + FFFFh FFFFh

FFFFh : FFFFh

REGISTROS DEL PROCESADOR 8086.

GENERALES:

Son cuatro registros que se denominan AX, BX, CX y DX. Cada uno de estos registros se subdivide además en dos registros de tipo byte, que se denominan con la misma letra que el registro completo pero terminada en H si se refiere al byte superior o HIGH (8 bits más significativos del registro) o en L si se refiere al byte inferior o LOW (los 8 bits menos significativos). Así pues, si hay un dato de tipo word almacenado en el registro AX, es posible acceder a su byte superior mediante el registro AH y al inferior a través de AL. Los otros tres registros también cuentan con esta propiedad, por lo que existe un BL y BH, CL y CH y DL y DH.

El registro AX (Acumulador) es utilizado por algunas operaciones aritméticas como origen o destino de los datos de forma implícita, es decir, que siempre utilizan este registro y no hay posibilidad de cambiarlo por otro.

El registro BX (Base) se utiliza en algunos modos de direccionamiento para formar la dirección de memoria de la que obtiene o en la que almacena los datos una determinada instrucción.

El registro CX (Contador) se utiliza con las instrucciones de repetición y de bucle, almacenando el número de veces que se repetirá una determinada instrucción o fragmento de programa.

El registro DX (Datos) se combina con AX en algunas instrucciones que manejan cantidades de 32 bits (DX&AX) y especifica la dirección de un puerto de entrada/salida.

INDICES:

Su principal finalidad es la de almacenar la posición de memoria donde se encuentra algún dato necesario para las instrucciones del programa. Los registros índices son SI y DI.

Los registros SI (Source Index) y DI (Destination Index) se utilizan como índices en los fragmentos de programa que necesitan acceder a varias posiciones consecutivas de memoria. SI es utilizado por algunas instrucciones como el origen de los datos que necesita, mientras que DI de utiliza como destino de los resultados que se producen.

DE PILA:

El registro SP (Stack Pointer, Puntero de Pila) contiene el puntero de la pila, apuntando (almacenando la dirección de memoria) donde se guardará el siguiente dato en la pila.

El registro BP (Base Pointer) es un registro especialmente diseñado para realizar lecturas/escrituras en la Pila.

Hay una forma de pasar parámetros a un procedimiento a través de la Pila:

  • Colocamos en la Pila los datos a pasar.

  • Apuntamos con BP al primer elemento.

  • Leemos a partir de BP los elementos deseados.

  • De esta forma nos ahorramos tener que hacer múltiples PUSH y POP.

    Si al direccionar, alguno de los registros implicados es BP, el micro autodetecta que queremos acceder a la zona de la Pila.

    Si no ponemos BP, el segmento por defecto sería el especificado anteriormente (DS o SS). Ejemplo:

    MOV AL , [BX-18h] [DS : BX-18h]AL

    LODSB [DS : SI]AL ; SI++ ó SI -

    MOV [DI],AX AX[DS : DI]

    STOSB AL[ES : DI]

    MOV AL,[BP+DI-428Ah] [SS : BP+DI-428Ah]AL

    MOV BP,[384Ah] [DS : 384Ah]BP

    Se usa DS porque BP no está dentro del direcionamiento

    PUNTERO DE INSTRUCCIÓN:

    El registro IP (Instruction Pointer) contiene el offset del contador de programa, es decir, cuando el procesador necesita una nueva instrucción de programa, la obtiene de la dirección indicada por el registro IP, que contiene el desplazamiento dentro del segmento apuntado por el registro CS desde donde se leerá dicha instrucción. Al igual que sucedía con el registro CS, éste sólo puede modificarse mediante las instrucciones de transferencia de control.

    DE SEGMENTO:

    Una posición de memoria queda determinada por una dirección de segmento y un desplazamiento relativo a dicho segmento denominado offset, donde el segmento se encuentra contenido en unos registros especiales denominados “de segmento”.

    Cuando una instrucción hace referencia a una posición de memoria, ésta sólo especifica el offset de dicha posición, mientras que el segmento en que está contenida se obtiene de uno de los registros de segmento. Existen cuatro registros de este tipo, de 16 bits cada uno, que reciben el nombre de CS, DS, ES y DS.

    Memoria

    • CS = Code Segment Para código (instrucciones)

    • DS = Data Segment Para Datos (constantes, variables,...) Código CS

    • SS = Stack Segment Para la Pila

    • ES = Extra Segment Para Datos Extra

    No existe limitación alguna para tener varios segmentos de código, Datos DS

    datos y pila, lo único necesario es cambiar la dirección de inicio de

    los segmentos en el registro adecuado. La limitación es que en un

    determinado instante, el micro sólo puede “ver” 4 segmentos Pila SS

    (CS,DS,SS,ES), pues cada registro de segmento referencia

    únicamente a un segmento de 64 KB. Así pues, podemos tener,

    por ejemplo dos (o más) segmentos de código, y para acceder a

    uno u otro, cambiaremos el valor del registro CS para que apunte al Datos Extra ES

    comienzo del segmento deseado.

    Registro CS (Code Segment): apunta siempre al segmento donde se encuentra la instrucción que se está ejecutando. Este registro no se puede modificar directamente y debe hacerse mediante las denominadas “instrucciones de transferencia de control”.

    Registro DS (Data Segment): apunta al segmento de memoria donde las instrucciones leen los datos o los almacenan. Este registro puede cambiarse durante la ejecución del programa para así poder acceder a toda la memoria instalada en el sistema.

    Registro ES (Extra Segment): indica una zona de memoria para datos adicional.

    Registro SS (Stack Segment): apunta al segmento de memoria donde se encuentra la pila del procesador.

    Cuando una instrucción necesita leer o escribir un dato en memoria, lo hace por defecto en el segmento apuntado por DS, aunque este funcionamiento puede variarse de forma que la instrucción obtenga el dato de cualquiera de los otros tres segmentos indicándolo de forma explícita en la instrucción, mediante los denominados “prefijos de segmento”, que veremos más adelante.

    FLAGS:

    El registro de banderas o flags (PSW, Program Status Word) se utiliza para indicar al programa ciertas condiciones que han tenido lugar como resultado de la última operación indicada. Cada uno de los bits del registro de banderas marca si se ha producido una de estas condiciones: 1 si se produjo o 0 si no tuvo lugar.

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

    OF

    DF

    IF

    TF

    SF

    ZF

    AF

    PF

    CF

    Las banderas contenidas en este registro son las siguientes:

    Flags Aritméticos:(0 , 2, 4, 6, 7 y 11):

    CF (Carry Flag): Flag de acarreo en operaciones aritméticas. Toma el valor 1 si en la última operación de suma o de resta se produjo acarreo (o borrow en restas).

    PF (Parity Flag): Flag de paridad. Toma el valor 1 cuando el resultado de la última operación tiene un número par de bits a uno.

    AF Auxiliary Flag): Flag auxiliar. Es un tipo de acarreo especial que se utiliza para indicar un acarreo entre las cifras de un número en formato BCD.

    ZF (Zero Flag): Flag de cero. Adopta el valor 1 en caso de que la última operación haya tenido un resultado igual a cero.

    SF (Sign Flag): Flag de signo. Indica el signo de la última operación:

    0 +

    1 -

    OF (Overflow Flag): Flag de desbordamiento. Cualquier operación que provoque un resultado que no quepa en el destino (desbordamiento) pondrá este indicador a 1.

    Flags Software: (8, 9 y 10) (Modificables mediante instrucciones software):

    DF (Direction Flag): Flag de dirección. Si tiene el valor 0, los punteros en instrucciones de proceso de cadenas se incrementan , y si tiene el valor 1 dichos punteros se irán decrementando.

    IF (Interrupt Flag): Flag de interrupciones. Cuando se coloca el valor 0 en esta bandera, el procesador ignora las peticiones de interrupción que le hagan los dispositivos externos. Esto es útil para proteger secciones críticas del código que podrían dejar el sistema en estado inestable en caso de que se produjese una interrupción durante su ejecución.

    TF (Trap Flag): Flag de paso a paso. Si éste flag tiene el valor 1, entonces el procesador genera una interrupción interna por cada instrucción que se ejecuta, posibilitando así a un programa de depuración el seguir el transcurso de un programa paso a paso.

    PREFIJOS.

    Un Prefijo es un byte que se coloca delante de una instrucción ensamblada (código máquina) y que modifica la ejecución de dicha instrucción. No todos los prefijos pueden ir con todas las instrucciones.

    Instrucción ensamblada.

    Byte de Prefijo

    TIPOS DE PREFIJOS:

    De Bloqueo LOCK Instrucción

    SEG RegSeg Instrucción

    De Segmento ó

    RegSeg: delante del operando en memoria.

    REP Instrucción.

    REPE Instrucción.

    De Repetición REPZ Instrucción.

    REPNE Instrucción.

    REPNZ Instrucción.

    PREFIJO DE BLOQUEO.

    Supongamos lo siguiente:

    Proceso 1 Zona de memoria común.

    Proceso 2

    Para que un proceso no modifique los datos del otro proceso, se emplea una variable semáforo (es decir, que puede tomos dos valores). Si cada proceso accede a la tabla (memoria común) de la siguiente manera, aparentemente el acceso funciona (aunque, como veremos, no es así):

    R V

    Semáforo

    Rojo Semáforo

    Accesos

    Verde Semáforo

    El trozo de código dentro del óvalo debe ser una sola instrucción para que en caso de cambio de tarea, no quede a la mitad de su ejecución. Para ello se emplea la instrucción genérica Test&Set, que comprueba el semáforo y lo establece a un determinado valor.

    Sin embargo este planteamiento puede dar problemas. El microprocesador asigna siempre una Time Slice (rodaja o porción de tiempo) a cada proceso (para que un mismo proceso no monopolice el uso del micro) para su ejecución. Cuando acaba el tiempo de un proceso, se guardan sus datos y se asigna el micro al siguiente proceso. Para saber cuándo acaba cada porción de tiempo, suele haber un Timer (temporizador) que envía una señal de interrupción cada x tiempo al micro advirtiéndole que el Time Slice del proceso actual ha acabado (es decir, el cambio de tareas se detecta/efectúa a través de una interrupción). Cuando se recibe la interrupción, se termina de ejecutar la instrucción en curso y justo después se atiende a la interrupción (la instrucción en curso no puede quedar a medio ejecutar).

    En el 8086 no hay una instrucción específica de Test&Set, así que se emplea la instrucción XCHG, que realiza algo parecido.

    XCHG reg , memoria reg mem

    mem reg

    Para simular la instrucción Test&Set (que Intel decidió no incorporar al juego de instrucciones del 8086, la incorporó a partir del 386), en un 8086 habría que realizar el siguiente proceso:

    Rojo reg

    Micro 8086 Memoria

    XCHG reg , semáforo reg

    (memoria)

    R V

    reg ? reg. aux

    Accesos

    Verde Semáforo

    Supongamos ahora que tenemos dos o más CPUs 8086 con una cola de procesos. Una vez que un micro coge los buses, no los suelta hasta que acaba de ejecutar la/las instrucciones (las que dé tiempo en el Time Slice). Lo que hace <LOCK Instrucción> (nótese que LOCK va con una sóla instrucción) es precisamente blindar el proceso, para que no se permita cambiar de tarea hasta que la instrucción en curso no se haya terminado de ejecutar, impidiendo al otro micro el meterse por medio cuando el micro actual está ejecutando y tiene los buses bajo su control.

    LOCK es una instrucción que se utiliza en aplicaciones de recursos compartidos para asegurar que no accede simultáneamente a la memoria más de un procesador. Cuando una instrucción va precedida de LOCK, el procesador bloquea automáticamente el bus, introduciendo una señal por la patilla LOCK.

    La sintaxis de la instrucción Time&Set simulada es por tanto:

    LOCK XCHG reg, semáforo

    Cuando el procesador encuentra esa instrucción, pide los buses pero con bloqueo (el bloqueo del bus de acceso a memoria no desaparece hasta que se acaba de ejecutar la instrucción a la que modifica LOCK). Así se asegura que sólo un procesador acceda a la memoria en un determinado momento.

    PREFIJOS DE SEGMENTO.

    Indican al ensamblador que la dirección física de algún operando debe calcularse con algún registro de segmento (RegSeg) distinto al que se usa por defecto. Hay dos formas de indicarlo:

    Si los operandos son implícitos:

    Se coloca delante de la instrucción SEG RegSeg

    Ej:

  • SEG SS MOVSB

  • [SS : SI] [ES : DI] ; SI ± ±; DI ± ±

  • SEG DS STOSB

  • AL ES : DI; DI ± ± Incorrecta

    Si los operandos son explícitos:

    Se coloca delante del operando en memoria regseg :

    Ej:

  • MOV AL, ES : [BP+DI-18h]

  • [ES : BP+DI-18h] AL

  • MOV CS : [BX+1248h], AL

  • AL [CS : BX+1248h]

    PREFIJOS DE REPETICIÓN.

    Pueden usarse solamente en instrucciones de manipulación de Strings.

    Las instrucciones de manipulación de strings son las siguientes:

    LODSB [DS : SI]8 AL ; SI ±±

    LODSW [DS : SI]16 AL ; SI ±2 SI

    De Transferencia STOSB AL [ES : DI]8 ; DI ±±

    ( Prefijo REP ) STOSW AX [ES : DI]16 ; DI ±2 DI

    MOVSB [DS : SI]8 [ES : DI]8 ; SI±± ; DI ±±

    MOVSW [DS : SI]16 [ES : DI]16 ; SI± 2 SI ; DI± 2 DI

    SCASB AL - [ES : DI]8 Act.Flags ; DI ±±

    De Comparación SCASW AX - [ES : DI]16 Act.Flags ; DI ±2 DI

    (Prefijos ) CMPSB [DS : SI]8 - [ES : DI]8 Act.Flags ; SI±± ; DI ±±

    (REPE o REPZ) CMPSW [DS : SI]16- [ES : DI]16 Act.Flags ; SI±2 SI;DI ±2DI

    (REPNE o REPNZ)

    REP

    N S

    CX=0

    Ejecuta instrucción

    CX - - (no afecta a flags)

    REPE / REPZ REPNE / REPNZ

    N S N S

    CX=0 CX=0

    Ejecuta instrucción Ejecuta instrucción

    CX - - (no afecta a flags) CX - - (no afecta a flags)

    =1 =0 =0 =1

    Fz Fz

    INTERRUPCIONES Y EXCEPCIONES.

    La Tabla Vectorial de Interrupciones es una tabla de 256 entradas de 4 bytes cada una (256 punteros), por lo que su tamaño es de 1KB = 400H, situada justo al comienzo de la memoria del ordenador (0000h:0000h). Toda interrupción que se ejecute supone una ruptura con salto intersegmento (modifica el registro de segmento).

    Tipos de interrupciones: Interrupciones Hardware, Software, No Enmascarables y Excepciones.

    Interrupciones Hardware:

    Algunas veces, un dispositivo necesita llamar la atención del procesador para indicarle, por ejemplo, que tiene un dato disponible o que ha terminado de realizar la acción que se le había encargado .Este es el sistema utilizado, por ejemplo, por el teclado, el cual envía una interrupción al procesador cada vez que se pulsa una tecla, o también el utilizado por la unidad de disco para señalar que ha terminado de escribir los datos en el disquete. A este tipo de interrupciones también se les denomina externas, para diferenciarlas de las de tipo interno generadas por el propio procesador para indicar errores de tipo matemático o como ayuda a la depuración de programas.

    Interface

    IRQ0

    INT

    PIC Interface

    8086 INTA IRQ1

    . . . . . .

    IRQ7

    Interface

    Buses

    Vector de interrupción (número)

    Dado que el microprocesador es millones de veces más rápido que los periféricos, no es útil que esté preguntando a los periféricos y quede esperando respuesta (pérdida de tiempo). La misión del PIC (controlador de interrupciones) es multiplexar las señales de interrupción que vienen de los periféricos.

    Las interrupciones pueden ser enmascarables en función del flag de interrupción (Si FI = 1 no se atienden).

    El proceso de detección y atención a la interrupción es el siguiente:

    • Cuando llega una señal de interrupción al PIC, este le manda una señal INT (de petición de interrupción) al micro.

    • El micro finaliza la ejecución de la instrucción en curso.

    • Analiza el flag de interrupción:

    • Si es 1, continúa sin atender la señal (sigue atendiendo las instrucciones anteriores).

    • Si es 0, atiende a la interrupción y activa la señal INTA (INTerrupt Acknowledge).

    • El PIC detecta esta INTA y envía al DBUS el vector de interrupción (num. de 8 bits sin signo).

    • El micro recoge el vector del DBUS. {Ciclo de interrupción}

    • Se meten en la pila el PSW, CS e IP.

    • Se multiplica por 4 el vector y se lee de esa posición en la tabla de vectores.

    Si hay varias IRQ's pidiendo INT, el PIC elige, por un sistema de prioridades, que IRQ atender, pudiendo enmascarar una a una cualquiera de las IRQ's.

    El vector puede ser cualquiera entre 05h y FFh (inclusive).

    Interrupciones Software:

    Para poder acceder a diversas rutinas (rutinas DOS, BIOS o de usuario), se accede a través de interrupciones software. Para ello, se colocan en unos registros determinados los parámetros que necesita la subrutina y se llama a la interrupción correspondiente (mediante la instrucción “INT vector”). Una vez completado el proceso, la interrupción retornará devolviendo resultados en registros. Además, en los casos en que una misma interrupción ofrece varias rutinas, en el registro AH contiene un número identificativo de la función que se desea utilizar.

    Interrupciones No Enmascarables (NMI):

    • Son interrupciones hardware.

    • No les afecta el FI, por lo que se atienden siempre.

    • La señal de control es distinta NMI

    • En el caso del 8086 el único vector válido es el 02.

    • Suelen estar asociadas a interrupciones terminales.

    Excepciones:

    Son interrupciones que genera el propio micro durante la ejecución del programa cuando se produce una anomalía (por ejemplo un error aritmético, como división entre cero, que el micro no sabe tratar). Cada anomalía posible tiene asignado un determinado número de interrupción (nº de Excepción), y viene dado por el fabricante del procesador. Por ejemplo, en el 8086, la división entre cero provocará la Excepción 00h).

    ¿Cómo se atienden?

    Lo que nos ofrecen cualquiera de los tipos de interrupción es un vector (nº de 8 bits sin signo) a través del Bus de Datos. La forma de atender ese vector (que se obtendrá de una forma u otra dependiendo del tipo de interrupción) es la misma en cualquier caso. El proceso de atención a la interrupción es el siguiente:

  • Se guarda en la Pila (automáticamente) el PSW (Flags), el CS y el IP:

  • SP - 2 SP ; PSW [SP]

    SP - 2 SP ; CS [SP]

    SP - 2 SP ; IP [SP]

    Antes Tras guardarlos en la Pila

    SP IP

    SS SS SP CS

    SP PSW

    SP SP

  • Se ponen a 0 los flags I y T. (0 FI ; 0 FT )

  • Flag I: Cuando va a atender a una interrupción, el micro inhabilita las interrupciones para que si llega otra interrupción mientras atiende una, no haga caso y termine de atender a la que esté en curso.

    Rutina Atención Interrupción

    Deshabilitar ints. Habilitar interrupciones

    INT

    8086

    Recupera

    PSW anterior

    Flag T: Supongamos que tenemos un depurador y vamos a depurar un programa. Si entre medias surge una interrupción y FT=1, se trataría la rutina de atención a la interrupción también de instrucción en instrucción (paso a paso), cosa no deseada.

  • Se lee de la Tabla Vectorial de Interrupciones la dirección inicial de la rutina de atención y se salta a ella (las direcciones de las rutinas de atención a interrupciones de almacenan en dicha tabla, a la que debemos acceder, conocido el vector, para determinar dónde se encuentra la rutina de interrupción deseada). La dirección de la rutina de atención a la interrupción, CS:IP, se obtiene:

  • (4 * Vector ) CS

    (4 * Vector + 2) IP

    Vector 0 0 1 2 3

    Vector 1 4 5 6 7

    ... ... ... ... ...

    4v 4v+1 4v+2 4v+3

    Vector V 1 A 8 2 4 F 3 C

    ... ... ... ... ...

    3F8 3F9 3FA 3FB

    Vector FEh

    3FC 3FD 3FE 3FF

    Vector FFh

    Menos singnificativa. Más significativa. Menos singnificativa. Más significativa.

    Offset Segment

    Por ejemplo, la rutina que atiende al vector V empieza en la dirección: 3 C 4 F h : 8 2 1 A h

    VECTORES RESERVADOS.

    En el 8086 los vectores reservados van del 0 al 4:

    Vector 0 Desbordamiento en instrucciones de división. (Excepción)

    Vector 1 Interrupción por finalización de instrucción si FT = 1.

    Vector 2 Interrupción hardware no enmascarable (señal NMI).

    Vector 3 Interrupción software especialmente diseñada para implementar Breakpoints en

    depuradores, ya que la INT 3 ocupa 1 byte (todas las demás INT ocupan 2 bytes).

    Vector 4 Producida por una INT 0 si el Fo = 1.

    División:

    Divid16 / Divid8 se espera que produzca: Cociente8 y Resto8

    1111 1111 1111 1111 / 0000 0001 Desbordamiento de división INT 0

    Cuando FT = 1, se producirá una interrupción cada vez que se termine de ejecutar una instrucción.

    La mayoría de las INT hardware van por el sistema conocido: diálogo entre Microprocesador - PIC.

    INT

    8086 PIC

    INTA

    Vector

    Sin embargo, también hay otra posibilidad, que es cuando sucede una INT de tipo NMI. Ésta interrupción tiene una línea (cable) asignada, y cuando se activa, no hay diálogo entre Microprocesador - PIC, sino que directamente la NMI tiene siempre asignado el Vector 2 (INT 2):

    8086 PIC

    NMI (Vector 2)

    La interrupción 3 (INT 3) tiene un código de operación (OPCODE) de 1 byte, mientras que las demás

    tienen 2 bytes.

    Un Breakpoint (punto de ruptura) indica el punto en que el programa dejará de ejecutarse normalmente

    y pasará a hacerlo paso a paso ( para que pueda usarlo un depurador).

    El depurador debe estar diseñado de la siguiente forma:

    en donde se sitúa el Breakpoint, se coge la instrucción, (que se almacenará en el depurador), y la

    sustituye por una llamada a la INT 3 (por lo que dicha llamada debe ocupar 1 byte, ya que la

    instrucción sustituida puede ser de las que ocupan un solo byte).

    INT 0 mira el Flag de Overflow, y si está a 1 hay overflow, lo que provocará una INT 4, saltando a la

    rutina de atención a la INT 4 que atenderá dicho desbordamiento.

    Oper ...

    INT 0 JNO xxxx

    .... JMP/CALL rutina

    ope xxxx:

    INT 0 ...

    VECTORES DE INTERRUPCIÓN.

    Los siguientes vectores de interrupción son los mas usados:

    Nº Vect. Función que realiza

    0-4 Reservados para el micro

    5 (BIOS, Soft.) Volcado de pantalla en impresora al pulsar IMPR PANT

    8-0FH (Hard.) 1er controlador de interrupciones

    8 Periódica cada 1/18.2 segundos

    9 Teclado

    0BH COM1

    0CH COM2

    0DH LPT2 (en XT disco duro)

    0EH Diskette

    0FH LPT1

    10H-1AH Servicios BIOS

    10H Vídeo

    13H Discos y Floppy

    14H Comunicaciones serie

    16H Teclado

    17H Impresora

    1AH Fecha y Hora

    1BH (Soft.,BIOS) Tratamiento CTRL+PAUSE

    20H Terminación del programa

    21H Servicios del SO

    22H Terminación normal

    23H Terminación por aborto

    24H Terminación por error critico

    25H-26H Lectura y escritura en discos y floppys por número de sector

    27H Terminación quedando residente

    33H Ratón (driver del ratón) (Soft.)

    40H-47H --------------disponibles-------------------

    50H-57H (Hard.) aquí se tratan los vectores 08H a 0FH cuando se pasa a Modo Protegido

    58H-6FH --------------disponibles-------------------

    70H-77H(Hard.) Segundo controlador interrupciones

    70H Reloj tiempo real

    74H Ratón (Hard.)

    75H Coprocesador

    76H Disco duro

    78H-7FH -------------disponibles--------------------

    80H-FFH -------------disponibles-------------------- (Antiguamente BASIC de la PROM)

    EL PREFETCH.

    Lectura anticipada de código.

    El 8086 se puede considerar internamente dividido en 2 partes: BIU (Bus Interface Unit) y EU (Execution Unit).

    8086

    BIU EU

    BUSES

    Pila de Prefetch.

    (FIFO)

    El BIU es la unidad que se encarga de la comunicación del micro con los buses externos al microprocesador. El EU se encarga de interpretar y ejecutar las instrucciones.

    Cuando el EU necesita un dato, se lo debe pedir al BIU, el cual gestionará dicha petición. Cuando el BIU no tiene nada que hacer, lee las siguientes instrucciones a ejecutar y las almacena en la Pila de Prefetch (estructura FIFO), que es una pila interna del micro, de 6 bytes y no modificable por nosotros (es gestionada interiormente por el micro).

    Esto es útil sólo en el caso de que las siguientes instrucciones leídas sean las que se vayan a ejecutar, pero si el EU se encuentra con una instrucción de salto, entonces las instrucciones introducidas en la Pila de Prefetch no nos sirven, por lo que el EU vaciará dicha pila (además de actualizar valores de IP y demás registros).

    CS : IP JMP xxxx

    xxxx:

    Hay casos (código automodificable) que dificultan el antidebug, en los cuales al leer instrucciones y depositarlas en la Pila de Prefetch, si luego el código se automodifica, lo haría en memoria, pero no en la Pila de Prefetch. Para ignorar las instrucciones de la Pila de Prefetch, se puede, p.e., hacer un salto (JMP) a la siguiente instrucción, lo que a simple vista es poco útil, pero EU detecta dicho salto, y borra la Pila de Prefetch ( el salto provoca el borrado de la Pila de Prefetch).

    JMP xxxx Provoca el borrado de la Pila de Prefetch.

    xxxx:

    OTRAS CARACTERÍSTICAS.

    Ciclo de máquina típico: 4 ciclos de reloj.

    Código de operación: 1 o 2 bytes.

    Tamaño de la instrucción: 1 a 6 bytes.

    Utiliza DMA: El micro pasa al estado de parada (HALT) del que sale por cualquier interrupción HLT.

    OPERANDOS.

    Memoria

    Micro 8086

    [DS:SI]8

    Byte

    DS

    AH AL [DS:SI]16

    AX

    (Word)

    [ES:DI]8

    ES

    [ES:DI]16

    Load

    mem reg

    Store

    reg mem

    ACCESOS A MEMORIA.

    Tipo de Ciclo Máquina (acceso)

    Segmento

    Offset

    ¿Puede usarse

    otro segmento?

    Comentarios

    Fetch: Lectura de instrucción.

    CS

    IP

    NO

    CS:IP hace las veces de contador de programa. En cada instrucción leída se incrementa IP. Si IP sale del segmento CS por abajo, vuelve a 0000h de CS.

    Ciclos automáticos de Pila.

    SS

    SP

    NO

    SS:SP hace las veces de puntero de pila. Los incrementos/decrementos sólo se producirán sobre SP.

    Datos

    Inst. de

    Manip. Strings.

    Ptro. destino.

    ES

    DI

    NO

    Ptro. Fuente.

    DS

    SI

    SI

    Otras instruccs.

    BP interviene en inst.

    SS

    Varios modos de direcc.

    SI

    (Prefijo de segmento)

    BP no interviene en inst.

    DS

    Varios modos de direcc.

    SI

    (Prefijo de segmento)

    • Ciclos automáticos de Pila:

    • Introducen o sacan algo de la Pila. Por lo tanto, siempre están referidos al Puntero de Pila y lo modifican.

    • En la instrucción no se indica explícitamente a qué dirección de la Pila se accede.

    • Los hay en las instrucciones:

    PUSH, POP

    CALL, INT, INTO

    RET, IRET

    • El incremento o decremento depende de:

    BYTE: Se incrementa /decrementa el puntero en 1 posición.

    Si el elemento es un

    WORD: Se incrementa/decrementa el puntero en 2 posiciones.

    • SP es el offset del último byte ocupado de la pila, por lo que el par SS:SP apunta a la Cima de la Pila.

    • Si seguimos intentando llenar la Pila al llegar SP a 0000h (recordemos que la pila crece hacia abajo en posiciones de memoria), el puntero SP volvería cíclicamente al FFFFh de SS (Segmento de Pila).

    IP

    CS Código (1segmento = 64KB max)

    SS Pila (1segmento = 64KB max)

    SP Parte ocupada

    de la Pila

    • Instrucciones de Manipulación de Strings.

    • Dejan incrementados o decrementados los punteros que intervengan para facilitar la realización de bucles y repeticiones.

    • Sintácticamente no tienen operandos y los mnemónicos de estas instrucciones acaban en SB o en SW. Concretamente son:

    LODSB, LODSW

    STOSB, STOSW

    MOVSB, MOVSW

    SCASB, SCASW

    CMPSB, CMPSW

    Instrucción STOS / STOSB / STOSW: (almacena cadena)

    Sintaxis: STOS cadena_destino

    STOSB (bytes)

    STOSW (words)

    Transfiere el operando origen almacenado en AX (si es word) o en AL (si es byte), al destino direccionado por ES : DI. Tras la operación, DI se incrementa o decrementa según el flag DF para apuntar el siguiente elemento de la cadena. “cadena_destino” es un operando redundante que sólo indica el tipo de dato (byte o palabra) a cargar, es más cómodo colocar STOSB o STOSW para indicar bytes/words.

    Instrucción MOVS/ MOVSB / MOVSW: (copia cadena)

    Sintaxis: MOVS cadena_destino, cadena_origen

    MOVSB (bytes)

    MOVSW (words)

    Transfiere un byte o palabra de la cadena origen direccionada por DS : SI a la cadena destino direccionada por ES : DI, incrementando o decrementando a continuación los registros SI y DI según el valor del flag DF en una o dos unidades, dependiendo de si se trabaja con bytes o con palabras. Si se indica un registro de segmento, éste se sustituirá en la cadena origen al DS ordinario.

    A base de repeticiones se puede copiar una zona de memoria a otra (para lo que precisaríamos un contador para saber qué número de elementos (bytes con MOVSB, o words con MOVSW) se copian.

    DS

    SI

    DI

    ES

    Hay algunas instrucciones de manipulación de string que trabajan con uno otro puntero o incluso los dos:

    PUNTERO FUENTE: DS : SI ( LODSB y LODSW )

    PUNTERO DESTINO: ES : DI ( STOSB y STOSW )

    ( SCASB y SCASW )

    CON LOS DOS PTROS: ( MOVSB y MOVSW )

    ( CMPSB y CMPSW )

    • Otras instrucciones.

    • Normalmente el operando es explícito.

    • El contenido de memoria se expresa con corchetes [ ] en vez de con paréntesis.

    • Lo que hay dentro de los paréntesis siempre es el Offset.

    • Existen las siguientes formas de expresarlo:

    [Offset] Ej: MOV A , [4832h]

    [Reg] Ej: MOV [BC] , A

    [Seg + Desp] Ej: MOV

    [Reg + Reg] Ej: MOV [BC + X] , A

    [Reg + Reg + Desp] Ej: MOV

    PUERTOS.

    BHE

    A0