interfaces

26
Instrucciones de Ajuste AAA (Ajuste ASCII para la suma). Sintaxis: AAA Indicadores: OF DF IF TF SF ZF AF PF CF ? - - - ? ? x ? x Convierte el contenido del registro AL en un número BCD no empaquetado. Si los cuatro bits menos significativos de AL son mayores que 9 ó si el indicador AF está a 1, se suma 6 a AL, 1 a AH, AF se pone a 1, CF se iguala a AF y AL pone sus cuatro bits más significativos a 0. Ejemplo: ADD AL,BL AAA En el ejemplo, tras la suma de dos números BCD no empaquetados colocados en AL y BL, el resultado (por medio de AAA) sigue siendo un número BCD no empaquetado. DAA (Ajuste decimal para la suma). Sintaxis: DAA Indicadores: OF DF IF TF SF ZF AF PF CF ? - - - x x x x x Convierte el contenido del registro AL en un par de valores BCD: si los cuatro bits menos significativos de AL son un número mayor que 9, el indicador AF se pone a 1 y se suma 6 a AL. De igual forma, si los cuatro bits más significativos de AL tras la operación anterior son un número mayor que 9, el indicador CF se pone a 1 y se suma 60h a AL. Ejemplo: ADD AL, CL DAA En el ejemplo anterior, si AL y CL contenían dos números BCD empaquetados, DAA hace que el resultado de la suma (en AL) siga siendo también un BCD empaquetado. AAS (Ajuste ASCII para la resta). Sintaxis: AAS Indicadores: OF DF IF TF SF ZF AF PF CF ? - - - ?? x? x Convierte el resultado de la sustracción de dos operandos BCD no empaquetados para que siga siendo un número BCD no empaquetado. Si el nibble inferior de AL tiene un valor mayor que 9, de AL se resta 6, se decrementa AH, AF se pone a 1 y CF se iguala a AF. El resultado se guarda en AL con los bits de 4 a 7 puestos a 0. Ejemplo: SUB AL,BL AAS

Upload: jefte-abisai-perez-canche

Post on 25-Oct-2015

4 views

Category:

Documents


0 download

TRANSCRIPT

Instrucciones de AjusteAAA (Ajuste ASCII para la suma).Sintaxis:AAAIndicadores:OF DF IF TF SF ZF AF PF CF? - - - ? ? x ? xConvierte el contenido del registro AL en un número BCD no empaquetado. Si los cuatro bits menos significativos de AL son mayores que 9 ó si el indicador AF está a 1, se suma 6 a AL, 1 a AH, AF se pone a 1, CF se iguala a AF y AL pone sus cuatro bits más significativos a 0.Ejemplo:ADD AL,BLAAAEn el ejemplo, tras la suma de dos números BCD no empaquetados colocados en AL y BL, el resultado (por medio de AAA) sigue siendo un número BCD no empaquetado.DAA (Ajuste decimal para la suma).Sintaxis:DAAIndicadores:OF DF IF TF SF ZF AF PF CF? - - - x x x x xConvierte el contenido del registro AL en un par de valores BCD: si los cuatro bits menos significativos de AL son un número mayor que 9, el indicador AF se pone a 1 y se suma 6 a AL. De igual forma, si los cuatro bits más significativos de AL tras la operación anterior son un número mayor que 9, el indicador CF se pone a 1 y se suma 60h a AL.Ejemplo:ADD AL, CLDAAEn el ejemplo anterior, si AL y CL contenían dos números BCD empaquetados, DAA hace que el resultado de la suma (en AL) siga siendo también un BCD empaquetado.AAS (Ajuste ASCII para la resta).Sintaxis:AASIndicadores:OF DF IF TF SF ZF AF PF CF? - - - ?? x? x

Convierte el resultado de la sustracción de dos operandos BCD no empaquetados para que siga siendo un número BCD no empaquetado. Si el nibble inferior de AL tiene un valor mayor que 9, de AL se resta 6, se decrementa AH, AF se pone a 1 y CF se iguala a AF. El resultado se guarda en AL con los bits de 4 a 7 puestos a 0.Ejemplo:SUB AL,BLAASEn el ejemplo, tras la resta de dos números BCD no empaquetados colocados en AL yBL, el resultado (por medio de AAS) sigue siendo un número BCD no empaquetado.DAS (Ajuste decimal para la resta).Sintaxis:DASIndicadores:OF DF IF TF SF ZF AF PF CF- - - - x x x x XCorrige el resultado en AL de la resta de dos números BCD empaquetados, convirtiéndolo también en un valor BCD empaquetado. Si el nibble inferior tiene un valor mayor que 9 o AF es 1, a AL se le resta 6, AF se pone a 1. Si el nibble mas significativo es mayor que 9 ó CF está a 1, entonces se resta 60h a AL y se activa después CF.

Ejemplo:SUB AL, BLDASEn el ejemplo anterior, si AL y BL contenían dos números BCD empaquetados, DAS hace que el resultado de la resta (en AL) siga siendo también un BCD empaquetado.AAM (Ajuste ASCII para la multiplicación).Sintaxis:AAMIndicadores:OF DF IF TF SF ZF AF PF CF? - - - x x ? x ?Corrige el resultado en AX del producto de dos números BCD no empaquetados, convirtiéndolo en un valor BCD también no empaquetado. En AH sitúa el cociente de AL/10 quedando en AL el resto de dicha operación.Ejemplo:MUL BLAAMEn el ejemplo, tras el producto de dos números BCD no empaquetados colocados en AL y BL, el resultado (por medio de AAA) sigue siendo, en AX, un número BCD no empaquetado.AAD (Ajuste ASCII para la división).Sintaxis:AADIndicadores:OF DF IF TF SF ZF AF PF CF? - - - x x ? x ?Convierte dos números BCD no empaquetados contenidos en AH y AL en un dividendo de un byte que queda almacenado en AL. Tras la operación AH queda a cero. Esta instrucción es necesaria ANTES de la operación de dividir, al contrario que AAM.Ejemplo:AADDIV BLEn el ejemplo, tras convertir los dos números BCD no empaquetados (en AX) en un dividendo válido, la instrucción de dividir genera un resultado correcto.CBW (Conversión de byte en palabra).Sintaxis:CBWIndicadores: OF DF IF TF SF ZF AF PF CF- - - - - - - - -Copia el bit 7 del registro AL en todos los bits del registro AH, es decir, expande el signo de AL a AX como paso previo a una operación de 16 bits.CWD (conversión de palabra a doble palabra).Sintaxis:CWDIndicadores: OF DF IF TF SF ZF AF PF CF- - - - - - - - -Expande el signo del registro AX sobre el registro DX, copiando el bit más significativo deAH en todo DX.Instrucciones AritméticasADC (Suma con acarreo). Sintaxis: ADC destino, origen Indicadores:

OF DF IF TF SF ZF AF PF CF x - - - x x x x x Suma los operandos origen, destino y el valor del indicador de acarreo (0 ó 1) y el resultado lo almacena en el operando destino. Se utiliza normalmente para sumar números grandes, de más de 16 bits, en varios pasos, considerando lo que nos llevamos (el acarreo) de la suma anterior. Ejemplo: ADC AX,BX ADD (suma). Sintaxis: ADD destino, origen Indicadores: OF DF IF TF SF ZF AF PF CFx - - - x x x x xSuma los operandos origen y destino almacenando el resultado en el operando destino.Se activa el acarreo si se desborda el registro destino durante la suma.Ejemplos:ADD AX, BXADD CL, DHINC (Incrementar).Sintaxis:INC destinoIndicadores:OF DF IF TF SF ZF AF PF CFx - - - x x x x -Incrementa el operando destino. El operando destino puede ser byte o palabra.Obsérvese que esta instrucción no modifica el bit de acarreo (CF) y no es posible detectar un desbordamiento por este procedimiento (utilícese ZF).Ejemplos:INC ALINC ES:[DI]INC SS: [BP+4]INC WORD PTR CS: [BX+DI+7]CMP (Comparación).Sintaxis:CMP destino, origenIndicadores:OF DF IF TF SF ZF AF PF CFx - - - x x x x xResta origen de destino sin retornar ningún resultado. Los operandos quedan inalterados, paro los indicadores pueden ser consultados mediante instrucciones de bifurcación condicional. Los operandos pueden ser de tipo byte o palabra pero ambos de la misma dimensión.Ejemplo:CMP BX, MEM_PALCMP CH, CLDEC (Decrementar).Sintaxis:DEC destinoIndicadores:OF DF IF TF SF ZF AF PF CFx - - -x x x x -Resta una unidad del operando destino. El operando puede ser byte o palabra. Obsérvese que esta instrucción no modifica el bit de acarreo (CF) y no es posible detectar un desbordamiento por este procedimiento (utilícese ZF).Ejemplo:

DEC AXDEC MEM_BYTENEG (Negación).Sintaxis:NEG destinoIndicadores:OF DF IF TF SF ZF AF PF CFx - - -x x x x xCalcula el valor negativo en complemento a dos del operando y devuelve el resultado en el mismo operando.Ejemplo:NEG ALSBB (resta con acarreo).Sintaxis: SBB destino, origenIndicadores:OF DF IF TF SF ZF AF PF CFx - - - x x x x x

Resta el operando origen del operando destino y el resultado lo almacena en el operando destino. Si está a 1 el indicador de acarreo además resta una unidad más. Los operandos pueden ser de tipo byte o palabra. Se utiliza normalmente para restar números grandes de más de 16 bits, en varios pasos, considerando lo que nos llevamos (el acarreo) de la resta anterior.Ejemplo:SBB AX, AXSBB CH, DHSUB (Resta).Sintaxis:SUB destino, origenIndicadores:OF DF IF TF SF ZF AF PF CFx - - - x x x x xResta el operando destino al operando origen, colocando el resultado en el operando destino. Los operandos pueden tener o no signo, siendo necesario que sean del mismo tipo, byte o palabra.Ejemplos:SUB AL, BLSUB DX, DXIMUL (multiplicación entera con signo).Sintaxis:IMUL origen (origen no puede ser operando inmediato en 8086, sí en 286)Indicadores: OF DF IF TF SF ZF AF PF CFx - - - ? ? ? ? xMultiplica un operando origen con signo de longitud byte o palabra por AL o AX respectivamente. Si origen es un byte el resultado se guarda en AH (byte más significativo) y en AL (menos significativo), si origen es una palabra el resultado es devuelto en DX (parte alta) y AX (parte baja). Si las mitades más significativas son distintas de cero, independientemente del signo, CF y OF son activados.Ejemplo:IMUL BXIMUL CHMUL (multiplicación sin signo).Sintaxis:MUL origen (origen no puede ser operando inmediato)Indicadores: OF DF IF TF SF ZF AF PF CF

x - - - ? ? ? ? xMultiplica el contenido sin signo del acumulador por el operando origen. Si el operando destino es un byte el acumulador es AL guardando el resultado en AH y AL, si el contenido de AH es distinto de 0 activa los indicadores CF y OF. Cuando el operando origen es de longitud palabra el acumulador es AX quedando el resultado sobre DX y AX, si el valor de DX es distinto de cero los indicadores CF y OF se activan.Ejemplo:MUL BYTE PTR DS: [DI]MUL DXMUL CLDesbordamientos.Este alerta con los desbordamientos en las operaciones aritméticas. Ya que un byte solo permite el uso de un bit de signo y siete de datos (desde -128 hasta +127), una operación aritmética puede exceder con facilidad la capacidad de un registro de un byte. Y una suma en el registro AL, que exceda su capacidad puede provocar resultados inesperados.Byte por byte.Para multiplicar dos números de un byte, el multiplicando esta en el registro AL y el multiplicador es un byte en memoria o en otro registro. Para la instrucción MUL DL, la operación multiplica el contenido del AL por el contenido del DL. El producto generado esta en el registro AX. La operación ignora y borra cualquier información que pueda estar en el AH.

Antes de MultiplicarDespués de Multiplicar

Palabra por palabra.Para multiplicar dos números de una palabra, el multiplicando esta en el registro AX y el multiplicador es una palabra en memoria o en otro registro. Para la instrucción MUL DX, la operación multiplica el contenido del AX por el contenido del DX. El producto generado es una palabra doble que necesita dos registros: la parte de orden alto (mas a la izquierda) en el DX y la parte de orden bajo (mas a la derecha) en el AX. La operación ignora y borra cualquier información que puede estar en el DX.

Palabra doble por palabra doble.Para multiplicar dos números de palabras dobles, el multiplicando esta en el registro EAX y el multiplicador es una palabra doble en memoria o en otro registro. El producto es generado en el par EDX:EAX. La operación ignora y borra cualquier información que ya este en el EDX.

En los ejemplos siguientes, el multiplicador esta en un registro, el cual especifica el tipo de operación:INSTRUCCIÓN MULTIPLICADOR MULTIPLICANDO PRODUCTOMUL CL byte AL AXMUL BXpalabra AX DX:AXMUL EBX palabra doble EAX EDX:EAXEn los ejemplos siguientes, los multiplicadores están definidos en memoria:BYTE1 DB ?

WORD1 DW ? DWORD1 DD ?OPERACION MULTIPLICADOR MULTIPLICANDO PRODUCTO MUL BYTE1 BYTE1 AL AXMUL WORD1 WORD1 AX DX:AXMUL DWORD1 DWORD1 EAX EDX:EAX

DIV (División sin signo).Sintaxis:DIV origen (origen no puede ser operando inmediato).Indicadores:OF DF IF TF SF ZF AF PF CF? - - - ? ? ? ? ?Divide, sin considerar el signo, un número contenido en el acumulador y su extensión (AH, AL si el operando es de tipo byte o DX, AX si el operando es palabra) entre el operando fuente. El cociente se guarda en AL o AX y el resto en AH o DX según el operando sea byte o palabra respectivamente. DX o AH deben ser cero antes de la operación. Cuando el cociente es mayor que el resultado máximo que puede almacenar, cociente y resto quedan indefinidos produciéndose una interrupción 0. En caso de que las partes más significativas del cociente tengan un valor distinto de cero se activan los indicadores CF y OF.Ejemplo:DIV BLDIV MEM_PAL

IDIV (División entera).Sintaxis:IDIV origen (origen no puede ser operando inmediato).Indicadores: OF DF IF TF SF ZF AF PF CF? - - - ? ? ? ? ?Divide, considerando el signo, un número contenido en el acumulador y su extensión entre el operando fuente. El cociente se almacena en AL o AX según el operando sea byte o palabra y de igual manera el resto en AH o DX. DX o AH deben ser cero antes de la operación. Cuando el cociente es positivo y superior al valor máximo que puede almacenarse (7fh ó 7fffh), o cuando el cociente es negativo e inferior al valor mínimo que puede almacenarse (81h u 8001h) entonces cociente y resto quedan indefinidos, generándose una interrupción 0, lo que también sucede si el divisor es 0.Ejemplo:IDIV BLIDIV BX

Las operaciones de división básicas son byte entre byte, palabra entre palabra y palabras dobles entre palabra dobles.Palabra entre palabraAquí el dividendo esta en el AX y el divisor es un byte en memoria o en otro registro. Después de la división, el residuo esta en el AH y el cociente esta en el AL. Ya que un cociente de un byte es muy pequeño -si es sin signo, un máximo de +255 (FFH) y con signo +127 (7FH)- esta operación tiene un uso limitado. Palabra doble entre palabra.Para esta operación, el dividendo esta en el par DX:AX y el divisor es una palabra en memoria o en otro registro. Después de la división, el residuo esta en el DX y el cociente esta en el AX. El cociente de una palabra permite para datos sin signo un máximo de +32, 767 (FFFFH) y con signo +16, 383 (7FFFH). Tenemos:

Palabra cuádruple entre palabra doble.Al dividir una palabra cuádruple entre una palabra doble, el dividendo esta en el par EDX:EAX y el divisor está en una palabra doble en memoria o en otro registro. Después de la división, el residuo esta en el EDX y el cociente en el AEX.

En los ejemplos siguientes, de DIV, los divisores están en un registro, que determina el tipo de operación:OPERACIÓN DIVISOR DIVIDENDO COCIENTE RESIDUODIV CL byte AX AL AHDIV CX palabra DX:AX AX DXDIV EBXpalabra doble EDX:EAX EAX EDXEn los ejemplos siguientes de DIV, los divisores están definidos en memoria:BYTE1 DB ?WORD1 DW ?DWORD1 DD ?...DIVISOR DIVIDENDO COCIENTE RESIDUODIV BYTE1 BYTE1 AX AL AHDIV WORD1 WORD1 DX:AX AX DXDIV DWORD1 DWORD1 EDX:EAX EAX EDXInstrucciones de la pila.Estas instrucciones permiten el uso de la pila para almacenar y extraer datos. Instrucción POPPropósito: Recupera un dato de la pilaSintaxis:POP destino Esta instrucción transfiere el último valor almacenado en la pila al operando destino, después incrementa en dos el registro SP. La instrucción POP CS, poco útil, no funciona correctamente en los 286 y superiores.Este incremento se debe a que la pila va creciendo desde la dirección más alta de memoria del segmento hacia la más baja, y la pila solo trabaja con palabras (2 bytes), entonces al incrementar en dos el registro SP realmente se le está restando dos al tamaño real de la pila. Ejemplos:

POP AXPOP PEPE

Instrucción POPFPropósito: Extrae las banderas almacenadas en la pila.Sintaxis: POPF Este comando transfiere bits de la palabra almacenada en la parte superior de la pila hacia el registro de banderas.La forma de transferencia es la siguiente:BIT BANDERA 0 CF 2 PF 4 AF 6 ZF 7 SF 8 TF 9 IF 10 DF 11 OF Estas localizaciones son las mismas para el comando PUSHF

Una vez hecha la transferencia se incrementa en 2 el registro SP disminuyendo así el tamaño de la pila. Instrucción PUSH Propósito: Coloca una palabra en la pila.Sintaxis: PUSH fuente La instrucción PUSH decrementa en dos el valor de SP y luego transfiere el contenido del operando fuente a la nueva dirección resultante en el registro recién modificado.El decremento en la dirección se debe a que al agregar valores a la pila ésta crece de la dirección mayor a la dirección menor del segmento, por lo tanto al restarle 2 al valor del registro SP lo que hacemos es aumentar el tamaño de la pila en dos bytes, que es la única cantidad de información que puede manejar la pila en cada entrada y salida de datos. Ejemplo:

PUSH CSInstrucción PUSHFPropósito: Coloca el valor de las banderas en la pilaSintaxis: PUSHF Este comando decrementa en 2 el valor del registro SP y luego se transfiere el contenido del registro de banderas a la pila, en la dirección indicada por SP.Las banderas quedan almacenadas en memoria en los mismos bits indicados en el comando POPF.Instrucciones de Desplazamiento LinealAL/SHL (Desplazamiento aritmético a la izquierda).Sintaxis:SAL/SHL destino, contadorIndicadores:OF DF IF TF SF ZF AF PF CFX - - - x x ? x XDesplaza a la izquierda los bits del operando el número de bits especificado en el segundo operando que debe ser CL si es mayor que 1 los bits desplazados.

SAR (Desplazamiento aritmético a la derecha).Sintaxis:SAR destino, contadorIndicadores:OF DF IF TF SF ZF AF PF CFX - - - x x ? x xDesplaza a la derecha los bits del operando destino el número de bits especificado en el segundo operando. Los bits de la izquierda se rellenan con el bit de signo del primer operando. Si el número de bits a desplazar es 1 se puede especificar directamente, si es mayor se especifica a través de CL.

Ejemplos:SAR AX, CLSAR BP,1SHR (Desplazamiento lógico a la derecha).Sintaxis:SHR destino, contadorIndicadores:OF DF IF TF SF ZF AF PF CFX - - - x x ? x xDesplaza a la derecha los bits del operando destino el número de los bits especificados en el segundo operando. Los bits de la izquierda se llena con cero. Si el número de bits a desplazar es 1 se puede especificar directamente en el caso en que no ocurra se pone el valor en CL:

Ejemplos:SHR AX,CLSHR CL,1AND (y lógico).Sintaxis:AND destino, origenIndicadores: OF DF IF TF SF ZF AF PF CF0 - - - x x ? x 0Realiza una operación de Y lógico entre el operando origen y destino quedando el resultado en el destino. Son válidos operandos byte o palabra, pero ambos del mismo tipo.Ejemplos:AND AX,BXAND BL, BYTE PTR ES:[SI+10H]NOT (No lógico).Sintaxis:NOT destinoIndicadores: OF DF IF TF SF ZF AF PF CF- - - - - - - - -Realiza el complemento a uno del operando destino, invirtiendo cada uno de sus bits. Los indicadores no resultan afectados.Ejemplo:NOT AXOR (O lógico).Sintaxis:OR destino, origenIndicadores:OF DF IF TF SF ZF AF PF CF0 - - - x x ? x 0Realiza una operación O lógico a nivel de bits entre los dos operandos,almacenándose después el resultado en el operando destino.Ejemplo:OR AX,BXXOR (O exclusivo).Sintaxis:XOR destino, origenIndicadores:OF DF IF TF SF ZF AF PF CF0 - - - x x ? x 0Operación OR exclusivo a nivel de bits entre los operandos origen y destino almacenándose el resultado en este último.Ejemplo:XOR DI, AXInstrucciones de Desplazamiento CircularRCL (Rotación a la izquierda con acarreo).Sintaxis:RCL destino, contadorIndicadores:OF DF IF TF SF ZF AF PF CFx - - - - - - - x

Rotar a la izquierda los bits del operando destino junto con el indicador de acarreo CF el número de bits especificado en el segundo operando. Si el número de bits a desplazar es 1, se puede especificar directamente, en caso contrario el valor debe cargarse en CL y especificar CL como segundo operando. No es conveniente que CL sea mayor de 7, en bytes; ó 15, en palabras.Ejemplos:RCL AX,1RCL AL,CLRCL DI,1RCR (Rotación a la derecha con acarreo).Sintaxis:RCR destino, contadorIndicadores:OF DF IF TF SF ZF AF PF CFx - - - - - - - xRotar a la derecha los bits del operando destino junto con el indicador de acarreo CF el número de bits especificado en el segundo operando. Si el número de bits es 1 se puede especificar directamente; en caso contrario su valor debe cargarse en CL y especificar CL como segundo operando:Ejemplos:RCR BX,CLRCR BX,ROL (Rotación a la izquierda).Sintaxis:ROL destino, contadorIndicadores:OF DF IF TF SF ZF AF PF CFx - - - - - - - xRota a la izquierda los bits del operando destino el número de bits especificado en el segundo operando, que puede ser 1 ó CL previamente cargado con el valor del número de veces.Ejemplos:ROL DX,CLROL AH,1ROR (Rotación a la derecha).Sintaxis:ROR destino, contadorIndicadores:OF DF IF TF SF ZF AF PF CFx - - - - - - - xRota a la derecha los bits del operando destino el número de bits especificado en el segundo operando. Si el número de bits es 1 se puede poner directamente, en caso contrario debe ponerse a través de CL.Ejemplos:ROR CL,1ROR AX,CL

Procesos de ControlNOP (Operación nula).Sintaxis:NOPIndicadores: OF DF IF TF SF ZF AF PF CF- - - - - - - - -Realiza una operación nula, es decir, el microprocesador decodifica la instrucción y pasaa la siguiente. Realmente se trata de la instrucción XCHG AX,AX.ESC (Salida a un coprocesador).

Sintaxis:ESC código_operación, origenIndicadores: OF DF IF TF SF ZF AF PF CF- - - - - - - - -Se utiliza en combinación con procesadores externos, tales como los coprocesadores de coma flotante o de E/S, y abre al dispositivo externo el acceso a las direcciones y operandos requeridos. Al mnemónico ESC le siguen los códigos de operación apropiados para el coprocesador así como la instrucción y la dirección del operando necesario.Ejemplo:ESC 21,AXHLT (Parada hasta interrupción o reset).Sintaxis:HLTIndicadores:OF DF IF TF SF ZF AF PF CF- - - - - - - - -El procesador se detiene hasta que se restaura el sistema o se recibe una interrupción. Como en los PC se producen normalmente 18,2 interrupciones de tipo 8 por segundo (del temporizador) algunos programadores utilizan HLT para hacer pausas y bucles de retardo. Sin embargo, el método no es preciso y puede fallar con ciertos controladores de memoria.LOCK (Bloquea los buses).Sintaxis:LOCKIndicadores:OF DF IF TF SF ZF AF PF CF- - - - - - - - -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 por LOCK, el procesador bloquea inmediatamente el bus, introduciendo una señal por la patilla LOCK.WAIT (Espera).Sintaxis:WAITIndicadores:OF DF IF TF SF ZF AF PF CF- - - - - - - - -Provoca la espera del procesador hasta que se detecta una señal en la patilla TEST. Ocurre, por ejemplo, cuando el coprocesador ha terminado una operación e indica su finalización. Suele preceder a ESC para sincronizar las acciones del procesador y coprocesador.XLAT (traducción).Sintaxis:XLAT tablaIndicadores: OF DF IF TF SF ZF AF PF CF- - - - - - - - -La instrucción XLAT tabla carga en el registro AL el contenido de la posición [BX][AL], en donde el registro BX ha de apuntar al comienzo de una tabla. Dicho de otra manera, AL hace de índice de la tabla y de almacén destino del contenido de la tabla.Por ejemplo, el siguiente programa:DATOS SEGMENTTABLA DB 2, 3, 5, 8, 16, 23DATOS ENDSCODIGO SEGMENT

MOVE BX, OFFSET TABLA ;Inicializa BX con la dirección donde comienza la tablaMOVE AL, 5XLAT TABLACODIGO ENDSHace que al final el contenido de AL sea 16 ya que es el quinto elemento de la tabla y AL antes de XLAT TABLA contenía el valor 5.Otro ejemplo:MOV BX, OFFSET TABLAMOV AL, 4XLAT TABLAPara finalizar con las instrucciones de transferencia veremos un grupo de tresinstrucciones:LEA o cargar dirección efectivaLDS o cargar el puntero en DSLES o cargar el puntero en ESdenominadas de transferencia de direcciones.LEA (carga dirección efectiva).Sintaxis:LEA destino, origenIndicadores:OF DF IF TF SF ZF AF PF CF- - - - - - - - -Transfiere el desplazamiento del operando fuente al operando destino. Otras instrucciones pueden a continuación utilizar el registro como desplazamiento para acceder a los datos que constituyen el objetivo. El operando destino no puede ser un registro de segmento. En general, esta instrucción es equivalente a MOV destino, OFFSET fuentey de hecho los buenos ensambladores (TASM) la codifican como MOV para economizar un byte de memoria. Sin embargo, LEA es en algunos casos más potente que MOV al permitir indicar registros de índice y desplazamiento para calcular el offset:En el ejemplo de arriba, el valor depositado en DX es elOFFSET de la etiquetaDATO Smás el registro SI. Esa sola instrucción es equivalente a estas dos:MOV DX, OFFSET DATOSADD DX, SILDS (carga un puntero utilizando DS).Sintaxis:LDS destino, origenIndicadores:OF DF IF TF SF ZF AF PF CF- - - - - - - - -Traslada un puntero de 32 bits (dirección completa de memoria compuesta por segmento y desplazamiento), al destino indicado y a DS. A partir de la dirección indicada por el operando origen, el procesador toma 4 bytes de la memoria: con los dos primeros forma una palabra que deposita endestino y, con los otros dos, otra en DS.Ejemplo:PUNT DD 12345678HLDS SI, PUNTComo resultado de esta instrucción, en DS:SI se hace referencia a la posición de memoria 1234h:5678h; 'DD' sirve para definir una variable larga de 4 bytes (denominadaPUNT en el ejemplo).LES (carga un puntero utilizando ES).Sintaxis:LES destino, origenEsta instrucción es análoga a LDS, pero utilizando ES en lugar de DBloques en ensambladorMODELOS DE MEMORIA. Los modelos de memoria constituyen las diversas maneras de acceder a la memoria por parte de los compiladores de C. En el caso del Turbo C se pueden distinguir los siguientes:

TINY: Se emplea en los programas donde es preciso apurar el consumo de memoria hasta el último byte. Los 4 registros de segmento (CS, DS, ES, SS) están asignados a la misma dirección, por lo que existe un total de 64 Kb donde se mezclan código, datos y pila. Los programas de este tipo pueden convertirse a formato COM.SMALL: Se utiliza en aplicaciones pequeñas. Los segmentos de código y datos son diferentes y no se solapan. Por ello, hay 64 kb para código y otros 64 Kb a repartir entre datos y pila.

Segmentos PunterosModelo Código Datos Pila Código DatosTiny 64 Kb near nearSmall 64 Kb 64 Kb near nearMedium 1 Mb 64 Kb far nearCompact 64 Kb 1 Mb near farLarge 1 Mb 1 Mb far farHuge 1 Mb 1 Mb(Bloques > 64 Kb) far farMEDIUM: Este modelo es ideal para programas largos que no manejan demasiados datos. Se utilizan punteros largos para el código (que puede extenderse hasta 1 Mb) y cortos para los datos: la pila y los datos juntos no pueden exceder de 64 Kb.COMPACT: Al contrario que el anterior, este modelo es el apropiado para los programas pequeños que emplean muchos datos. Por ello, el programa no puede exceder de 64 Kb aunque los datos que controla pueden alcanzar el Mb, ya que los punteros de datos son de tipo far por defecto.LARGE: Empleado en las aplicaciones grandes y también por los programadores de sistemas que no tienen paciencia para andar forzando continuamente el tipo de los punteros (para rebasar el límite de 64 Kb). Tanto los datos como el código pueden alcanzar el Mb, aunque no se admite que los datos estáticos ocupen más de 64 Kb. Este modo es el que menos problemas da para manejar la memoria, no siendo quizá tan lento y pesado como indica el fabricante.HUGE: Similar al anterior, pero con algunas ventajas: por un lado, todos los punteros son normalizados automáticamente y se admiten datos estáticos de más de 64 Kb. Por otro, y gracias a esto último, es factible manipular bloques de datos de más de 64 Kb cada uno, ya que los segmentos de los punteros se actualizan correctamente. Sin embargo, este modelo es el más costoso en tiempo de ejecución de los programas.Usando la pilaUna sección de la memoria del programa es reservado para el uso de una pila. La Intel 80386 y procesadores superiores contienen un registro llamado puntero a la pila, esp, el cual almacena la dirección del tope de la pila, la figura 1 de abajo muestra 3 valores enteros, 49, 30 y 72, almacenados en la pila(cada entero ocupando 4 bytes) con el registro esp apuntando a la dirección del tope de la pila.A diferencia de una pila creciendo hacia arriba, en las máquinas intel crecen hacia abajo. En la Figura 2 muestra las capas de la pila después de la ejecución pushl $15.El punter de la pila es decrementado de cuatro en cuatro y el número 15 es almacenando como lugares de 4 bytes, 1988, 1989, 1990 y 1991

La instrucción popl %eax copia el valor del tope de la pila(4 bytes) a eax e incrementa esp en 4. Qué sucede si no quieres copiar el valor del tope de la pila a un registro?. Puedes ejecutar la instrucción addl $4, %esp el cual simplemente incrementa el puntero de la pila.#Listing 3.globl mainmain:

movl $10, %eaxcall fooret

foo:addl $5, %eax

ret

En Listing 3, la instrucción call foo pone la dirección de la instrucción después de call en la llamada al programa sobre la pila y va hacia foo. La subrutina termina con ret, el cual transfiere el control a la instrucción cuya dirección se toma desde el tope de la pila. Obviamente el tope de la pila debe contener una dirección válidaENTRADA Y SALIDA Funciones que realiza Vamos a señalar las funciones que debe realizar un computador para ejecutar trabajos de entrada/salida:- Direccionamiento o selección del dispositivo que debe llevar a cabo la operación de E/S.- Transferencia de los datos entre el procesador y el dispositivo (en uno u otro sentido).- Sincronización y coordinación de las operaciones.Esta última función es necesaria debido a la deferencia de velocidades entre los dispositivos y la CPU y a la independencia que debe existir entre los periféricos y la CPU (por ejemplo, suelen tener relojes diferentes).Se define una transferencia elemental de información como la transmisión de una sola unidad de información (normalmente un byte) entre el procesador y el periférico o viceversa. Para efectuar una transferencia elemental de información son precisas las siguientes funciones:- Establecimiento de una comunicación física entre el procesador y el periférico para la transmisión de la unidad de información.- Control de los periféricos, en que se incluyen operaciones como prueba y modificación del estado del periférico. Para realizar estas funciones la CPU gestionará las líneas de control necesarias.Definiremos una operación de E/S como el conjunto de acciones necesarias para la transferencia de un conjunto de datos (es decir, una transferencia completa de datos). Para la realización de una operación de E/S se deben efectuar las siguientes funciones: - Recuento de las unidades de información transferidas (normalmente bytes) para reconocer el fin de operación.- Sincronización de velocidad entre la CPU y el periférico.- Detección de errores (e incluso corrección) mediante la utilización de los códigos necesarios (bits de paridad, códigos de redundancia cíclica, etc.)- Almacenamiento temporal de la información. Es más eficiente utilizar un buffer temporal específico para las operaciones de E/S que utilizan el área de datos del programa.- Conversión de códigos, conversión serie/paralelo, etc.Dispositivos externos Una de las funciones básicas del ordenador es comunicarse con los dispositivos exteriores, es decir, el ordenador debe ser capaz de enviar y recibir datos desde estos dispositivo. Sin esta función, el ordenador no sería operativo porque sus cálculos no serían visibles desde el exterior.Existe una gran variedad de dispositivos que pueden comunicarse con un ordenador, desde los dispositivos clásicos (terminales, impresoras, discos, cintas, etc.) hasta convertidores A/D y D/A para aplicaciones de medida y control de procesos, De todos los posibles periféricos, algunos son de lectura, otros de escritura y otros de lectura y escritura (es importante resaltar que este hecho siempre se mira desde el punto de vista del proceso). Por otra parte, existen periféricos de almacenamiento también llamados memorias auxiliares o masivas.La mayoría de los periféricos están compuestos por una parte mecánica y otra parte electrónica. Estas partes suelen separarse claramente para dar una mayor modularidad. A la componente electrónica del periférico se le suele denominar controlador del dispositivo o, también, adaptador del dispositivo. Si el dispositivo no tiene parte mecánica (como, por ejemplo, la pantalla de un terminal), el controlador estará formado por la parte digital del circuito. Frecuentemente los controladores de los dispositivos están alojados en una placa de circuito impreso diferenciada del resto del periférico. En este caso es bastante habitual que un mismo controlador pueda dar servicio a dispositivos de características similares.El principal problema planteado por los periféricos es su gran variedad que también afecta a las velocidades de transmisión. Por tanto, el mayor inconveniente que encontramos en los periféricos es la diferencia entre sus velocidades de transmisión y la diferencia entre éstas y la velocidad de operación del ordenador.PROCEDIMIENTOS EXTERNOSEste tipo de procedimientos permiten crear bibliotecas de funciones de ensamblador, permitiendo a su vez asemejarse más a la programación de alto nivel.El nombre del procedimiento debe estar presente, ser único y seguir las reglas para la formación de nombres del lenguaje. El operando far está relacionado con la ejecución del programa. Cuando se solicita la ejecución de un programa, el cargador de programas del DOS utiliza este nombre de procedimiento como el punto de entrada para la

primera instrucción a ejecutar. La directiva ENDP indica el fin de un procedimiento y contiene el mismo nombre que el enunciado PROC para permitir que el ensamblador relacione a los dos. Ya que los procedimientos deben estar por completo dentro de un segmento, ENDP define el final de un procedimiento antes que ENDS defina el final de un segmento. La organización de un programa en procedimientos proporciona los beneficios siguientes: 1. Reduce la cantidad de código, ya que un procedimiento común puede ser llamado desde cualquier lugar en el segmento de código. 2. Fortalece la mejor organización del programa. 3. Facilita la depuración del programa, ya que los errores pueden ser aislados con mayor claridad. 4. Ayuda en el mantenimiento progresivo de programas, ya que los procedimientos son identificados de forma rápida para su modificación. Los procedimientos externos, a diferencia de los internos, se declaran en módulos o programas separados al programa donde el procedimiento es llamado, en otras palabras, la llamada al procedimiento se encuentra en un programa y el procedimiento en otro. Para poder utilizar procedimientos externos, es necesario que sean declarados como públicos en el programa donde se encuentran y que sean llamados como externos en el programa donde serán usados. Se debe contar con tres directivas de ensamble: .PUBLIC para declarar los procedimientos como públicos, .EXTERN para indicar que el procedimiento que se va a usar está fuera del programa y .INCLUDE para enlazar el programa que contiene los procedimientos con el programa que los llama. Con estas capacidades, es fácil crear bibliotecas de procedimientos y macros que puedan ser utilizados constantemente por los demás programas, ahorrando con ello tiempo de programación al reutilizar código fuente.El segmento de código contiene el código ejecutable de un programa. También tiene uno o mas procedimientos, definidos con la directiva PROC. Un segmento que tiene solo un procedimiento puede aparecer como sigue: NOMBRE OPERACION OPERANDO COMENTARIO nomsegmento SEGMENT PARA nomproc PROC FAR ;Un ;procedimiento ;dentro ;del segmento nomproc ENDP ;de código nomsegmento ENDSOperaciones CALL y RET La instrucción CALL transfiere el control a un procedimiento llamado, y la instrucción RET regresa del procedimiento llamado al procedimiento original que hizo la llamada. RET debe ser la ultima instrucción en un procedimiento llamado. Los formatos generales para CALL y RET son: El código objeto particular que CALL y RET generan depende de si la operación implica un procedimiento NEAR (cercano) o un procedimiento FAR (lejano). Llamada y regreso cercanos. Una llamada (CALL) a un procedimiento dentro del mismo segmento es cercana y realiza lo siguiente: • Disminuye el SP en 2 (una palabra) • Mete el IP (que contiene el desplazamiento de la instrucción que sigue al CALL) en la pila. • Inserta la dirección del desplazamiento del procedimiento llamado en el IP (esta operación vacía el resultado de la instrucción previamente procesada), Un RET que regresa desde un procedimiento cercano realiza lo siguiente: • Saca el antiguo valor de IP de la pila y lo envía al IP (lo cual también vacía el resultado de la instrucción previamente procesada). • Incrementa el SP en 2. Ahora el CS:IP apunta a la instrucción que sigue al CALL original en la llamada del procedimiento, en donde se reasume la ejecución. Llamada y regreso lejanos. Una llamada (CALL) lejana llama a un procedimiento etiquetado con FAR, tal vez en un segmento de código separado. Un CALL lejano mete a la pila al CS y al IP, y RET los saca de la pila. PROCEDIMIENTOS INTERNOSProcedimiento o subrutina. Es un grupo de instrucciones que, por lo general, desempeñan una tarea. Un procedimiento es una sección de un programa que se puede volver a utilizar y que se almacena en memoria, pero se emplea tan a menudo como se necesite. Esto ahorra espacio en la memoria y facilita el desarrollo de la programación. La desventaja de usar procedimientos es que la computadora requiere tiempo para ligarse con el procedimiento y regresar desde él.La instrucción CALL liga al procedimiento y la instrucción RET regresa del procedimiento.

Ejemplo:SUMS PROC NEAR

ADD AX, BXADD AX, CXADD AX, DX

SUMS ENDPSUMS1 PROC FAR

ADD AX, BXADD AX, CXADD AX, DX

SUMS ENDPCuando se comparan estos dos procedimientos, la única diferencia es el código de operación de la instrucción para el retorno. Para NEAR el código de operación es C3H; para FAR es CBH.Cuando un procedimiento debe ser global, se debe definir como FAR. Los que realizan tareas locales se suelen definir como NEAR.Las principales ventajas en el uso de procedimientos son: permiten una codificación más limpia y compacta, es decir el código fuente es más pequeño; también permiten el ahorro de memoria, esto es porque un mismo procedimiento puede ser llamado varias veces en el mismo programa y sólo requiere memoria una vez.Las partes que componen a un procedimiento son: • Declaración del procedimiento • Código del procedimiento • Directiva de regreso • Terminación del procedimiento Por ejemplo, si queremos una rutina que nos sume dos bytes, almacenados en AH y AL cada uno y guardar la suma en el registro BX: suma PROC NEAR ;Declaración del procedimiento mov Bx, 0 ;Contenido del procedimiento mov Bl, Ah mov Ah, 00 add Bx, Ax Ret ;Directiva de regreso suma Endp ;Declaración de final del procedimiento En la declaración la primera palabra, Suma, corresponde al nombre de nuestro procedimiento, Proc lo declara como tal y la palabra Near le indica al MASM que el procedimiento es intrasegmento. La directiva Ret carga la dirección IP almacenada en la pila para regresar al programa original, por último, la directiva Suma Endp indica el final del procedimiento. Para declarar un procedimiento intersegmento sustituimos la palabra Near por la palabra FAR. El llamado de este procedimiento se realiza de la siguiente forma: Call Suma Las macros ofrecen una mayor flexibilidad en la Programación comparadas con los procedimientos, pero no por ello se dejarán de utilizar estos últimos.MACROS.Una macro es un grupo de instrucciones que efectúan una tarea. Al ser llamada se inserta en el programa como nuevo código que contiene una secuencia de instrucciones. Se utilizan las directivas MACRO y ENDM para delimitar una macrosecuencia. El primer enunciado de una macro es el que contiene el nombre y sus parámetros relacionados con ella. Por ejemplo TRANSF MACRO A,B que define la macro TRANSF. El último enunciado de una macro es la instrucción ENDM que es una línea por sí sola. Es necesario definir la macro antes de utilizarla. Una macro puede llamar a otra.Variable local en una macro. Es aquella que aparece dentro del cuerpo de la macro, pero no está disponible fuera de ella. Para definir una variable local se utiliza la directiva LOCAL. Se puede utilizar para declarar etiquetas de saltos que requieren ser llamados varias veces y evita que marque error al expandir la macro.Ejemplo: MINIMO MACRO dato1, dato2, resultado LOCAL ya_esta MOV AX,dato1 CMP AX,dato2 ; ¿es dato1 el menor? JB ya_esta ; sí MOV AX,dato2 ; no, es dato2 ya_esta: MOV resultado,AX ENDM

La etiqueta ya_esta solo aparecerá en la definición de la macro, pero al expandirse será sustituida por ??0000, ??0001, etc.Parámetros Formales y Parámetros Actuales. Cuando se llama a una macro se le pueden pasar opcionalmente un cierto número de parámetros de cierto tipo. A estos parámetros se le denominan parámetros actuales. En la definición de la macro, dichos parámetros aparecen asociados a ciertos nombres, cuya única función es permitir distinguir unos parámetros de otros e indicar el orden en que son entregados, estos son los parámetros formales. Al expandir la macro los parámetros formales son sustituidos por sus parámetros actuales.Es una buena práctica utilizar PUSH y POP al inicio y al final de las MACROS para mantener los valores de los registros, en caso de ser necesario.Si se indican más parámetros de los que una macro necesita, se ignorarán los restantes. En caso de faltar se dará un mensaje de advertencia o error, dependiendo del ensamblador. Como buena práctica se debe evitar.Ejemplo: SUMAR MACRO a,b,total PUSH AX MOV AX,a ADD AX,b MOV total,AX POP AX ENDM .... SUMAR positivos, negativos, total

Es posible que no sea válido expandir una macro. Por ejemplo ejecutar SUMAR AX, BX, DL porque DL es de 8 bits.Operador ;;Indica que lo que viene a continuación es un comentario que no debe aparecer al expansionar la macro. Cuando al ensamblar se genera un listado del programa, las macros suelen aparecer expandidas en los puntos en que se invocan; sin embargo sólo aparecerán los comentarios normales que comiencen por (;). Los comentarios relacionados con el funcionamiento interno de la macro deberían ir con (;;), los relativos al uso y sintaxis de la misma con (;). Esto es además conveniente porque durante el ensamblaje son mantenidos en memoria los comentarios de macros (no los del resto del programa) que comienzan por (;), y no conviene desperdiciar memoria.Operador & Utilizado para concatenar texto o símbolos. Es necesario para lograr que el ensamblador sustituya un parámetro dentro de una cadena de caracteres o como parte de un símbolo: SALUDO MACRO c MOV AL,"&c" etiqueta&c: CALL imprimir ENDM Al ejecutar SALUDO A se producirá la siguiente expansión: MOV AL,"A" etiquetaA: CALL imprimir Si no se hubiera colocado el & se hubiera expandido como MOV AL,"c" Cuando se utilizan estructuras repetitivas REPT, IRP o IRPC (que se verán más adelante) existe un problema adicional al intentar crear etiquetas, ya que el ensamblador se come un & al hacer la primera sustitución, generando la misma etiqueta a menos que se duplique el operador &: MEMORIA MACRO x IRP i, <1, 2> x&i DB i ENDM ENDM Si se invoca MEMORIA ET se produce el error de "etiqueta ETi repetida", que se puede salvar añadiendo tantos '&' como niveles de anidamiento halla en las estructuras repetitivas empleadas, como se ejemplifica a continuación: MEMORIA MACRO x IRP i, <1, 2> x&&i DB i ENDM ENDM

Lo que con MEMORIA ET generará correctamente las líneas: ET1 DB 1 ET2 DB 2Operador ! o <> Empleado para indicar que el carácter que viene a continuación debe ser interpretado literalmente y no como un símbolo. Por ello, !; es equivalente a <;>.Operador % Convierte la expresión que le sigue -generalmente un símbolo- a un número; la expresión debe ser una constante (no relocalizable). Sólo se emplea en los argumentos de macros. Dada la macro siguiente: PSUM MACRO mensaje, suma %OUT * mensaje, suma * ENDM

(Evidentemente, el % que precede a OUT forma parte de la directiva y no se trata del % operador que estamos tratando) Supuesta la existencia de estos símbolos: SIM1 EQU 120 SIM2 EQU 500 Invocando la macro con las siguientes condiciones: PSUM < SIM1 + SIM2 = >, (SIM1+SIM2)

Se produce la siguiente expansión: %OUT * SIM1 + SIM2 = (SIM1+SIM2) * Sin embargo, invocando la macro de la siguiente manera (con %): PSUM < SIM1 + SIM2 = >, %(SIM1+SIM2)

Se produce la expansión deseada: %OUT * SIM1 + SIM2 = 620 *Directivas PUBLIC y EXTRN(EXTERN)La directiva PUBLIC se suele colocar en el campo de código de un enunciado para definir que una etiqueta es pública, a fin de poder emplearla en otros módulos. Esta etiqueta puede ser una dirección para salto, una dirección de datos o todo un segmento. Cuando los segmentos se hacen públicos se combinan con otros segmentos públicos que contienen datos con el mismo nombre del segmento.La directiva EXTRN aparece en los segmentos de datos y de código para definir que las etiquetas son externas al segmento. Si se define que los datos son externos, su tamaño se debe expresar como BYTE, WORD o DWORD. Si una dirección para salto o para llamada son externas, se deben representar como Cercana(NEAR) o Lejana(FAR). Ejemplo:

Se le llama macro interna a aquella que se declara y se llama dentro del mismo programa.MACROS EXTERNASUna macro externa es aquella que es declarada en un archivo externo.Estos archivos también son conocidos como bibliotecas de macrosecuencias y pueden ser llamados con la directiva INCLUDE.Existe una directiva que permite que el archivo sea leído una sola vez en la primera pasada, ésta directiva es IF1… ENDIF. En sí la definición de la macro no consume memoria, por lo que es indiferente declarar muchas macros a ninguna.

REPT veces ... ENDM (Repeat) Permite repetir cierto número de veces una secuencia de instrucciones. El bloque de instrucciones se delimita con ENDM (no confundirlo con el final de una macro). Por ejemplo: REPT 2 OUT DX,AL ENDM Esta secuencia se transformará, al ensamblar, en lo siguiente: OUT DX,AL OUT DX,AL Empleando símbolos definidos con (=) y apoyándose además en las macros se puede llegar a crear pseudo-instrucciones muy potentes: SUCESION MACRO n num = 0 REPT n DB num num = num + 1 ENDM ; fin de REPT ENDM ; fin de macro La sentencia SUCESION 3 provocará la siguiente expansión: DB 0 DB 1 DB 2IRP simbolo_control, <arg1, arg2, ..., arg_n> ... ENDM (Indefinite repeat) Es relativamente similar a la instrucción FOR de los lenguajes de alto nivel. Los ángulos (<) y (>) son obligatorios. El símbolo de control va tomando sucesivamente los valores (no necesariamente numéricos) arg1, arg2, ... y recorre en cada pasada todo el bloque de instrucciones hasta alcanzar el ENDM (no confundirlo con fin de macro) sustituyendo simbolo_control por esos valores en todos los lugares en que aparece: IRP i, <1,2,3> DB 0, i, i*i ENDM Al expansionarse, este conjunto de instrucciones se convierte en lo siguiente: DB 0, 1, 1 DB 0, 2, 4 DB 0, 3, 9 Nota: Todo lo encerrado entre los ángulos se considera un único parámetro. Un (;) dentro de los ángulos no se interpreta como el inicio de un comentario sino como un elemento más. Por otra parte, al emplear macros anidadas, deben indicarse tantos símbolos angulares '<' y '>' consecutivos como niveles de anidamiento existan. Lógicamente, dentro de una macro también resulta bastante útil la estructura IRP: TETRAOUT MACRO p1, p2, p3, p4, valor PUSH AX PUSH DX MOV AL,valor IRP cn, <p1, p2, p3, p4> MOV DX, cn OUT DX, AL ENDM ; fin de IRP POP DX POP AX ENDM ; fin de macro

Al ejecutar TETRAOUT 318h, 1C9h, 2D1h, 1A4h, 17 se obtendrá: PUSH AX PUSH DX MOV AL, 17 MOV DX, 318h OUT DX, AL MOV DX, 1C9h OUT DX, AL

MOV DX, 2D1h OUT DX, AL MOV DX, 1A4h

OUT DX,AL POP DX POP AX

Cuando se pasan listas como parámetros hay que encerrarlas entre '<' y '>' al llamar, para no confundirlas con elementos independientes. Por ejemplo, supuesta la macro INCD: INCD MACRO lista, p IRP i, <lista> INC i ENDM ; fin de IRP DEC p ENDM ; fin de macro

Se comprende la necesidad de utilizar los ángulos: INCD AX, BX, CX, DX se expandirá: INC AX DEC BX; CX y DX se ignoran (4 parámetros)

INCD <AX, BX, CX>, DX se expandirá: INC AX INC BX INC CX DEC DX ; (2 parámetros)

* IRPC simbolo_control, <c1c2 ... cn> ... ENDM (Indefinite repeat character) Esta directiva es similar a la anterior, con una salvedad: los elementos situados entre los ángulos (<) y (>) -ahora opcionales, por cierto- son caracteres ASCII y no van separados por comas: IRPC i, <813> DB i ENDM El bloque anterior generará al expandirse:

DB 8DB 1DB 3

Ejemplo de utilización dentro de una macro (en combinación con el operador &): INICIALIZA MACRO a, b, c, dIRPC iter, <&a&b&c&d>DB iterENDM ; fin de IRPCENDM ; fin de macro

Al ejecutar INICIALIZA 7, 1, 4, 0 se produce la siguiente expansión: DB 7DB 1DB 4DB 0EXITM

Sirve para abortar la ejecución de un bloque MACRO, REPT, IRP ó IRPC. Normalmente se utiliza apoyándose en una directiva condicional (IF...ELSE...ENDIF). Al salir del bloque, se pasa al nivel inmediatamente superior (que puede ser otro bloque de estos). Como ejemplo, la siguiente macro reserva n bytes de memoria a cero hasta un máximo de 100, colocando un byte 255 al final del bloque reservado: MALLOC MACRO n maximo=100 REPT n IF maximo EQ 0 ; ¿ya van 100? EXITM ; abandonar REPT ENDIF maximo = maximo - 1 DB 0 ; reservar byte ENDM DB 255 ; byte de fin de bloque ENDM

existe la posibilidad de chequear condicionalmente la presencia de un parámetro por medio de IFNB, o su ausencia con IFB. Uniendo esto a la potencia de IRP es posible crear macros extraordinariamente versátiles. Como ejemplo, valga la siguiente macro, destinada a introducir en la pila un número variable de parámetros (hasta 10): es especialmente útil en los programas que gestionan interrupciones: XPUSH MACRO R1,R2,R3,R4,R5,R6,R7,R8,R9,R10 IRP reg, <R1,R2,R3,R4,R5,R6,R7,R8,R9,R10> IFNB <reg> PUSH reg ENDIF ENDM ; fin de IRP ENDM ; fin de XPUSH Por ejemplo, la instrucción: XPUSH AX,BX,DS,ES,VAR1 Se expandirá en: PUSH AX PUSH AX PUSH DS PUSH ES PUSH VAR1 El ejemplo anterior es ilustrativo del mecanismo de comprobación de presencia de parámetros. Sin embargo, este ejemplo puede ser optimizado notablemente empleando una lista como único parámetro: XPUSH MACRO lista IRP i, <lista> PUSH i ENDM ENDM XPOP MACRO lista IRP i, <lista> POP i ENDM ENDM La ventaja es el número indefinido de parámetros soportados (no sólo 10). Un ejemplo de uso puede ser el siguiente: XPUSH <AX, BX, CX> XPOP <CX, BX, AX>Que al expandirse queda: PUSH AX PUSH BX PUSH CX POP CX POP BX POP AX