Características generales del 8088

Arquitectura del Sistema. Flags. Registros Internos. Unidad Aritmético Lógica. Flags. Instrucciones. Interrupciones. Modos de Direccionamiento

  • Enviado por: Yeroscar Senra
  • Idioma: castellano
  • País: Ecuador Ecuador
  • 20 páginas
publicidad

Características generales

  • Bus de datos de 8 bits

  • Arquitectura interna de 16 bits

  • Direccionamiento de 1Mb

  • Clock de 5 MHz

  • Modo máximo y modo mínimo

  • Bus de direcciones y datos multiplexados

 

Características generales del 8088

Registros

Dispone de 4 tipos de registros:

  • Registros de datos

  • Registros de segmento

  • Registros punteros

  • Registros de estado

Registros de datos

  • AX

  • BX

  • CX

  • DX

Sirven de acumuladores y de registros de operandos de 16 bits. Cada uno puede separarse en 2 de 8 bits: AH, AL, BH, BL, CH, CL, DH, DL. Cada uno de los 4 registros pueden comportarse como registros generales, pero cada uno tiene una función específica según la operación asociada.

Registros de Segmento

  • CS: contiene la dirección de base del segmento de programa (Code Segment)

  • DS: contiene la dirección de base del espacio de direcciones de datos (Data Segment)

  • SS: contiene la dirección de base del espacio de direcciones de pila (Stack Segment)

  • ES: Contiene la dirección de base del espacio de direcciones de datos suplementarios (External data Segment)

Forman parte de la unidad de gestión de memoria. Cada uno contiene la dirección física de base de uno de los cuatro segmentos de 64Kb. Contienen los 16 bits más significativos de la dirección, los otros cuatro siempre son ceros.

Registros Punteros (pointers)

  • SP

  • BP

  • SI

  • DI

Participan en las operaciones aritméticas y lógicas.

SP y BP se toman por defecto para expresar un desplazamiento en el interior del segmento de pila.

SI y DI se usan por defecto para expresar un desplazamiento en el interior del segmento de datos, salvo en operaciones con cadenas.

Contador de Programa (IP - Instruction Pointer)

Contiene el desplazamiento con respecto la dirección contenida en el CS. La suma de IP y CS da la dirección de la próxima instrucción.

Registro de estado (FLAGS)

  • AF (Auxiliary Carry Flag): es el acarreo entre los bits 3 y 4. Se usa en el ajuste decimal.

  • CF (Carry Flag): indica que hubo acarreo de 8 bit

  • PF (Parity Flag): Es el indicador de paridad, si está en 1 indica paridad par.

  • SF (Sign Flag): es el indicador de signo. Un 1 indica negativo.

  • ZF (Zero Flag): Es el indicador de cero. Si ZF =1 indica que el resultado fue cero.

  • OF (Overflow Flag): se pone en 1 cuando el bit más significativo se pierde debido a un rebasamiento.

  • DF (Direction Flag): para dar la dirección (direcciones crecientes o decrecientes de memoria) en las cadenas.

  • IF (Interrupt Flag): Es la mascara de interrupciones, en 0 enmascara.

  • TF (Trace Flag): controla el modo traza. Si el programador coloca un 1, se desencadenará una interrupción interna al final de cada instrucción. Entonces el programa se bifurca a la rutina de atención, la cual corre sin parar en cada instrucción.

 

Modo de Uso de la Memoria

El 8088 tiene un bus de direcciones de 20 bits para poder direccionar 1Mb. Pero para disminuir la longitud de las instrucciones limitando el campo de direcciones a 16 bits, se divide la memoria en 4 segmentos. Cada segmento tiene una capacidad máxima de 64Kb.

Características generales del 8088

El cálculo de la dirección física depende de dos registros:

  • El registro de segmento que puede estar indicado implícita o explícitamente en la instrucción, al cual se le agregan los últimos cuatro ceros.

  • El desplazamiento indicado en el campo de dirección de la instrucción.

  • Tipo de acceso a memoria

    Registro de segmento por defecto

    Otro posible registro de segmento

    Registro que contiene el desplazamiento

    Búsqueda de la instrucción

    CS

    Ninguno

    IP

    Operación sobre la pila

    SS

    Ninguno

    SP

    Acceso al dato fuente o destino de una cadena

    ES

    Ninguno

    DI

    Acceso a un dato

    DS

    CS, ES, SS

    Dir Efectiva

    Acceso a un dato con BP como registro base

    SS

    CS, DS, ES

    Dir Efectiva

    Cuando el operando es una palabra (16 bits), se pueden poner en direcciones pares o impares linderas. Tanto para direcciones como para datos, el byte menos significativo de la palabra se guarda en la dirección más chica y el byte mas significativo en la dirección superior siguiente.

    La BIU ejecutará automáticamente dos ciclos de búsqueda o escritura en caso de operandos de 16-bits.

    Los segmentos de memoria pueden estar separados, solapados o superpuestos.

    Relocalización: cuando un programa no contiene instrucciones de carga o modificación de los registros de segmento ni instrucciones de salto a un segmento distinto del segmento de programa, puede ser relocalizado. Para ello es necesario que todos los desplazamientos sean relativos a las direcciones bases contenidas en los registros de segmento.

    Algunas direcciones de memoria están reservadas para los vectores de interrupción y el de RESET.

    Características generales del 8088

    Tipo de referencia a memoria

    Registro de segmento usado

    Regla de seleccione de segmento

    Instrucciones

    CS (Code)

    Automática con todas las instrucciones

    Pila

    SS (Stack)

    Todos los pushes y pops a la pila. Referencias a memoria relativas al BP excepto en referencias de datos

    Local Data

    DS (Data)

    Referencias a datos cuando: relativo a la pila, operación con cadenas

    External (Global) Data

    ES (Extra)

    Uso con cadenas

    La pila se desarrolla hacia direcciones decrecientes de memoria. El SP contiene la dirección de la última palabra de la pila. La pila trabaja con palabras y no con bytes.

     

    Modos de Direccionamiento

    Para describir los modos de direccionamiento usaremos la instrucción MOV destino, origen.

    Modos de Direccionamiento de Datos

    Direccionamiento por Registro

    Transfiere el contenido de un registro a otro del mismo tamaño. El único MOV que no se permite es el que se hace entre un registro de segmento y otro. Tampoco se puede modificar el registro de segmento de código. Es rápido.

    MOV AX,BX (AX <- BX)

    Direccionamiento Inmediato

    Transfiere el dato que sigue al código de operación al registro especificado. Es muy rápido porque se hace con información de la cola.

    MOV AX,3456H (AX <- 3456H)

    Direccionamiento Directo

    Se suma el desplazamiento dado al segmento de datos.

    • Direccionamiento directo que solo se aplica a una MOV entre una localidad de memoria y AL ó AX. Son instrucciones muy comunes y tienen 3 bytes de longitud

    • Direccionamiento directo por desplazamiento: ídem anterior pero de 4 bytes

    MOV AX,1234H (AX <- [DS x 10H + 1234H])

    Direccionamiento indirecto por registro

    Transfiere un dato entre un registro y una dirección de memoria direccionada por un registro índice o base (BP, EX, DI, SL)

    MOV AX,[BX] (Ax <- [DS x 10H + BX])

    Cuando se utiliza este modo de direccionamiento y se emplean los registros BX, DI o SI, se asume que el dato está en el segmento de datos.

    Si se usa BP se toma que el dato está en el segmento de pila.

    Direccionamiento Base Más Índice

    Direcciona en forma indirecta los datos de memoria. Se usa un registro base (BP o BX) más un registro índice (DI o SI). Si se usa BP se toma como dato de pila

    MOV AX,[BX+SI] (AX <- [BX+SI+DS x 10H])

    Se usa para direccionar tablas en memoria.

    Direccionamiento Relativo por Registro

    Para ubicar el dato se agrega un desplazamiento al contenido del índice (BP, BX, DI o SI). También BP direcciona en pila y los otros en datos.

    MOV [BX+4],AX (AX -> BX+4+DS x 10H)

    Direccionamiento Relativo Base Más Índice

    Transfiere entre un registro y una dirección dada por un registro base más índice más desplazamiento.

    MOV ARRAY[BX+SI],AX (BX+ARRAY+SI+DS x 10H <- AX)

    Se usa para direccionar un arreglo bidireccional.

    Modos de Direccionamiento de Memoria de Programa

    Usados en instrucciones de salto (JMP) y llamada (CALL)

    Direccionamiento Directo a la Memoria del Program

    Se almacena la dirección con el código de operación. Se usa para saltos largos entre segmentos.

    JMP 10000H CS <- 10000H, IP <- 0000H

    Direccionamiento Relativo de Memoria de Programa

    Se modifica el contenido del IP para continuar la ejecución en otro lado, según el valor especificado luego del código de operación. Se usa para saltos cortos intrasegmento.

    JMP 2 (IP <- IP+2)

    Direccionamiento Indirecto de Memoria de Programa

    La dirección está contenida en un registro relativo.

    JMP [BX] (Ip <- BX)

    Direccionamiento a la Pila de Memoria

    Los datos se ponen en la pila por PUSH y se recuperan por POP.

    La instrucción CALL aprovecha la pila para salvar la dirección de retorno y la RET para recuperarla.

    La pila se mantiene con 2 registros:

    • SP: Stack Pointer

    • SS: Stack Segment

    • PUSH: El SP-1 apunta a donde se almacenará la parte alta del próximo dato. La parte baja se almacena en SP-2. Luego deccrementa 2.

    • POP: LA parte alta del dato se recupera de SP, la parte baja se recupera de SP+1. Luego incrementa 2.

    NOTA: PUSH A y POP A salva o recupera todos los registros (excepto los de segmento) en la pila.

    Direccionamiento Implícito

    El operando está implícito. HLT, LOCK, WAIT, DAA.

    Instrucciones de 8086 y 8088

    por Dario Alejandro Alpern

    INSTRUCCIONES DE TRANSFERENCIA DE DATOS (No afectan flags)

    MOV dest,src

    Copia el contenido del operando fuente (src) en el destino (dest).
    Operación: dest <- src
    Las posibilidades son:

  • MOV reg,{reg|mem|inmed}

  • MOV mem,{reg|inmed}

  • MOV {reg16|mem16},{CS|DS|ES|SS}

  • MOV {DS|ES|SS},{reg16|mem16}

  • PUSH src

    Pone el valor en el tope del stack.
    Operación: SP <- SP - 2, [SP+1:SP] <- src donde src = {reg16|mem16|CS|DS|ES|SS}.

    POP dest

    Retira el valor del tope del stack poniéndolo en el lugar indicado.
    Operación: dest <- [SP+1:SP], SP <- SP + 2 donde dest = {reg16|mem16|DS|ES|SS}.

    XCHG reg,{reg|mem}

    Intercambia ambos valores.

    IN {AL|AX},{DX|inmed (1 byte)}

    Pone en el acumulador el valor hallado en el port indicado.

    OUT {DX|inmed (1 byte)},{AL|AX}

    Pone en el port indicado el valor del acumulador.

    XLAT

    Realiza una operación de traducción de un código de un byte a otro código de un byte mediante una tabla.
    Operación: AL <- [BX+AL]

    LEA reg,mem

    Almacena la dirección efectiva del operando de memoria en un registro.
    Operación: reg <- dirección mem

    LDS reg,mem32

    Operación: reg <- [mem], DS <- [mem+2]

    LES reg,mem32

    Operación: reg <- [mem], ES <- [mem+2]

    LAHF

    Copia en el registro AH la imagen de los ocho bits menos significativos del registro de indicadores.
    Operación: AH <- SF:ZF:X:AF:X:PF:X:CF

    SAHF

    Almacena en los ocho bits menos significativos del registro de indicadores el valor del registro AH.
    Operación: SF:ZF:X:AF:X:PF:X:CF <- AH

    PUSHF

    Almacena los flags en la pila.
    Operación: SP <- SP - 2, [SP+1:SP] <- Flags.

    POPF

    Pone en los flags el valor que hay en la pila.
    Operación: Flags <- [SP+1:SP], SP <- SP + 2

    INSTRUCCIONES ARITMETICAS (Afectan los flags AF, CF, OF, PF, SF, ZF)

    ADD dest,src

    Operación: dest <- dest + src.

    ADC dest,src

    Operación: dest <- dest + src + CF.

    SUB dest,src

    Operación: dest <- dest - src.

    SBB dest,src

    Operación: dest <- dest - src - CF.

    CMP dest,src

    Operación: dest - src (sólo afecta flags).

    INC dest

    Operación: dest <- dest + 1 (no afecta CF).

    DEC dest

    Operación: dest <- dest - 1 (no afecta CF).

    NEG dest

    Operación: dest <- - dest.

    donde dest = {reg|mem} y src = {reg|mem|inmed} no pudiendo ambos operandos estar en memoria.

    DAA

    Corrige el resultado de una suma de dos valores BCD empaquetados en el registro AL (debe estar inmediatamente después de una instrucción ADD o ADC). OF es indefinido después de la operación.

    DAS

    Igual que DAA pero para resta (debe estar inmediatamente después de una instrucción SUB o SBB).

    AAA

    Lo mismo que DAA para números BCD desempaquetados.

    AAS

    Lo mismo que DAS para números BCD desempaquetados.

    AAD

    Convierte AH:AL en BCD desempaquetado a AL en binario.
    Operación: AL <- AH * 0Ah + AL, AH <- 0. Afecta PF, SF, ZF, mientras que AF, CF y OF quedan indefinidos.

    AAM

    Convierte AL en binario a AH:AL en BCD desempaquetado.
    Operación: AH <- AL / 0Ah, AL <- AL mod 0Ah. Afecta PF, SF, ZF, mientras que AF, CF y OF quedan indefinidos.

    MUL {reg8|mem8}

    Realiza una multiplicación con operandos no signados de 8 por 8 bits.
    Operación: AX <- AL * {reg8|mem8}. CF=OF=0 si AH = 0, CF=OF=1 en caso contrario. AF, PF, SF, ZF quedan indefinidos.

    MUL {reg16|mem16}

    Realiza una multiplicación con operandos no signados de 16 por 16 bits.
    Operación: DX:AX <- AX * {reg16|mem16}. CF=OF=0 si DX = 0, CF=OF=1 en caso contrario. AF, PF, SF, ZF quedan indefinidos.

    IMUL {reg8|mem8}

    Realiza una multiplicación con operandos con signo de 8 por 8 bits.
    Operación: AX <- AL * {reg8|mem8} realizando la multiplicación con signo. CF = OF = 0 si el resultado entra en un byte, en caso contrario valdrán 1. AF, PF, SF, ZF quedan indefinidos.

    IMUL {reg16|mem16}

    Realiza una multiplicación con operandos con signo de 16 por 16 bits.
    Operación: DX:AX <- AX * {reg16|mem16} realizando la multiplicación con signo. CF = OF = 0 si el resultado entra en dos bytes, en caso contrario valdrán 1. AF, PF, SF, ZF quedan indefinidos.

    CBW

    Extiende el signo de AL en AX. No se afectan los flags.

    CWD

    Extiende el signo de AX en DX:AX. No se afectan flags.

    INSTRUCCIONES LOGICAS (Afectan AF, CF, OF, PF, SF, ZF)

    AND dest,src

    Operación: dest <- dest and src.

    TEST dest,src

    Operación: dest and src. Sólo afecta flags.

    OR dest,src

    Operación: dest <- dest or src.

    XOR dest,src

    Operación: dest <- dest xor src.

    Las cuatro instrucciones anteriores ponen CF = OF = 0, AF queda indefinido y PF, SF y ZF dependen del resultado.

    NOT dest

    Operación: dest <- Complemento a 1 de dest. No afecta los flags.

    SHL/SAL dest,{1|CL}

    Realiza un desplazamiento lógico o aritmético a la izquierda.

    SHR dest,{1|CL}

    Realiza un desplazamiento lógico a la derecha.

    SAR dest,{1|CL}

    Realiza un desplazamiento aritmético a la derecha.

    ROL dest,{1|CL}

    Realiza una rotación hacia la izquierda.

    ROR dest,{1|CL}

    Realiza una rotación hacia la derecha.

    RCL dest,{1|CL}

    Realiza una rotación hacia la izquierda usando el CF.

    RCR dest,{1|CL}

    Realiza una rotación hacia la derecha usando el CF.

    En las siete instrucciones anteriores la cantidad de veces que se rota o desplaza puede ser un bit o la cantidad de bits indicado en CL.

    INSTRUCCIONES DE MANIPULACION DE CADENAS:

    MOVSB

    Copiar un byte de la cadena fuente al destino.
    Operación:

  • ES:[DI] <- DS:[SI] (un byte)

  • DI <- DI±1

  • SI <- SI±1

  • MOVSW

    Copiar dos bytes de la cadena fuente al destino.
    Operación:

  • ES:[DI] <- DS:[SI] (dos bytes)

  • DI <- DI±2

  • SI <- SI±2

  • LODSB

    Poner en el acumulador un byte de la cadena fuente.
    Operación:

  • AL <- DS:[SI] (un byte)

  • SI <- SI±1

  • LODSW

    Poner en el acumulador dos bytes de la cadena fuente.
    Operación:

  • AX <- DS:[SI] (dos bytes)

  • SI <- SI±2

  • STOSB

    Almacenar en la cadena destino un byte del acumulador.
    Operación:

  • ES:[DI] <- AL (un byte)

  • DI <- DI±1

  • STOSW

    Almacenar en la cadena destino dos bytes del acumulador.
    Operación:

  • ES:[DI] <- AX (dos bytes)

  • DI <- DI±2

  • CMPSB

    Comparar un byte de la cadena fuente con el destino.
    Operación:

  • DS:[SI] - ES:[DI] (Un byte, afecta sólo los flags)

  • DI <- DI±1

  • SI <- SI±1

  • CMPSW

    Comparar dos bytes de la cadena fuente con el destino.
    Operación:

  • DS:[SI] - ES:[DI] (Dos bytes, afecta sólo los flags)

  • DI <- DI±2

  • SI <- SI±2

  • SCASB

    Comparar un byte del acumulador con la cadena destino.
    Operación:

  • AL - ES:[DI] (Un byte, afecta sólo los flags)

  • DI <- DI±1

  • SCASW

    Comparar dos bytes del acumulador con la cadena destino.
    Operación:

  • AX - ES:[DI] (Dos byte, afecta sólo los flags)

  • DI <- DI±2

  • En todos los casos el signo + se toma si el indicador DF vale cero. Si vale 1 hay que tomar el signo -.

    Prefijo para las instrucciones MOVSB, MOVSW, LODSB, LODSW, STOSB y STOSW:

    • REP: Repetir la instrucción CX veces.

    Prefijos para las instrucciones CMPSB, CMPSW, SCASB, SCASW:

    • REPZ/REPE: Repetir mientras que sean iguales hasta un máximo de CX veces.

    • REPNZ/REPNE: Repetir mientras que sean diferentes hasta un máximo de CX veces.

    INSTRUCCIONES DE TRANSFERENCIA DE CONTROL (No afectan los flags):

    CALL label

    Ir al procedimiento cuyo inicio es label.

    RET

    Retorno de procedimiento.

    RET inmed

    Retorno de procedimiento y SP <- SP + inmed.

    Variaciones de la instrucción de retorno:

    RETN [inmed]

    En el mismo segmento de código.

    RETF [inmed]

    En otro segmento de código.

    Saltos condicionales aritméticos (usar después de CMP):

    • Aritmética signada (con números positivos, negativos y cero)

    JL etiqueta/JNGE etiqueta

    Saltar a etiqueta si es menor.

    JLE etiqueta/JNG etiqueta

    Saltar a etiqueta si es menor o igual.

    JE etiqueta

    Saltar a etiqueta si es igual.

    JNE etiqueta

    Saltar a etiqueta si es distinto.

    JGE etiqueta/JNL etiqueta

    Saltar a etiqueta si es mayor o igual.

    JG etiqueta/JNLE etiqueta

    Saltar a etiqueta si es mayor.

    • Aritmética sin signo (con números positivos y cero)

    JB etiqueta/JNAE etiqueta

    Saltar a etiqueta si es menor.

    JBE etiqueta/JNA etiqueta

    Saltar a etiqueta si es menor o igual.

    JE etiqueta

    Saltar a etiqueta si es igual.

    JNE etiqueta

    Saltar a etiqueta si es distinto.

    JAE etiqueta/JNB etiqueta

    Saltar a etiqueta si es mayor o igual.

    JA etiqueta/JNBE etiqueta

    Saltar a etiqueta si es mayor.

    Saltos condicionales según el valor de los indicadores:

    JC label

    Saltar si hubo arrastre/préstamo (CF = 1).

    JNC label

    Saltar si no hubo arrastre/préstamo (CF = 0).

    JZ label

    Saltar si el resultado es cero (ZF = 1).

    JNZ label

    Saltar si el resultado no es cero (ZF = 0).

    JS label

    Saltar si el signo es negativo (SF = 1).

    JNS label

    Saltar si el signo es positivo (SF = 0).

    JP/JPE label

    Saltar si la paridad es par (PF = 1).

    JNP/JPO label

    Saltar si la paridad es impar (PF = 0).

    Saltos condicionales que usan el registro CX como contador:

    LOOP label

    Operación: CX <- CX-1. Saltar a label si CX<>0.

    LOOPZ/LOOPE label

    Operación: CX <- CX-1. Saltar a label si CX <> 0 y ZF = 1.

    LOOPNZ/LOOPNE label

    Operación: CX <- CX-1. Saltar a label si CX <> 0 y ZF = 0.

    JCXZ label

    Operación: Salta a label si CX = 0.

    Interrupciones:

    INT número

    Salva los flags en la pila, hace TF=IF=0 y ejecuta la interrupción con el número indicado.

    INTO

    Interrupción condicional. Si OF = 1, hace INT 4.

    IRET

    Retorno de interrupción. Restaura los indicadores del stack.

    INSTRUCCIONES DE CONTROL DEL PROCESADOR

    CLC

    CF <- 0.

    STC

    CF <- 1.

    CMC

    CF <- 1 - CF.

    NOP

    No hace nada.

    CLD

    DF <- 0 (Dirección ascendente).

    STD

    DF <- 1 (Dirección descendente).

    CLI

    IF <- 0 (Deshabilita interrupciones enmascarables).

    STI

    IF <- 1 (Habilita interrupciones enmascarables).

    HLT

    Detiene la ejecución del procesador hasta que llegue una interrupción externa.

    WAIT

    Detiene la ejecución del procesador hasta que se active el pin TEST del mismo.

    LOCK

    Prefijo de instrucción que activa el pin LOCK del procesador.

    OPERADORES

    Operadores aritméticos

    +, -, *, /, MOD (resto de la división).

    Operadores lógicos AND, OR, XOR, NOT, SHR, SHL.
    Para los dos últimos operadores, el operando derecho indica la cantidad de bits a desplazar hacia la derecha (para SHR) o izquierda (para SHL) el operando izquierdo.

    Operadores relacionales

    Valen cero si son falsos y 65535 si son verdaderos.

    • EQ: Igual a.

    • NE: Distinto de.

    • LT: Menor que.

    • GT: Mayor que.

    • LE: Menor o igual a.

    • GE: Mayor o igual a.

    Operadores analíticos

    Descomponen operandos que representan direcciones de memoria en sus componentes.

    SEG memory-operand: Retorna el valor del segmento.

    OFFSET memory-operand: Retorna el valor del offset.

    TYPE memory-operand: Retorna un valor que representa el tipo de operando: BYTE = 1, WORD = 2, DWORD = 4 (para direcciones de datos) y NEAR = -1 y FAR = -2 (para direcciones de instrucciones).

    LENGHT memory-operand: Se aplica solamente a direcciones de datos. Retorna un valor numérico para el número de unidades (bytes, words o dwords) asociados con el operando. Si el operando es una cadena retorna el valor 1.

    Ejemplo: Dada la directiva PALABRAS DW 50 DUP (0), el valor de LENGHT PALABRAS es 50, mientras que dada la directiva CADENA DB "cadena" el valor de LENGHT CADENA es 1.

    SIZE memory-operand: LENGHT memory-operand * TYPE memory-operand.

    Operadores sintéticos

    Componen operandos de direcciones de memoria a partir de sus componentes.

    type PTR memory-operand: Compone un operando de memoria que tiene el mismo segmento y offset que el especificado en el operando derecho pero con el tipo (BYTE, WORD, DWORD, NEAR o FAR) especificado en el operando izquierdo.

    THIS type: Compone un operando de memoria con el tipo especificado que tiene el segmento y offset que la próxima ubicación a ensamblar.

    Operadores de macros

    Son operadores que se utilizan en las definiciones de macros. Hay cinco: &, <>, !, % y ;;.

    &parámetro: reemplaza el parámetro con el valor actual del argumento.

    <texto>: trata una serie de caracteres como una sola cadena. Se utiliza cuando el texto incluye comas, espacios u otros símbolos especiales.

    !carácter: trata el carácter que sigue al operador ! como un carácter en vez de un símbolo o separador.

    %texto: trata el texto que sigue a continuación del operador % como una expresión. El ensamblador calcula el valor de la expresión y reemplaza el texto por dicho valor.

    sentencia ;;comentario: Permite definir comentarios que aparecerán en la definición de la macro pero no cada vez que éste se invoque en el listado fuente que genera el ensamblador.

    DIRECTIVAS (Instrucciones para el ensamblador)

    Definición de símbolos

    EQU: Define nombres simbólicos que representan valores u otros valores simbólicos. Las dos formas son:
    nombre EQU expresión
    nuevo_nombre EQU viejo_nombre
    Una vez definido un nombre mediante EQU, no se puede volver a definir.

    =: Es similar a EQU pero permite que el símbolo se pueda redefinir. Sólo admite la forma: nombre = expresión.

    Definición de datos

    Ubica memoria para un ítem de datos y opcionalmente asocia un nombre simbólico con esa dirección de memoria y/o genera el valor inicial para ese ítem.

    [nombre] DB valor_inicial [, valor_inicial...]
    donde valor_inicial puede ser una cadena o una expresión numérica cuyo resultado esté entre -255 y 255.

    [nombre] DW valor_inicial [, valor_inicial...]
    donde valor_inicial puede ser una expresión numérica cuyo resultado esté entre -65535 y 65535 o un operando de memoria en cuyo caso se almacenará el offset del mismo.

    [nombre] DD valor_inicial [, valor_inicial...]
    donde valor_inicial puede ser una constante cuyo valor esté entre -4294967295 y 4294967295, una expresión numérica cuyo valor absoluto no supere 65535, o bien un operando de memoria en cuyo caso se almacenarán el offset y el segmento del mismo (en ese orden).

    Si se desea que no haya valor inicial, deberá utilizarse el símbolo ?.

    Otra forma de expresar el valor inicial es:
    cuenta DUP (valor_inicial [, valor_inicial...]) donde cuenta es la cantidad de veces que debe repetirse lo que está entre paréntesis.

    Definición de segmentos

    Organizan el programa para utilizar los segmentos de memoria del microprocesador 8088. Estos son SEGMENT, ENDS, DOSSEG, ASSUME, GROUP.

    nombre_segm

    SEGMENT [alineación][combinación]['clase']

    sentencias

    nombre_segm

    ENDS

    Alineación: define el rango de direcciones de memoria para el cual puede elegirse el inicio del segmento. Hay cinco posibles:

  • BYTE: El segmento comienza en el siguiente byte.

  • WORD: El segmento comienza en la siguiente dirección par.

  • DWORD: Comienza en la siguiente dirección múltiplo de 4.

  • PARA: Comienza en la siguiente dirección múltiplo de 16.

  • PAGE: Comienza en la siguiente dirección múltiplo de 256.

  • Si no se indica la alineación ésta será PARA.

    Combinación: define cómo combinar segmentos que tengan el mismo nombre. Hay cinco posibles:

  • PUBLIC: Concatena todos los segmentos que tienen el mismo nombre para formar un sólo segmento. Todas las direcciones de datos e instrucciones se representan la distancia entre el inicio del segmento y la dirección correspondiente. La longitud del segmento formado será la suma de las longitudes de los segmentos con el mismo nombre.

  • STACK: Es similar a PUBLIC. La diferencia consiste que, al comenzar la ejecución del programa, el registro SS apuntará a este segmento y SP se inicializará con la longitud en bytes de este segmento.

  • COMMON: Pone el inicio de todos los segmentos teniendo el mismo nombre en la misma dirección de memoria. La longitud del segmento será la del segmento más largo.

  • MEMORY: Es igual a PUBLIC.

  • AT dirección_de_segmento: Hace que todas las etiquetas y direcciones de variables tengan el segmento especificado por la expresión contenida en dirección_de_segmento. Este segmento no puede contener código o datos con valores iniciales. Todos los símbolos que forman la expresión dirección_de_segmento deben conocerse en el primer paso de ensamblado.

  • Si no se indica combinación, el segmento no se combinará con otros del mismo nombre (combinación "privada").

    Clase: Es una forma de asociar segmentos con diferentes nombres, pero con propósitos similares. Sirve también para identificar el segmento de código. Debe estar encerrado entre comillas simples.

    El linker pone los segmentos que tengan la misma clase uno a continuación de otro, si bien siguen siendo segmentos diferentes. Además supone que los segmentos de código tiene clase CODE o un nombre con el sufijo CODE.

    DOSSEG: Esta directiva especifica que los segmentos deben ordenarse según la convención de DOS. Esta es la convención usada por los compiladores de lenguajes de alto nivel.

    GROUP: Sirve para definir grupos de segmentos. Un grupo es una colección de segmentos asociados con la misma dirección inicial. De esta manera, aunque los datos estén en diferentes segmentos, todos pueden accederse mediante el mismo registro de segmento. Los segmentos de un grupo no necesitan ser contiguos.
    Sintaxis: nombre_grupo GROUP segmento [, segmento...]

    ASSUME: Sirve para indicar al ensamblador qué registro de segmento corresponde con un segmento determinado. Cuando el ensamblador necesita referenciar una dirección debe saber en qué registro de segmento lo apunta.
    Sintaxis: ASSUME reg_segm:nombre [, reg_segm:nombre...]
    donde el nombre puede ser de segmento o de grupo, una expresión utilizando el operador SEG o la palabra NOTHING, que cancela la selección de registro de segmento hecha con un ASSUME anterior.

    Control del ensamblador

    ORG expresión: El offset del código o datos a continuación será la indicada por la expresión. Todos los símbolos que forman la expresión deben conocerse en el primer paso de ensamblado.

    EVEN: Hace que la próxima instrucción o dato se ensamble en la siguiente posición par.

    END [etiqueta]: Debe ser la última sentencia del código fuente. La etiqueta indica dónde debe comenzar la ejecución del programa. Si el programa se compone de varios módulos, sólo el módulo que contiene la dirección de arranque del programa debe contener la directiva END etiqueta. Los demás módulos deberán terminar con la directiva END (sin etiqueta).

    Definición de procedimientos

    Los procedimientos son secciones de código que se pueden llamar para su ejecución desde distintas partes del programa.

    etiqueta

    PROC

    {NEAR|FAR}

    sentencias

    etiqueta

    ENDP

    Ensamblado condicional

    Verifican una condición determinada y si se cumple, ensambla una porción de código. Opcionalmente puede ensamblarse otra porción de código si la condición no se cumple. Son los siguientes: IF, IF1, IF2, IFB, IFDEF, IFDIF, IFE, IFIDN, IFNB, IFNDEF, ENDIF, ELSE.

    {IF|IFE}

    condición

    sentencias

    ;Se ejecutan si es cierta (IF) o falsa (IFE).

    [ELSE

    sentencias]

    ;Se ejecutan si es falsa (IF) o cierta (IFE).

    ENDIF

    La directiva ELSE y sus sentencias son opcionales. ENDIF termina el bloque y es obligatorio. Se pueden anidar directivas condicionales.

    IF1 permite el ensamblado de las sentencias sólo en el primer paso, mientras que IF2 lo permite en el segundo paso.

    IFDEF nombre permite el ensamblado de las sentencias si el nombre está definido, mientras que IFNDEF nombre lo permite si no está definido.

    IFB <argumento> permite el ensamblado si el argumento en una macro es blanco (no se pasó el argumento).

    IFNB <argumento> permite el ensamblado si el argumento en una macro no es blanco (se pasó el argumento).

    IFIDN <argumento1>, <argumento2> permite el ensamblado si los dos parámetros pasados a la macro son idénticos.

    IFDIF <argumento1>,<argumento2> permite el ensamblado si los dos parámetros pasados a la macro son diferentes.

    Macros: Las macros asignan un nombre simbólico a un bloque de sentencias fuente. Luego se puede usar dicho nombre para representar esas sentencias. Opcionalmente se pueden definir parámetros para representar argumentos para la macro.

    Definición de macros

    nombre_macro

    MACRO

    [parámetro [,parámetro...]]

    [LOCAL

    nombre_local[,nombre_local...]

    sentencias

    ENDM

    Los parámetros son opcionales. Si existen, entonces también aparecerán en algunas de las sentencias en la definición de la macro. Al invocar la macro mediante:

    nombre_macro [argumento [,argumento..]]

    se ensamblarán las sentencias indicadas en la macro teniendo en cuenta que cada lugar donde aparezca un parámetro se reemplazará por el argumento correspondiente.

    El nombre_local de la directiva LOCAL es un nombre simbólico temporario que será reemplazado por un único nombre simbólico (de la forma ??número) cuando la macro se invoque.

    Todas las etiquetas dentro de la macro deberán estar indicadas en la directiva LOCAL para que el ensamblador no genere un error indicando que un símbolo está definido varias veces.

    La directiva EXITM (usada dentro de la definición de la macro) sirve para que no se ensamblen más sentencias de la macro (se usa dentro de bloques condicionales).

    PURGE nombre_macro [,nombre_macro...]: Borra las macros indicadas de la memoria para poder utilizar este espacio para otros símbolos.

    Definición de bloques de repetición

    Son tres: REPT, IRP e IRPC. Como en el caso de la directiva MACRO, se puede incluir la sentencias LOCAL y EXITM y deben terminarse con la directiva ENDM.

    REPT expresión
    sentencias
    ENDM

    La expresión debe poder ser evaluada en el primer paso del ensamblado y el resultado deberá estar entre 0 y 65535.

    Esta expresión indica la cantidad de veces que debe repetirse el bloque.

    IRP parámetro, <argumento [,argumento...]>
    sentencias
    ENDM

    El parámetro se reemplaza por el primer argumento y se ensamblan las sentencias dentro del bloque. Luego el parámetro se reemplaza por el segundo argumento y se ensamblan las sentencias y así sucesivamente hasta agotar los argumentos.

    IRPC parámetro, cadena
    sentencias
    ENDM

    Es similar a IRP con la diferencia que el parámetro se reemplaza por cada carácter de la cadena. Si ésta contiene comas, espacios u otros caracteres especiales deberá encerrarse con paréntesis angulares (<>).

    Procesador: Indican el tipo de procesador y coprocesador en el que se va a ejecutar el programa. Los de procesador son: .8086, .186, .286, .386, .486 y .586 para instrucciones en modo real, .286P, .386P, .486P y .586P para instrucciones privilegiadas, .8087, .287 y .387 para coprocesadores. Deben ubicarse al principio del código fuente. Habilitan las instrucciones correspondientes al procesador y coprocesador indicado. Sin estas directivas, sólo se pueden ensamblar instrucciones del 8086 y 8087.

    Referencias externas al módulo

    Sirve para poder particionar un programa en varios archivos fuentes o módulos. Son imprescindibles si se hace un programa en alto nivel con procedimientos en assembler. Hay tres: PUBLIC, EXTRN e INCLUDE.

    PUBLIC nombre[, nombre...]: Estos nombres simbólicos se escriben en el archivo objeto. Durante una sesión con el linker, los símbolos en diferentes módulos pero con los mismos nombres tendrán la misma dirección.

    EXTRN nombre:tipo [,nombre:tipo...]: Define una variable externa con el nombre y tipo (NEAR, FAR, BYTE, WORD, DWORD o ABS (número constante especificado con la directiva EQU o =)) especificado. El tipo debe ser el mismo que el del ítem indicado con la directiva PUBLIC en otro módulo.

    INCLUDE nombre_de_archivo: Ensambla las sentencias indicadas en dicho archivo.

    Segmentos simplificados

    Permite definir los segmentos sin necesidad de utilizar las directivas de segmentos que aparecen más arriba.

    .MODEL modelo: Debe estar ubicada antes de otra directiva de segmento. El modelo puede ser uno de los siguientes:

  • TINY: Los datos y el código juntos ocupan menos de 64 KB por lo que entran en el mismo segmento. Se utiliza para programas .COM. Algunos ensambladores no soportan este modelo.

  • SMALL: Los datos caben en un segmento de 64 KB y el código cabe en otro segmento de 64 KB. Por lo tanto todo el código y los datos se pueden acceder como NEAR.

  • MEDIUM: Los datos entran en un sólo segmento de 64 KB, pero el código puede ser mayor de 64 KB. Por lo tanto, código es FAR, mientras que los datos se acceden como NEAR.

  • COMPACT: Todo el código entra en un segmento de 64 KB, pero los datos no (pero no pueden haber matrices de más de 64 KB). Por lo tanto, código es NEAR, mientras que los datos se acceden como FAR.

  • LARGE: Tanto el código como los datos pueden ocupar más de 64 KB (pero no pueden haber matrices de más de 64 KB), por lo que ambos se acceden como FAR.

  • HUGE: Tanto el código como los datos pueden ocupar más de 64 KB (y las matrices también), por lo que ambos se acceden como FAR y los punteros a los elementos de las matrices también son FAR.

  • .STACK [size]: Define el segmento de pila de la longitud especificada.

    .CODE [name]: Define el segmento de código.

    .DATA: Define un segmento de datos NEAR con valores iniciales.

    .DATA?: Define un segmento de datos NEAR sin valores iniciales.

    .FARDATA [name]: Define un segmento de datos FAR con valores iniciales.

    .FARDATA? [name]: Define un segmento de datos FAR sin valores iniciales.

    .CONST: Sefine un segmento de datos constantes.

    Los siguientes símbolos están definidos cuando se usan las directivas anteriores:

    • @curseg: Tiene el nombre del segmento que se está ensamblando.

    • @filename: Representa el nombre del archivo fuente (sin la extensión)

    • @codesize: Vale 0 para los modelos SMALL y COMPACT (código NEAR), y vale 1 para los modelos MEDIUM, LARGE y HUGE (código FAR).

    • @datasize: Vale 0 para los modelos SMALL y MEDIUM (datos NEAR), vale 1 para los modelos COMPACT y LARGE (datos FAR) y vale 2 para el modelo HUGE (punteros a matrices FAR).

    • @code: Nombre del segmento definido con la directiva .CODE.

    • @data: Nombre del segmento definido con la directivas .DATA, .DATA?, .CONST y .STACK (los cuatro están en el mismo segmento).

    • @fardata: Nombre del segmento definido con la directiva .FARDATA.

    • @fardata?: Nombre del segmento definido con la directiva .FARDATA?