computadora s

Upload: nibia-martinez

Post on 15-Oct-2015

25 views

Category:

Documents


0 download

TRANSCRIPT

Captulo I: INTRODUCCIN

1.1. -NUMEROS BINARIOS, OCTALES Y HEXADECIMALES.

El sistema de numeracin utilizado habitualmente es la base 10; es decir, consta de 10 dgitos (0-9) que podemos colocar en grupos, ordenados de izquierda a derecha y de mayor a menor.

Cada posicin tiene un valor o peso de 10ndondenrepresenta el lugar contado por la derecha:

1357 = 1 x 103+ 3 x 102+ 5 x 101+ 7 x 100Explcitamente, se indica la base de numeracin como 135710.

En un ordenador el sistema de numeracin esbinario-en base 2, utilizando el 0 y el 1- hecho propiciado por ser precisamente dos los estados estables en los dispositivos digitales que componen una computadora.

Anlogamente a la base 10, cada posicin tiene un valor de 2ndondenes la posicin contando desde la derecha y empezando por 0:

1012= 1 x 22+ 0 x 21+ 1 x 20Adems, por su importancia y utilidad, es necesario conocer otros sistemas de numeracin como pueden ser eloctal(base 8) y elhexadecimal(base 16). En este ltimo tenemos, adems de los nmeros del 0 al 9, letras -normalmente en maysculas- de la A a la F.

Llegar a un nmero en estos sistemas desde base 2 es realmente sencillo si agrupamos las cifras binarias de 3 en 3 (octal) o de 4 en 4 (hexadecimal):

Base 2 a base 8: 101 0112= 538Base 2 a base 16: 0010 10112= 2B16A la inversa, basta convertir cada dgito octal o hexadecimal en binario:

Base 8 a base 2: 248= 010 1002Base 16 a base 2: 2416= 0010 01002De ahora en adelante, se utilizarn una serie de sufijos para determinar el sistema de numeracin empleado:

SufijoBaseEjemplos

b201101010b

o,q8175o

d10789d

h166A5h

En caso de que no aparezca el sufijo, el nmero se considera decimal; es decir, en base 10.

1.2. -CAMBIO DE BASE.Pese a que las conversiones entre base 2 y base 8 y 16 son prcticamente directas, existe un sistema general para realizar el cambio de una base a otra. El paso de cualquier base a base 10 lo vimos antes:

6A5h = 6 x 162+ 10 x 161+ 5 x 160Inversamente, si queremos pasar de base 10 a cualquier otra habr que realizar sucesivas divisiones por la base y tomar los restos:

donde 4 es el ltimo cociente (menor que la base) y los restantes dgitos son los restos en orden inverso.

1.3. -ESTRUCTURA ELEMENTAL DE LA MEMORIA.

1.3.1. - BIT.

Toda la memoria del ordenador se compone de dispositivos electrnicos que pueden adoptar nicamente dos estados, que representamos matemticamente por 0 y 1. Cualquiera de estas unidades de informacin se denominaBIT, contraccin de binary digit en ingls.

1.3.2. - BYTE.

Cada grupo de 8 bits se conoce comobyteu octeto. Es la unidad de almacenamiento en memoria, la cual est constituida por un elevado nmero de posiciones que almacenan bytes. La cantidad de memoria de que dispone un sistema se mide en Kilobytes (1 Kb = 1024 bytes), en Megabytes (1 Mb = 1024 Kb), Gigabytes (1 Gb = 1024 Mb), Terabytes (1 Tb = 1024 Gb) o Petabytes (1 Pb = 1024 Tb).

Los bits en un byte se numeran de derecha a izquierda y de 0 a 7, correspondiendo con los exponentes de las potencias de 2 que reflejan el valor de cada posicin. Un byte nos permite, por tanto, representar 256 estados (de 0 a 255) segn la combinacin de bits que tomemos.

1.3.3. - NIBBLE.

Cada grupo de cuatro bits de un byte constituye unnibble, de forma que los dos nibbles de un byte se llaman nibble superior (el compuesto por los bits 4 a 7) e inferior (el compuesto por los bits 0 a 3). El nibble tiene gran utilidad debido a que cada uno almacena un dgito hexadecimal:

BinarioHex.DecimalBinarioHex.Decimal

000000100088

000111100199

0010221010A10

0011331011B11

0100441100C12

0101551101D13

0110661110E14

0111771111F15

1.4. -OPERACIONES ARITMTICAS SENCILLAS EN BINARIO.

Para sumar nmeros, tanto en base 2 como hexadecimal, se sigue el mismo proceso que en base 10:

Podemos observar que la suma se desa-

1010 1010b rrolla de la forma tradicional; es decir:

+ 0011 1100b sumamos normalmente, salvo en el caso de

-------------- 1 + 1 = 102 , en cuyo caso tenemos un aca-

1110 0110b rreo de 1 (lo que nos llevamos).

1.5. - COMPLEMENTO A DOS.

En general, se define como valor negativo de un nmero el que necesitamos sumarlo para obtener 00h, por ejemplo:

FFh Como en un byte solo tenemos dos nibbles, es

+ 01h decir, dos dgitos hexadecimales, el resultado es

------ 0 (observar cmo el 1 ms significativo subrayado

100h es ignorado). Luego FFh=-1. Normalmente, el bit 7

se considera como de signo y, si est activo (a 1)

el nmero es negativo.

Por esta razn, el nmero 80h, cuyo complemento a dos es l mismo, se considera negativo (-128) y el nmero 00h, positivo. En general, para hallar el complemento a dos de un nmero cualquiera basta con calcular primero sucomplemento a uno, que consiste en cambiar los unos por ceros y los ceros por unos en su notacin binaria; a continuacin se le suma una unidad para calcular elcomplemento a dos. Con una calculadora, la operacin es ms sencilla: el complemento a dos de un nmeroAdenbits es2n-A.

Otro factor a considerar es cuando se pasa de operar con un nmero de cierto tamao (ej., 8 bits) a otro mayor (pongamos de 16 bits). Si el nmero es positivo, la parte que se aadepor la izquierdason bits a 0. Sin embargo, si era negativo (bit ms significativo activo) la parte que se aade por la izquierda son bits a 1. Este fenmeno, en cuya demostracin matemtica no entraremos, se puede resumir en que el bit ms significativo se copia en todos los aadidos: es lo que se denomina laextensin del signo: los dos siguientes nmeros son realmente el mismo nmero (el -310): 11012(4 bits) y 111111012(8 bits).

1.6. -AGRUPACIONES DE BYTES.TipoDefinicin

Palabra2 bytes contiguos

Doble palabra2 palabras contiguas (4 bytes)

Cudruple palabra4 palabras contiguas (8 bytes)

Prrafo16 bytes

Pgina256 bytes, 16 Kb, etc.

Segmento64 Kbytes

1.7. -REPRESENTACIN DE LOS DATOS EN MEMORIA.

1.7.1. -NUMEROS BINARIOS: mximo nmero representable:

TipoSin signo

1 byte255

2 bytes65.535

4 bytes4.294.967.295

8 bytes18.446.744.073.709.551.615

TipoPositivoNegativo

1 byte127-128

2 bytes32.767-32.768

4 bytes2.147.483.647-2.147.483.648

8 bytes9.223.372.036.854.775.807-9.223.372.036.854.775.808

Los nmeros binarios de ms de un byte se almacenan en la memoria en los procesadores de Intel en orden inverso: 01234567h se almacenara: 67h, 45h, 23h, 01h.

1.7.2. -NUMEROS BINARIOS CODIFICADOS EN DECIMAL (BCD).

Consiste en emplear cuatro bits para codificar los dgitos del 0 al 9 (desperdiciando las seis combinaciones que van de la 1010 a la 1111). La ventaja es la simplicidad de conversin a/de base 10, que resulta inmediata. Los nmeros BCD pueden almacenarse desempaquetados, en cuyo caso cada byte contiene un dgitoBCD(Binary-Coded Decimal); o empaquetados, almacenando dos dgitos por byte (para construir los nmeros que van del 00 al 99). La notacinBCDocupa cuatro bits -un nibble- por cifra, de forma que en el formato desempaquetado el nibble superior siempre es 0.

1.7.3. -NUMEROS EN PUNTO FLOTANTE.

Son grupos de bytes en los que una parte se emplea para guardar las cifras del nmero (mantisa) y otra para indicar la posicin del punto flotante (exponente), de modo equivalente a la notacin cientfica. Esto permite trabajar con nmeros de muy elevado tamao -segn el exponente- y con una mayor o menor precisin en funcin de los bits empleados para codificar la mantisa.

1.7.4. -CDIGO ASCII.

El cdigo A.S.C.I.I. (American Standard Code for Information Interchange) es un convenio adoptado para asignar a cada carcter un valor numrico; su origen est en los comienzos de la Informtica tomando como muestra algunos cdigos de la transmisin de informacin de radioteletipo. Se trata de un cdigo de 7 bits con capacidad para 128 smbolos que incluyen todos los caracteres alfanumricos del ingls, con smbolos de puntuacin y algunos caracteres de control de la transmisin.

Con posterioridad, con la aparicin de los microordenadores y la gran expansin entre ellos de los IBM-PC y compatibles, la ampliacin del cdigo ASCII realizada por esta marca a 8 bits, con capacidad para 128 smbolos adicionales, experimenta un considerable auge, siendo en la actualidad muy utilizada y recibiendo la denominacin oficial de pgina de cdigos 437 (EEUU). Se puede consultar al final de este libro. Es habitualmente la nica pgina soportada por las BIOS de los PC. Para ciertas nacionalidades se han diseado otras pginas especficas que requieren de un software externo. En las lenguas del estado espaol y en las de la mayora de los dems pases de la UE, esta tabla cubre todas las necesidades del idioma.

1.8. -OPERACIONES LGICAS EN BINARIO.

Se realizan a nivel de bit y pueden ser de uno o dos operandos:

xNOT (x)

01

10

x yx AND yx OR yx XOR y

0 0000

0 1011

1 0011

1 1110

Captulo II: ARQUITECTURA E HISTORIA DE LOS MICROORDENADORES

El ensamblador es un lenguaje de programacin que, por la traduccin directa de los mnemnicos a instrucciones maquina, permite realizar aplicaciones rpidas, solucionando situaciones en las que los tiempos de ejecucin constituye el factor principal para que el proceso discurra con la suficiente fluidez. Esta situacin, que indudablemente s influye sobre la eleccin del lenguaje de programacin a utilizar en el desarrollo de una determinada rutina, y dada la aparicin de nuevos compiladores de lenguajes de alto nivel que optimizan el cdigo generado a niveles muy prximos a los que un buen programador es capaz de realizar en ensamblador, no es la nica razn para su utilizacin.

Es sobradamente conocido que los actuales sistemas operativos son programados en su mayor parte en lenguajes de alto nivel, especialmente C, pero siempre hay una parte en la que el ensamblador se hace casi insustituible bajo DOS y es la programacin de losdriverspara los controladores de dispositivos, relacionados con las tareas de ms bajo nivel de una mquina, fundamentalmente las operaciones de entrada/salida en las que es preciso actuar directamente sobre los demschipsque acompaan al microprocesador. Por ello y porque las instrucciones del lenguaje ensamblador estn ntimamente ligadas a la mquina, vamos a realizar primero un somero repaso a la arquitectura interna de un microordenador.

2.1. -ARQUITECTURA VON NEWMAN.

Centrndonos en los ordenadores sobre los que vamos a trabajar desarrollar a grandes rasgos la arquitecturaVon Newmanque, si bien no es la primera en aparecer, s que lo hizo prcticamente desde el comienzo de los ordenadores y se sigue desarrollando actualmente. Claro es que est siendo desplazada por otra que permiten una mayor velocidad de proceso, laRISC.

En los primeros tiempos de los ordenadores, con sistemas de numeracin decimal, una electrnica sumamente complicada muy susceptible a fallos y un sistema de programacin cableado o mediante fichas, Von Newman propuso dos conceptos bsicos que revolucionaran la incipiente informtica:

a)La utilizacin del sistema de numeracin binario. Simplificaba enormemente los problemas que la implementacin electrnica de las operaciones y funciones lgicas planteaban, a la vez proporcionaba una mayor inmunidad a los fallos (electrnica digital).

b)Almacenamiento de la secuencia de instrucciones de que consta el programa en una memoria interna, fcilmente accesible, junto con los datos que referencia. De este forma la velocidad de proceso experimenta un considerable incremento; recordemos que anteriormente una instruccin o un dato estaban codificados en una ficha en el mejor de los casos.

Tomando como modelo las mquinas que aparecieron incorporando las anteriores caractersticas, el ordenador se puede considerar compuesto por las siguientes partes:

- La Unidad Central de Proceso, U.C.P., ms conocida por sus siglas en ingls (CPU).- La Memoria Interna, MI.- Unidad de Entrada y Salida, E/S.- Memoria masiva Externa, ME.

Realicemos a continuacin una descripcin de lo que se entiende por cada una de estas partes y cmo estn relacionadas entre si:

- La Unidad Central de Proceso (CPU) viene a ser el cerebro del ordenador y tiene por misin efectuar las operaciones aritmtico-lgicas y controlar las transferencias de informacin a realizar.

- La Memoria Interna (MI) contiene el conjunto de instrucciones que ejecuta la CPU en el transcurso de un programa. Es tambin donde se almacenan temporalmente las variables del mismo, todos los datos que se precisan y todos los resultados que devuelve.

- Unidades de entrada y salida (E/S) o Input/Output (I/O): son las encargadas de la comunicacin de la mquina con el exterior, proporcionando al operador una forma de introducir al ordenador tanto los programas como los datos y obtener los resultados.

Como es de suponer, estas tres partes principales de que consta el ordenador deben estar ntimamente conectadas; aparece en este momento el concepto de bus: el bus es un conjunto de lneas que enlazan los distintos componentes del ordenador, por ellas se realiza la transferencia de datos entre todos sus elementos.

Se distinguen tres tipos de bus:

-De control: forman parte de l las lneas que seleccionan desde dnde y hacia dnde va dirigida la informacin, tambin las que marcan la secuencia de los pasos a seguir para dicha transferencia.-De datos: por l, de forma bidireccional, fluyen los datos entre las distintas partes del ordenador.-De direcciones: como vimos, la memoria est dividida en pequeas unidades de almacenamiento que contienen las instrucciones del programa y los datos. El bus de direcciones consta de un conjunto de lneas que permite seleccionar de qu posicin de la memoria se quiere leer su contenido. Tambin direcciona los puertos de E/S.

La forma de operar del ordenador en su conjunto es direccionar una posicin de la memoria en busca de una instruccin mediante el bus de direcciones, llevar la instruccin a la unidad central de proceso -CPU- por medio del bus de datos, marcando la secuencia de la transferencia el bus de control. En la CPU la instruccin se decodifica, interpretando qu operandos necesita: si son de memoria, es necesario llevarles a la CPU; una vez que la operacin es realizada, si es preciso se devuelve el resultado a la memoria.

2.2. -EL MICROPROCESADOR.

Un salto importante en la evolucin de los ordenadores lo introdujo el microprocesador: se trata de una unidad central de proceso contenida totalmente en un circuito integrado. Comenzaba as la gran carrera en busca de lo ms rpido, ms pequeo; rpidamente el mundo del ordenador empez a ser accesible a pequeas empresas e incluso a nivel domstico: es elboomde los microordenadores personales. Aunque cuando entremos en la descripcin de los microprocesadores objeto de nuestro estudio lo ampliaremos, har un pequeo comentario de las partes del microprocesador:

- Unidad aritmtico-lgica: Es donde se efectan las operaciones aritmticas (suma, resta, y a veces producto y divisin) y lgicas (and, or, not, etc.).- Decodificador de instrucciones: All se interpretan las instrucciones que van llegando y que componen el programa.- Bloque de registros: Los registros son celdas de memoria en donde queda almacenado un dato temporalmente. Existe un registro especial llamado de indicadores, estado o flags, que refleja el estado operativo del microprocesador.- Bloque de control de buses internos y externos: supervisa todo el proceso de transferencias de informacin dentro del microprocesador y fuera de l.

3.2. -REGISTROS DEL 8086 Y DEL 286.

Estos procesadores disponen de 14 registros de 16 bits (el 286 alguno ms, pero no se suele emplear bajo DOS). La misin de estos registros es almacenar las posiciones de memoria que van a experimentar repetidas manipulaciones, ya que los accesos a memoria son mucho ms lentos que los accesos a los registros. Adems, hay ciertas operaciones que slo se pueden realizar sobre los registros. No todos los registros sirven para almacenar datos, algunos estn especializados en apuntar a las direcciones de memoria. La mecnica bsica de funcionamiento de un programa consiste en cargar los registros con datos de la memoria o de un puerto de E/S, procesar los datos y devolver el resultado a la memoria o a otro puerto de E/S. Obviamente, si un dato slo va a experimentar un cambio, es preferible realizar la operacin directamente sobre la memoria, si ello es posible. A continuacin se describen los registros del 8086.

AXSPCSIP

BXBPDSflags

CXSISS

DXDIES

Registros de datosRegistros punteros de pila e ndicesRegistros de segmentoRegistro puntero de instrucciones y flags

-Registros de datos:

AX, BX, CX, DX: pueden utilizarse bien como registros de 16 bits o como dos registros separados de 8 bits (byte superior e inferior) cambiando la X por H o L segn queramos referirnos a la parte alta o baja respectivamente. Por ejemplo, AX se descompone en AH (parte alta) y AL (parte baja). Evidentemente, cualquier cambio sobre AH o AL altera AX!: valga como ejemplo que al incrementar AH se le estn aadiendo 256 unidades a AX.

AX = Acumulador.

Es el registro principal, es utilizado en las instrucciones de multiplicacin y divisin y en algunas instrucciones aritmticas especializadas, as como en ciertas operaciones de carcter especfico como entrada, salida y traduccin. Obsrvese que el 8086 es suficientemente potente para realizar las operaciones lgicas, la suma y la resta sobre cualquier registro de datos, no necesariamente el acumulador.

BX = Base.Se usa como registro base para referenciar direcciones de memoria con direccionamiento indirecto, manteniendo la direccin de la base o comienzo de tablas o matrices. De esta manera, no es preciso indicar una posicin de memoria fija, sino lanmero BX(as, haciendo avanzar de unidad en unidad a BX, por ejemplo, se puede ir accediendo a un gran bloque de memoria en un bucle).

CX = Contador.Se utiliza comnmente como contador en bucles y operaciones repetitivas de manejo de cadenas. En las instrucciones de desplazamiento y rotacin se utiliza como contador de 8 bits.

DX = Datos.Usado en conjuncin con AX en las operaciones de multiplicacin y divisin que involucran o generan datos de 32 bits. En las de entrada y salida se emplea para especificar la direccin del puerto E/S.

- Registros de segmento:

Definen reas de 64 Kb dentro del espacio de direcciones de 1 Mb del 8086. Estas reas pueden solaparse total o parcialmente. No es posible acceder a una posicin de memoria no definida por algn segmento: si es preciso, habr de moverse alguno.

CS = Registro de segmento de cdigo (code segment).Contiene la direccin del segmento con las instrucciones del programa. Los programas de ms de 64 Kb requieren cambiar CS peridicamente.

DS = Registro de segmento de datos (data segment).Segmento del rea de datos del programa.

SS = Registro de segmento de pila (stack segment).Segmento de pila.

ES = Registro de segmento extra (extra segment).Segmento de ampliacin para zona de datos. Es extraordinariamente til actuando en conjuncin con DS: con ambos se puede definir dos zonas de 64 Kb, tan alejadas como se desee en el espacio de direcciones, entre las que se pueden intercambiar datos.

- Registros punteros de pila:

SP = Puntero de pila (stack pointer).Apunta a la cabeza de la pila. Utilizado en las instrucciones de manejo de la pila.

BP = Puntero base (base pointer).Es un puntero de base, que apunta a una zona dentro de la pila dedicada al almacenamiento de datos (variables locales y parmetros de las funciones en los programas compilados).

-Registros ndices:

SI = ndice fuente (source index).Utilizado como registro de ndice en ciertos modos de direccionamiento indirecto, tambin se emplea para guardar un valor de desplazamiento en operaciones de cadenas.

DI = ndice destino (destination index).Se usa en determinados modos de direccionamiento indirecto y para almacenar un desplazamiento en operaciones con cadenas.

-Puntero de instruccioneso contador de programa:

IP = Puntero de instruccin (instruction pointer).Marca el desplazamiento de la instruccin en curso dentro del segmento de cdigo. Es automticamente modificado con la lectura de una instruccin.

-Registro de estadoo de indicadores (flags).

Es un registro de 16 bits de los cuales 9 son utilizados para indicar diversas situaciones durante la ejecucin de un programa. Los bits 0, 2, 4, 6, 7 y 11 son indicadores de condicin, que reflejan los resultados de operaciones del programa; los bits del 8 al 10 son indicadores de control y el resto no se utilizan. Estos indicadores pueden ser comprobados por las instrucciones de salto condicional, lo que permite variar el flujo secuencial del programa segn el resultado de las operaciones.

1514131211109876543210

OFDFIFTFSFZFAFPFCF

CF (Carry Flag): Indicador de acarreo. Su valor ms habitual eslo que nos llevamosen una suma o resta.

OF (Overflow Flag): Indicador de desbordamiento. Indica que el resultado de una operacin no cabe en el tamao del operando destino.

ZF (Zero Flag): Indicador de resultado 0 o comparacin igual.

SF (Sign Flag): Indicador de resultado o comparacin negativa.

PF (Parity Flag): Indicador de paridad. Se activa tras algunas operaciones aritmtico-lgicas para indicar que el nmero de bits a uno resultante es par.

AF (Auxiliary Flag): Para ajuste en operaciones BCD.

DF (Direction Flag): Indicador de direccin. Manipulando bloques de memoria, indica el sentido de avance (ascendente/descendente).

IF (Interrupt Flag): Indicador de interrupciones: puesto a 1 estn permitidas.

TF (Trap Flag): Indicador de atrape (ejecucin paso a paso).

3.3. -REGISTROS DEL 386 Y PROCESADORES SUPERIORES.

Los 386 y superiores disponen de muchos ms registros de los que vamos a ver ahora. Sin embargo, bajo el sistema operativo DOS slo se suelen emplear los que veremos, que constituyen bsicamente una extensin a 32 bits de los registros originales del 8086.

Se ampla el tamao de los registros de datos (que pueden ser accedidos en fragmentos de 8, 16 32 bits) y se aaden dos nuevos registros de segmento multipropsito (FS y GS). Algunos de los registros aqu mostrados son realmente de 32 bits (como EIP en vez de IP), pero bajo sistema operativo DOS no pueden ser empleados de manera directa, por lo que no les consideraremos.

3.4. -MODOS DE DIRECCIONAMIENTO.

Son los distintos modos de acceder a los datos en memoria por parte del procesador. Antes de ver los modos de direccionamiento, echaremos un vistazo a la sintaxis general de las instrucciones, ya que pondremos alguna en los ejemplos:

INSTRUCCINDESTINO, FUENTE

Donde destino indica dnde se deja el resultado de la operacin en la que pueden participar (segn casos) FUENTE e incluso el propio DESTINO. Hay instrucciones, sin embargo, que slo tienen un operando, como la siguiente, e incluso ninguno:

INSTRUCCINDESTINO

Como ejemplos, aunque no hemos visto an las instrucciones utilizaremos un par de ellas: la de copia o movimiento de datos (MOV) y la de suma (ADD).

3.4.1. -ORGANIZACIN DE DIRECCIONES: SEGMENTACIN.

Como ya sabemos, los microprocesadores 8086 y compatibles poseen registros de un tamao mximo de 16 bits que direccionaran hasta 64K; en cambio, la direccin se compone de 20 bits con capacidad para 1Mb, hay por tanto que recurrir a algn artificio para direccionar toda la memoria. Dicho artificio consiste en lasegmentacin: se trata de dividir la memoria en grupos de 64K. Cada grupo se asocia con un registro de segmento; el desplazamiento (offset) dentro de ese segmento lo proporciona otro registro de 16 bits. La direccin absoluta se calcula multiplicando por 16 el valor del registro de segmento y sumando el offset, obtenindose una direccin efectiva de 20 bits. Esto equivale a concebir el mecanismo de generacin de la direccin absoluta, como si se tratase de que los registros de segmento tuvieran 4 bits a 0 (imaginarios) a la derecha antes de sumarles el desplazamiento:

direccin = segmento * 16 + offset

En la prctica, una direccin se indica con la notacin SEGMENTO:OFFSET; adems, una misma direccin puede expresarse de ms de una manera: por ejemplo, 3D00h:0300h es equivalente a 3D30:0000h. Es importante resaltar que no se puede acceder a ms de 64 Kb en un segmento de datos. Por ello, en los procesadores 386 y superiores no se deben emplear registros de 32 bit para generar direcciones (bajo DOS), aunque para los clculos pueden ser interesantes (no obstante, s sera posible configurar estos procesadores para poder direccionar ms memoria bajo DOS con los registros de 32 bits, aunque no resulta por lo general prctico).

3.4.2. -MODOS DE DIRECCIONAMIENTO.

- Direccionamientoinmediato: El operando es una constante situada detrs del cdigo de la instruccin. Sin embargo, como registro destino no se puede indicar uno de segmento (habr que utilizar uno de datos como paso intermedio).

ADD AX,0fffh

El nmero hexadecimal 0fffh es la constante numrica que en el direccionamiento inmediato se le sumar al registro AX. Al trabajar con ensambladores, se pueden definir smbolosconstantes(ojo, no variables) y es ms intuitivo:

dato EQU 0fffh ; smbolo constante

MOV AX,dato

Si se referencia a la direccin de memoria de una variable de la siguiente forma, tambin se trata de un caso de direccionamiento inmediato:

dato DW 0fffh ; ahora es una variable

MO AX,OFFSET dato ; AX = "direccin de memoria" de datoPorque hay que tener en cuenta que cuando traduzcamos a nmeros el smbolo podra quedar:

17F3:0A11 DW FFF

MOV AX,0A11

- Direccionamientode registro: Los operandos, necesariamente de igual tamao, estn contenidos en los registros indicados en la instruccin:

MOV DX,AX

MOV AH,AL

- Direccionamientodirecto o absoluto: El operando est situado en la direccin indicada en la instruccin, relativa al segmento que se trate:

MOV AX,[57D1h]

MOV AX,ES:[429Ch]

Esta sintaxis (quitando la 'h' de hexadecimal) sera la que admite el programa DEBUG (realmente habra que poner, en el segundo caso, ES: en una lnea y el MOV en otra). Al trabajar con ensambladores, lasvariablesen memoria se pueden referenciar con etiquetas simblicas:

MOV AX,dato

MOV AX,ES:dato

dato DW 1234h ; variable del programa

En el primer ejemplo se transfiere a AX el valor contenido en la direccin apuntada por la etiquetadatosobre el segmento de datos (DS) que se asume por defecto; en el segundo ejemplo se indica de forma explcita el segmento tratndose del segmento ES. La direccin efectiva se calcula de la forma ya vista con anterioridad: Registro de segmento*16+desplazamiento_de_dato (este desplazamiento depende de la posicin al ensamblar el programa).

- Direccionamientoindirecto: El operando se encuentra en una direccin sealada por un registro de segmento*16 ms un registro base (BX/BP) o ndice (SI/DI). (Nota: BP acta por defecto con SS).

MOV AX,[BP] ; AX = [SS*16+BP]

MOV ES:[DI],AX ; [ES*16+DI] = AX

-Indirecto con ndice o indexado: El operando se encuentra en una direccin determinada por la suma de un registro de segmento*16, un registro de ndice, SI o DI y un desplazamiento de 8 16 bits. Ejemplos:

MOV AX,[DI+DESP] MOV AX,desp[DI]

ADD [SI+DESP],BX ADD desp[SI],BX

-Indirecto con base e ndice o indexado a base: El operando se encuentra en una direccin especificada por la suma de un registro de segmento*16, uno de base, uno de ndice y opcionalmente un desplazamiento de 8 16 bits:

MOV AX,ES:[BX+DI+DESP] MOV AX,ES:desp[BX][DI]

MOV CS:[BX+SI+DESP],CX MOV CS:desp[BX][SI],CX

Combinaciones de registros de segmento y desplazamiento.

Como se ve en los modos de direccionamiento, hay casos en los que se indica explcitamente el registro de segmento a usar para acceder a los datos. Existen unos segmentos asociados por defecto a los registros de desplazamiento (IP, SP, BP, BX, DI, SI); slo es necesario declarar el segmento cuando no coincide con el asignado por defecto. En ese caso, el ensamblador genera un byte adicional (a modo de prefijo) para indicar cul es el segmento referenciado. La siguiente tabla relaciona las posibles combinaciones de los registros de segmento y los de desplazamiento:

CSSSDSES

IPSNoNoNo

SPNoSNoNo

BPcon prefijopor defectocon prefijocon prefijo

BXcon prefijocon prefijopor defectocon prefijo

SIcon prefijocon prefijopor defectocon prefijo

DIcon prefijocon prefijopor defectocon prefijo(1)

(1) Tambin por defecto en el manejo de cadenas.

Los 386 y superiores admiten otros modos de direccionamiento ms sofisticados, que se vern en el prximo captulo, despus de conocer todas las instrucciones del 8086. Por ahora, con todos estos modos se puede considerar que hay ms que suficiente. De hecho, algunos se utilizan en muy contadas ocasiones.

3.5. -LA PILA.

La pila es un bloque de memoria de estructuraLIFO(Last Input First Output: ltimo en entrar, primero en salir) que se direcciona mediante desplazamientos desde el registro SS (segmento de pila). Las posiciones individuales dentro de la pila se calculan sumando al contenido del segmento de pila SS un desplazamiento contenido en el registro puntero de pila SP. Todos los datos que se almacenan en la pila son de longitud palabra, y cada vez que se introduce algo en ella por medio de las instrucciones de manejo de pila (PUSH y POP), el puntero se decrementa en dos; es decir, la pila avanza hacia direcciones decrecientes. El registro BP suele utilizarse normalmente para apuntar a una cierta posicin de la pila y acceder indexadamente a sus elementos -generalmente en el caso de variables- sin necesidad de desapilarlos para consultarlos.

La pila es utilizada frecuentemente al principio de una subrutina para preservar los registros que no se desean modificar; al final de la subrutina basta con recuperarlos en orden inverso al que fueron depositados. En estas operaciones conviene tener cuidado, ya que la pila en los 8086 es comn al procesador y al usuario, por lo que se almacenan en ella tambin las direcciones de retorno de las subrutinas. Esta ltima es, de hecho, la ms importante de sus funciones. La estructura de pila permite que unas subrutinas llamen a otras que a su vez pueden llamar a otras y as sucesivamente: en la pila se almacenan las direcciones de retorno, que sern las de la siguiente instruccin que provoc la llamada a la subrutina. As, al retornar de la subrutina se extrae de la pila la direccin a donde volver. Los compiladores de los lenguajes de alto nivel la emplean tambin para pasar los parmetros de los procedimientos y para generar en ella las variablesautomticas-variables locales que existen durante la ejecucin del subprograma y se destruyen inmediatamente despus-. Por ello, una norma bsica es que se debe desapilar siempre todo lo apilado para evitar una prdida de control inmediata del ordenador.

Ejemplo de operacin sobre la pila (todos los datos son arbitrarios):

3.6. -UN PROGRAMA DE EJEMPLO.

Aunque las instrucciones del procesador no sern vistas hasta el prximo captulo, con objeto de ayudar a la imaginacin del lector elaboraremos un primer programa de ejemplo en lenguaje ensamblador. La utilidad de este programa es dejar patente que lo nico que entiende el 8086 son nmeros, aunque nosotros nos referiremos a ellos con unos smbolos que faciliten entenderlos. Tambin es interesante este ejemplo para afianzar el concepto de registro de segmento.

En este programa slo vamos a emplear las instrucciones MOV, ya conocida, y alguna otra ms como la instruccin INC (incrementar), DEC (disminuir una unidad) y JNZ (saltar si el resultado no es cero). Suponemos que el programa est ubicado a partir de la direccin de memoria 14D3:7A10 (arbitrariamente elegida) y que lo que pretendemos hacer con l es limpiar la pantalla. Como el ordenador es un PC con monitor en color, la pantalla de texto comienza en B800:0000 (no es ms que una zona de memoria). Por cada carcter que hay en dicha pantalla, comenzando arriba a la izquierda, a partir de la direccin B800:0000 tenemos dos bytes: el primero, con el cdigo ASCII del carcter y el segundo con el color. Lo que vamos a hacer es rellenar los 2000 caracteres (80 columnas x 25 lneas) con espacios en blanco (cdigo ASCII 32, 20h en hexadecimal), sin modificar el color que hubiera antes. Esto es, se trata de poner el valor 32 en la direccin B800:0000, la B800:0002, la B800:0004... y as sucesivamente.

El programa quedara en memoria de esta manera: La primera columna indica la direccin de memoria donde est el programa que se ejecuta (CS=14D3h e IP=7A10h al principio). La segunda columna constituye el cdigo mquina que interpreta el 8086. Algunas instrucciones ocupan un byte de memoria, otras dos tres (las hay de ms). La tercera columna contiene el nombre de las instrucciones, algo mucho ms legible para los humanos que los nmeros:

14D3:7A10 B9 D0 07 MOV CX,7D0H ; CX = 7D0h (2000 decimal = 7D0 hexadecimal)

14D3:7A13 B8 00 B8 MOV AX,0B800h ; segmento de la memoria de pantalla

14D3:7A16 8E D8 MOV DS,AX ; apuntar segmento de datos a la misma

14D3:7A18 BB 00 00 MOV BX,0 ; apuntar al primer carcter ASCII de la pantalla

14D3:7A1B C6 07 20 MOV BYTE PTR [BX],32 ; se pone BYTE PTR para indicar que 32 es de 8 bits

14D3:7A1E 43 INC BX ; BX=BX+1 -< apuntar al byte de color

14D3:7A1F 43 INC BX ; BX=BX+1 -< apuntar al siguiente carcter ASCII

14D3:7A20 49 DEC CX ; CX=CX-1 -< queda un carcter menos

14D3:7A21 75 F8 JNZ -8 ; si CX no es 0, saltar 8 bytes atrs (a 14D3:7A1B)

Como se puede ver, la segunda instruccin (bytes de cdigo mquina 0B8h, 0 y 0B8h colocados en posiciones consecutivas) est colocada a partir del desplazamiento 7A13h, ya que la anterior que ocupaba 3 bytes comenzaba en 7A10h. En el ejemplo cargamos el valor 0B800h en DS apoyndonos en AX como intermediario. El motivo es que los registros de segmento no admiten el direccionamiento inmediato. A medida que se van haciendo programas, el ensamblador da mensajes de error cuando se encuentra con estos fallos y permite ir aprendiendo con facilidad las normas, que tampoco son demasiadas. La instruccinMOV BYTE PTR [BX],32equivale a decir:poner en la direccin de memoria apuntada por BX(DS:[BX] para ser ms exactos)el byte de valor 32. El valor 0F8h del cdigo mquina de la ltima instruccin es el complemento a dos (nmero negativo) del valor 8.

Normalmente, casi nunca habr que ensamblara manoconsultando unas tablas, como hemos hecho en este ejemplo. Sin embargo, la mejor manera de aprender ensamblador es no olvidando la estrecha relacin de cada lnea de programa con la CPU y la memoria.

Captulo IV: JUEGO DE INSTRUCCIONES 80x86

4.1. -DESCRIPCIN COMPLETA DE LAS INSTRUCCIONES.

Nota: en el efecto de las instrucciones sobre el registro de estado se utilizar la siguiente notacin:- bit no modificado? desconocido o indefinidox modificado segn el resultado de la operacin1 puesto siempre a 10 puesto siempre a 0

4.1.1. -INSTRUCCIONES DE CARGA DE REGISTROS Y DIRECCIONES.

MOV (transferencia)

Sintaxis: MOV dest, origen.

Indicadores: OF DF IF TF SF ZF AF PF CF

- - - - - - - - -

Transfiere datos de longitud byte o palabra del operando origen al operando destino. Pueden ser operando origen y operando destino cualquier registro o posicin de memoria direccionada de las formas ya vistas, con la nica condicin de que origen y destino tengan la misma dimensin. Existen ciertas limitaciones, como que los registros de segmento no admiten el direccionamiento inmediato: es incorrecto MOV DS,4000h; pero no lo es por ejemplo MOV DS,AX o MOV DS,VARIABLE. No es posible, as mismo, utilizar CS como destino (es incorrecto hacer MOV CS,AX aunque pueda admitirlo algn ensamblador). Al hacer MOV hacia un registro de segmento, las interrupciones quedan inhibidas hastadespusde ejecutarse la siguiente instruccin (8086/88 de 1983 y procesadores posteriores).

Ejemplos: mov ds,ax

mov bx,es:[si]

mov si,offset dato

En el ltimo ejemplo, no se coloca en SI el valor de la variabledatosino su direccin de memoria o desplazamiento respecto al segmento de datos. En otras palabras, SI es un puntero adatopero no esdato. En el prximo captulo se ver cmo se declaran las variables.

XCHG (intercambiar)

Sintaxis: XCHG destino, origen

Indicadores: OF DF IF TF SF ZF AF PF CF

- - - - - - - - -

Intercambia el contenido de los operandos origen y destino. No pueden utilizarse registros de segmentos como operandos.

Ejemplo: xchg bl,ch

xchg mem_pal,bx

XLAT (traduccin)

Sintaxis: XLAT tabla

Indicadores: OF DF IF TF SF ZF AF PF CF

- - - - - - - - -

Se utiliza para traducir un byte del registro AL a un byte tomado de la tabla de traduccin. Los datos se toman desde una direccin de la tabla correspondiente a BX + AL, donde bx es un puntero a el comienzo de la tabla y AL es un ndice. Indicartablaal lado de xlat es slo una redundancia opcional.

Ejemplo: mov bx,offset tabla

mov al,4

xlat

LEA (carga direccin efectiva)

Sintaxis: LEA destino, origen

Indicadores: OF DF IF TF SF ZF AF PF CF

- - - - - - - - -

Transfiere el desplazamiento del operando fuente al operando destino. Otras instrucciones pueden a continuacin 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 instruccin es equivalente aMOV 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 ms potente que MOV al permitir indicar registros de ndice y desplazamiento para calcular el offset:

lea dx,datos[si]

En el ejemplo de arriba, el valor depositado en DX es el offset de la etiquetadatosms el registro SI. Esa sola instruccin es equivalente a estas dos:

mov dx,offset datos

add dx,si

LDS (carga un puntero utilizando DS)

Sintaxis: LDS destino, origen

Indicadores: OF DF IF TF SF ZF AF PF CF

- - - - - - - - -

Traslada un puntero de 32 bits (direccin completa de memoria compuesta porsegmento y desplazamiento), al destino indicado y a DS. A partir de la direccin indicada por el operando origen, el procesador toma 4 bytes de la memoria: con los dos primeros forma una palabra que deposita endestinoy, con los otros dos, otra en DS.

Ejemplo: punt dd 12345678h

lds si,punt

Como resultado de esta instruccin, en DS:SI se hace referencia a la posicin de memoria 1234h:5678h; 'dd' sirve para definir una variable larga de 4 bytes (denominadapunten el ejemplo) y ser explicado en el captulo siguiente.

LES (carga un puntero utilizando ES)

Sintaxis: LES destino, origen

Esta instruccin es anloga a LDS, pero utilizando ES en lugar de DS.

LAHF (carga AH con los indicadores)

Sintaxis: LAHF

Indicadores: OF DF IF TF SF ZF AF PF CF

- - - - - - - - -

Carga los bits 7, 6, 4, 2 y 0 del registro AH con el contenido de los indicadores SF, ZF, AF, PF Y CF respectivamente. El contenido de los dems bits queda sin definir.

SAHF (copia AH en los indicadores)

Sintaxis: SAHF

Indicadores: OF DF IF TF SF ZF AF PF CF

- - - - x x x x x

Transfiere el contenido de los bits 7, 6, 4, 2 y 0 a los indicadores SF, ZF, AF, PF y CF respectivamente.

4.1.2. -INSTRUCCIONES DE MANIPULACIN DEL REGISTRO DE ESTADO.

CLC (baja el indicador de acarreo)

Sintaxis: CLC

Indicadores: OF DF IF TF SF ZF AF PF CF

- - - - - - - - 0

Borra el indicador de acarreo (CF) sin afectar a ninguno otro.

CLD (baja el indicador de direccin)

Sintaxis: CLD

Indicadores: OF DF IF TF SF ZF AF PF CF

- 0 - - - - - - -

Pone a 0 el indicador de direccin DF, por lo que los registros SI y/o DI se autoincrementan en las operaciones de cadenas, sin afectar al resto de los indicadores. Es NECESARIO colocarlo antes de las instrucciones de manejo de cadenas si no se conoce con seguridad el valor de DF. Vase STD.

CLI (baja indicador de interrupcin)

Sintaxis: CLI

Indicadores: OF DF IF TF SF ZF AF PF CF

- - 0 - - - - - -

Borra el indicador de activacin de interrupciones IF, lo que desactiva las interrupciones enmascarables. Es muy conveniente hacer esto antes de modificar la pareja SS:SP en los 8086/88 anteriores a 1983 (vase comentario en la instruccin MOV), o antes de cambiar un vector de interrupcin sin el apoyo del DOS. Generalmente las interrupciones slo se inhiben por breves instantes en momentos crticos. Vase tambin STI.

CMC (complementa el indicador de acarreo)

Sintaxis: CMC

Indicadores: OF DF IF TF SF ZF AF PF CF

- - - - - - - - x

Complementa el indicador de acarreo CF invirtiendo su estado.

STC (pone a uno el indicador de acarreo)

Sintaxis: STC

Indicadores: OF DF IF TF SF ZF AF PF CF

- - - - - - - - 1

Pone a 1 el indicador de acarreo CF sin afectar a ningn otro indicador.

STD (pone a uno el indicador de direccin)

Sintaxis: STD

Indicadores: OF DF IF TF SF ZF AF PF CF

- 1 - - - - - - -

Pone a 1 el indicador de direccin DF, por lo que los registros SI y/o DI se autodecrementan en las operaciones de cadenas, sin afectar al resto de los indicadores. Es NECESARIO colocarlo antes de las instrucciones de manejo de cadenas si no se conoce con seguridad el estado de DF. Vase tambin CLD.

STI (pone a uno el indicador de interrupcin)

Sintaxis: STI

Indicadores: OF DF IF TF SF ZF AF PF CF

- - 1 - - - - - -

Pone a 1 la bandera de desactivacin de interrupciones IF y activa las interrupciones enmascarables. Una interrupcin pendiente no es reconocida, sin embargo, hasta despus de ejecutar la instruccin que sigue a STI. Vase tambin CLI.

4.1.3. -INSTRUCCIONES DE MANEJO DE LA PILA.

POP (extraer de la pila)

Sintaxis: POP destino

Indicadores: OF DF IF TF SF ZF AF PF CF

- - - - - - - - -

Transfiere el elemento palabra que se encuentra en lo alto de la pila (apuntado por SP) al operando destino que a de ser tipo palabra, e incrementa en dos el registro SP. La instruccin POP CS, poco til, no funciona correctamente en los 286 y superiores.

Ejemplos: pop ax

pop pepe

PUSH (introduce en la pila)

Sintaxis: PUSH origen

Indicadores: OF DF IF TF SF ZF AF PF CF

- - - - - - - - -

Decrementa el puntero de pila (SP) en 2 y luego transfiere la palabra especificada en el operando origen a la cima de la pila. El registro CS aqu s se puede especificar como origen, al contrario de lo que afirman algunas publicaciones.

Ejemplo: push cs

POPF (extrae los indicadores de la pila)

Sintaxis: POPF

Indicadores: OF DF IF TF SF ZF AF PF CF

x x x x x x x x x

Traslada al registro de los indicadores la palabra almacenada en la cima de la pila; a continuacin el puntero de pila SP se incrementa en dos.

PUSHF (introduce los indicadores en la pila)

Sintaxis: PUSHF

Indicadores: OF DF IF TF SF ZF AF PF CF

- - - - - - - - -

Decrementa en dos el puntero de pila y traslada a la cima de la pila el contenido de los indicadores.

4.1.4. -INSTRUCCIONES DE TRANSFERENCIA DE CONTROL.

Incondicional

CALL (llamada a subrutina)

Sintaxis: CALL destino

Indicadores: OF DF IF TF SF ZF AF PF CF

- - - - - - - - -

Transfiere el control del programa a un procedimiento, salvando previamente en la pila la direccin de la instruccin siguiente, para poder volver a ella una vez ejecutado el procedimiento. El procedimiento puede estar en el mismo segmento (tipo NEAR) o en otro segmento (tipo FAR). A su vez la llamada puede ser directa a una etiqueta (especificando el tipo de llamada NEAR -por defecto- o FAR) o indirecta, indicando la direccin donde se encuentra el puntero. Segn la llamada sea cercana o lejana, se almacena en la pila una direccin de retorno de 16 bits o dos palabras de 16 bits indicando en este ltimo caso tanto el offset (IP) como el segmento (CS) a donde volver.

Ejemplos: call proc1

dir dd 0f000e987h

call dword ptr dir

En el segundo ejemplo, la variable dir almacena la direccin a donde saltar. De esta ltima manera -conociendo su direccin- puede llamarse tambin a un vector de interrupcin, guardando previamente los flags en la pila (PUSHF), porque la rutina de interrupcin retornar (con IRET en vez de con RETF) sacndolos.

JMP (salto)

Sintaxis: JMP direccin o JMP SHORT direccin

Indicadores: OF DF IF TF SF ZF AF PF CF

- - - - - - - - -

Transfiere el control incondicionalmente a la direccin indicada en el operando. La bifurcacin puede ser tambin directa o indirecta como anteriormente vimos, pero adems puede ser corta (tipo SHORT) con un desplazamiento comprendido entre -128 y 127; o larga, con un desplazamiento de dos bytes con signo. Si se hace un JMP SHORT y no llega el salto (porque est demasiado alejada esa etiqueta) el ensamblador dar error. Los buenos ensambladores (como TASM) cuando dan dos pasadas colocan all donde es posible un salto corto, para economizar memoria, sin que el programador tenga que ocuparse de ponershort. Si el salto de dos bytes, que permite desplazamientos de 64 Kb en la memoria sigue siendo insuficiente, se puede indicar confarque es largo (salto a otro segmento).

Ejemplos: jmp etiqueta

jmp far ptr etiqueta

RET / RETF (retorno de subrutina)

Sintaxis: RET [valor] o RETF [valor]

Indicadores: OF DF IF TF SF ZF AF PF CF

- - - - - - - - -

Retorna de un procedimiento extrayendo de la pila la direccin de la siguiente direccin. Se extraer el registro de segmento y el desplazamiento en un procedimiento de tipo FAR (dos palabras) y solo el desplazamiento en un procedimiento NEAR (una palabra). si esta instruccin es colocada dentro de un bloque PROC-ENDP (como se ver en el siguiente captulo) el ensamblador sabe el tipo de retorno que debe hacer, segn el procedimiento sea NEAR o FAR. En cualquier caso, se puede forzar que el retorno sea de tipo FAR con la instruccin RETF.Valor, si es indicado permite sumar una cantidadvaloren bytes a SP antes de retornar, lo que es frecuente en el cdigo generado por los compiladores para retornar de una funcin con parmetros. Tambin se puede retornar de una interrupcin con RETF 2, para que devuelva el registro de estado sin restaurarlo de la pila.

Condicional

Las siguientes instrucciones son de transferencia condicional de control a la instruccin que se encuentra en la posicin IP+desplazamiento (desplazamiento comprendido entre -128 y +127) si se cumple la condicin. Algunas condiciones se pueden denotar de varias maneras. Todos los saltos son cortos ysi no alcanzahay que aparselas como sea. Ennegritase realzan las condiciones ms empleadas. Donde interviene SF se consideran con signo los operandos implicados en la ltima comparacin u operacin aritmetico-lgica, y se indican en la tabla como '' (-128 a +127 -32768 a +32767); en los dems casos, indicados como '+', se consideran sin signo (0 a 255 0 a 65535):

JA/JNBESalto si mayor (above), si no menor o igual (not below or equal), si CF=0 y ZF=0.+

JAE/JNBSalto si mayor o igual (above or equal), si no menor (not below), si CF=0.+

JB/JNAE/JCSalto si menor (below), si no superior ni igual (not above or equal), si acarreo, si CF=1.+

JBE/JNASalto si menor o igual (not below or equal), si no mayor (not above), si CF=1 ZF=1.+

JCXZSalto si CX=0.

JE/JZSalto si igual (equal), si cero (zero), si ZF=1.

JG/JNLESalto si mayor (greater), si no menor ni igual (not less or equal), si ZF=0 y SF=0.

JGE/JNLSalto si mayor o igual (greater or equal), si no menor (not less), si SF=0.

JL/JNGESalto si menor (less), si no mayor ni igual (not greater or equal), si SFOF.

JLE/JNGSalto si menor o igual (less or equal), si no mayor (not greater), si ZF=0 y SFOF.

JNCSalto si no acarreo, si CF=0.

JNE/JNZSalto si no igual, si no cero, si ZF=0.

JNOSalto si no desbordamiento, si OF=0.

JNP/JPOSalto si no paridad, si paridad impar, si PF=0.

JNSSalto si no signo, si positivo, si SF=0.

JOSalto si desbordamiento, si OF=1.

JP/JPESalto si paridad, si paridad par, si PF=1.

JSSalto si signo, si SF=1.

Gestin de bucle

LOOP (bucle)

Sintaxis: LOOP desplazamiento

Indicadores: OF DF IF TF SF ZF AF PF CF

- - - - - - - - -

Decrementa el registro contador CX; si CX es cero, ejecuta la siguiente instruccin, en caso contrario transfiere el control a la direccin resultante de sumar a IP + desplazamiento. El desplazamiento debe estar comprendido entre -128 y +127. Ejemplo:

mov cx,10

bucle: .......

.......

loop bucle

Con las mismas caractersticas que la instruccin anterior:

LOOPE/LOOPZ Bucle si igual, si cero. Z=1 y CX0

LOOPNE/LOOPNZ Bucle si no igual, si no cero. Z=0 y CX0

Interrupciones

INT (interrupcin)

Sintaxis: INT n (0 ax destino

es:[di] origen

Campo de comentarios.Cuando en una lnea hay un punto y coma (;) todo lo que sigue en la lnea es un comentario que realiza aclaraciones sobre lo que se est haciendo en ese programa, resulta de gran utilidad de cara a realizar futuras modificaciones al mismo.

5.2. -CONSTANTES Y OPERADORES.

Las sentencias fuente -tanto instrucciones como directivas- pueden contener constantes y operadores.

5.2.1. -CONSTANTES.

Pueden ser binarias (ej. 10010b), decimales (ej. 34d), hexadecimales (ej. 0E0h) u octales (ej. 21o 21q); tambin las hay de cadena (ej. 'pepe', "juan") e incluso con comillas dentro de comillas de distinto tipo (como 'hola,"amigo"'). En las hexadecimales, si el primer dgito no es numrico hay que poner un 0. Slo se puede poner el signo (-) en las decimales (en las dems, calclese el complemento a dos). Por defecto, las numricas estn en base 10 si no se indica lo contrario con una directiva (poco recomendable como se ver).

5.2.2. -OPERADORES ARITMTICOS.

Pueden emplearse libremente (+), (-), (*) y (/) -en este ltimo caso la divisin es siempre entera-. Es vlida, por ejemplo, la siguiente lnea en ensamblador (que se apoya en la directiva DW, que se ver ms adelante, para reservar memoria para una palabra de 16 bits):

dato DW 12*(numero+65)/7

Tambin se admiten los operadores MOD (resto de la divisin) y SHL/SHR (desplazar a la izquierda/derecha cierto nmero de bits). Obviamente, el ensamblador no codifica las instrucciones de desplazamiento (al aplicarse sobre datos constantes el resultado se calcula en tiempo de ensamblaje):

dato DW (12 SHR 2) + 5

5.2.3. -OPERADORES LGICOS.

Pueden ser el AND, OR, XOR y NOT. Realizan las operaciones lgicas en las expresiones. Ej.: MOV BL,(255 AND 128) XOR 128 ; BL = 0

5.2.4. - OPERADORES RELACIONALES.

Devuelven condiciones de cierto (0FFFFh 0FFh) o falso (0) evaluando una expresin. Pueden ser: EQ (igual), NE (no igual), LT (menor que), GT (mayor que), LE (menor o igual que), GE (mayor o igual que). Ejemplo:

dato EQU 100 ; dato vale 100

MOV AL,dato GE 10 ; AL = 0FFh (cierto)

MOV AH,dato EQ 99 ; AH = 0 (falso)

5.2.5. - OPERADORES DE RETORNO DE VALORES.

* Operador SEG: devuelve el valor del segmento de la variable o etiqueta, slo se puede emplear en programas de tipo EXE:

MOV AX,SEG tabla_datos

* Operador OFFSET: devuelve el desplazamiento de la variable o etiqueta en su segmento:

MOV AX,OFFSET variable

Si se desea obtener el offset de una variable respecto al grupo (directiva GROUP) de segmentos en que est definida y no respecto al segmento concreto en que est definida:

MOV AX,OFFSET nombre_grupo:variable

tambin es vlido: MOV AX,OFFSET DS:variable

* Operador .TYPE: devuelve el modo de la expresin indicada en un byte. El bit 0 indica modo relativo al cdigo y el 1 modo relativo a datos, si ambos bits estn inactivos significa modo absoluto. El bit 5 indica si la expresin es local (0 si est definida externamente o indefinida); el bit 7 indica si la expresin contiene una referencia externa. El TASM utiliza tambin el bit 3 para indicar algo que desconozco. Este operador es til sobre todo en las macros para determinar el tipo de los parmetros:

info .TYPE variable

* Operador TYPE: devuelve el tamao (bytes) de la variable indicada. No vlido en variables DUP:

kilos DW 76

MOV AX,TYPE kilos ; AX = 2

Tratndose de etiquetas -en lugar de variables- indica si es lejana o FAR (0FFFEh) o cercana o NEAR (0FFFFh).

* Operadores SIZE y LENGTH: devuelven el tamao (en bytes) o el n de elementos, respectivamente, de la variable indicada (definida obligatoriamente con DUP):

matriz DW 100 DUP (12345)

MOV AX,SIZE matriz ; AX = 200

MOV BX,LENGTH matriz ; BX = 100

* Operadores MASK y WIDTH: informan de los campos de un registro de bits (vase RECORD).

5.2.6. -OPERADORES DE ATRIBUTOS.

* Operador PTR: redefine el atributo de tipo (BYTE, WORD, DWORD, QWORD, TBYTE) o elde distancia (NEAR o FAR) de un operando de memoria. Por ejemplo, si se tiene una tabla definida de la siguiente manera:

tabla DW 10 DUP (0) ; 10 palabras a 0

Para colocar en AL el primer byte de la misma, la instruccin MOV AL,tabla es incorrecta, ya que tabla (una cadena 10palabras) no cabe en el registro AL. Lo que desea el programador debe indicrselo en este caso explcitamente al ensamblador de la siguiente manera:

MOV AL,BYTE PTR tabla

Trabajando con varios segmentos, PTR puede redefinir una etiqueta NEAR de uno de ellos para convertirla en FAR desde el otro, con objeto de poder llamarla.

* Operadores CS:, DS:, ES: y SS: el ensamblador genera un prefijo de un byte que indica al microprocesador el segmento que debe emplear para acceder a los datos en memoria. Por defecto, se supone DS para los registros BX, DI o SI (o sin registros de base o ndice) y SS para SP y BP. Si al acceder a un dato ste no se encuentra en el segmento por defecto, el ensamblador aadir el byte adicional de manera automtica. Sin embargo, el programador puede forzar tambin esta circunstancia:

MOV AL,ES:variable

En el ejemplo,variablese supone ubicada en el segmento extra. Cuando se referencia una direccin fija hay que indicar el segmento, ya que el ensamblador no conoce en qu segmento est la variable, es uno de los pocos casos en que debe indicarse. Por ejemplo, la siguiente lnea dar un error al ensamblar:

MOV AL,[0]

Para solucionarlo hay que indicar en qu segmento est el dato (incluso aunque ste sea DS):

MOV AL,DS:[0]

En este ltimo ejemplo el ensamblador no generar el byte adicional ya que las instrucciones MOV operan por defecto sobre DS (como casi todas), pero ha sido necesario indicar DS para que el ensamblador nos entienda. Sin embargo, en el siguiente ejemplo no es necesario, ya quemidatoest declarado en el segmento de datos y el ensamblador lo sabe:

MOV AL,midato

Por lo general no es muy frecuente la necesidad de indicar explcitamente el segmento: al acceder a una variable el ensamblador mira en qu segmento est declarada (vase la directiva SEGMENT) y segn como estn asignados los ASSUME, pondr o no el prefijo adecuado segn sea conveniente. Es responsabilidad exclusiva del programador inicializar los registros de segmento al principio de los procedimientos para que el ASSUME no se quede en tinta mojada... s se emplean con bastante frecuencia, sin embargo, los prefijos CS en las rutinas que gestionan interrupciones (ya que CS es el nico registro de segmento que apunta en principio a las mismas, hasta que se cargue DS u otro).

* Operador SHORT: indica que la etiqueta referenciada, de tipo NEAR, puede alcanzarse con un salto corto (-128 a +127 posiciones) desde la actual situacin del contador de programa. El ensamblador TASM, si se solicitan dos pasadas, coloca automticamente instrucciones SHORT all donde es posible, para economizar memoria (el MASM no).

* Operador '$': indica la posicin del contador de posiciones (Location Counter) utilizado por el ensamblador dentro del segmento para llevar la cuenta de por dndese llegaensamblando. Muy til:

frase DB "simptico"

longitud EQU $-OFFSET frase

En el ejemplo, longitud tomar el valor 9.

* Operadores HIGH y LOW: devuelven la parte alta o baja, respectivamente (8 bits) de la expresin:

dato EQU 1025

MOV AL,LOW dato ; AL = 1

MOV AH,HIGH dato ; AH = 4

5.3. -PRINCIPALES DIRECTIVAS.

La sintaxis de una sentencia directiva es muy similar a la de una sentencia de instruccin:

[nombre] nombre_directiva [operandos] [comentario]

Slo es obligatorio el campo nombre_directiva; los campos han de estar separados por al menos un espacio en blanco. La sintaxis de nombre es anloga a la de la etiqueta de las lneas de instrucciones, aunque nunca se pone el sufijo :. El campo de comentario cumple tambin las mismas normas. A continuacin se explican las directivas empleadas en los programas ejemplo de este libro y alguna ms, aunque falta alguna que otra y las explicadas no lo estn en todos los casos con profundidad.

5.3.1. -DIRECTIVAS DE DEFINICIN DE DATOS.

* DB (definir byte), DW (definir palabra), DD (definir doble palabra), DQ (definir cudruple palabra), DT (definir 10 bytes): sirven para declarar las variables, asignndolas un valor inicial:

anno DW 1991

mes DB 12

numerazo DD 12345678h

texto DB "Hola",13,10

Se pueden definir nmeros reales de simple precisin (4 bytes) con DD, de doble precisin (8 bytes) con DQ y reales temporales (10 bytes) con DT; todos ellos con el formato empleado por el coprocesador. Para que el ensamblador interprete el nmero como real ha de llevar el punto decimal:

temperatura DD 29.72

espanoles91 DQ 38.9E6

Con el operando DUP pueden definirse estructuras repetitivas. Por ejemplo, para asignar 100 bytes a cero y 25 palabras de contenido indefinido (no importa lo que el ensamblador asigne):

ceros DB 100 DUP (0)

basura DW 25 DUP (?)

Se admiten tambin los anidamientos. El siguiente ejemplo crea una tabla de bytes donde se repite 50 veces la secuencia 1,2,3,7,7:

tabla DB 50 DUP (1, 2, 3, 2 DUP (7))

5.3.2. - DIRECTIVAS DE DEFINICIN DE SMBOLOS.

* EQU (EQUivalence): Asigna el valor de una expresin a un nombre simblico fijo:

olimpiadas EQU 1992

Dondeolimpiadasya no podr cambiar de valor en todo el programa. Se trata de un operador muy flexible. Es vlido hacer:

edad EQU [BX+DI+8]

MOV AX,edad

* = (signo '='): asigna el valor de la expresin a un nombre simblico variable: Anlogo al anterior pero con posibilidad de cambiar en el futuro. Muy usada en macros (sobre todo con REPT).

num = 19

num = pepe + 1

dato = [BX+3]

dato = ES:[BP+1]

5.3.3. -DIRECTIVAS DE CONTROL DEL ENSAMBLADOR.

* ORG (ORiGin): pone el contador de posiciones del ensamblador, que indica el offset donde se deposita la instruccin o dato, donde se indique. En los programas COM (que se cargan en memoria con un OFFSET 100h) es necesario colocar al principio un ORG 100h, y un ORG 0 en los controladores de dispositivo (aunque si se omite se asume de hecho un ORG 0).

* END [expresin]: indica el final del fichero fuente. Si se incluye,expresinindica el punto donde arranca el programa. Puede omitirse en los programas EXE si stos constan de un slo mdulo. En los COM es preciso indicarla y, adems, la expresin -realmente una etiqueta- debe estar inmediatamente despus del ORG 100h.

* .286, .386 Y .8087 obligan al ensamblador a reconocer instrucciones especficas del 286, el 386 y del 8087. Tambin debe ponerse el . inicial. Con .8086 se fuerza a que de nuevo slo se reconozcan instrucciones del 8086 (modo por defecto). La directiva .386 puede ser colocada dentro de un segmento (entre las directivas SEGMENT/ENDS) con el ensamblador TASM, lo que permite emplear instrucciones de 386 con segmentos de 16 bits; alternativamente se puede ubicar fuera de los segmentos (obligatorio en MASM) y definir stos explcitamente como de 16 bits con USE16.

* EVEN: fuerza el contador de posiciones a una posicin par, intercalando un byte con la instruccin NOP si es preciso. En buses de 16 ms bits (8086 y superiores, no en 8088) es dos veces ms rpido el acceso a palabras en posicin par:

EVEN

dato_rapido DW 0

* .RADIX n: cambia la base de numeracin por defecto. Bastante desaconsejable dada la notacin elegida para indicar las bases por parte de IBM/Microsoft (si se cambia la base por defecto a 16, los nmeros no pueden acabar en 'd' ya que se confundiran con el sufijo de decimal!: lo ideal sera emplear un prefijo y no un sufijo, que a menudo obliga adems a iniciar los nmeros por 0 para distinguirlos de las etiquetas).

5.3.4. -DIRECTIVAS DE DEFINICIN DE SEGMENTOS Y PROCEDIMIENTOS.

* SEGMENT-ENDS: SEGMENT indica el comienzo de un segmento (cdigo, datos, pila, etc.) y ENDS su final. El programa ms simple, de tipo COM, necesita la declaracin de un segmento (comn para datos, cdigo y pila). Junto a SEGMENT puede aparecer, opcionalmente, el tipo dealineamiento, lacombinacin, el uso y la clase:

nombre SEGMENT [alineamiento] [combinacin] [uso] ['clase']....nombre ENDS

Se pueden definir unos segmentos dentro de otros (el ensamblador los ubicar unos tras otros). El alineamiento puede ser BYTE (ninguno), WORD (el segmento comienza en posicin par), DWORD (comienza en posicin mltiplo de 4), PARA (comienza en una direccin mltiplo de 16, opcin por defecto) y PAGE (comienza en direccin mltiplo de 256). La combinacin puede ser:

- (No indicada): los segmentos se colocan unos tras otros fsicamente, pero son lgicamente independientes: cada uno tiene su propia base y sus propios offsets relativos.-PUBLIC: usado especialmente cuando se trabaja con segmentos definidos en varios ficheros que se ensamblan por separado o se compilan con otros lenguajes, por ello debe declararse un nombre entre comillas simples -'clase'- para ayudar al linkador. Todos los segmentos PUBLIC de igual nombre y clase tienen una base comn y son colocados adyacentemente unos tras otros, siendo el offset relativo al primer segmento cargado.-COMMON: similar, aunque ahora los segmentos de igual nombre y clase se solapan. Por ello, las variables declaradas han de serlo en el mismo orden y tamao.-AT: asocia un segmento a una posicin de memoria fija, no para ensamblar sino para declarar variables (inicializadas siempre con '?') de cara a acceder con comodidad a zonas de ROM, vectores de interrupcin, etc. Ejemplo:

vars_bios SEGMENT AT 40h

p_serie0 DW ?

vars_bios ENDS

De esta manera, la direccin del primer puerto serie puede obtenerse de esta manera (por ejemplo):

MOV AX,variables_bios ; segmento

MOV ES,AX ; inicializar ES

MOV AX,ES:p_serie0

-STACK: segmento de pila, debe existir uno en los programas de tipo EXE; adems el Linkador de Borland (TLINK 4.0) exige obligatoriamente que la clase de ste sea tambin 'STACK', con el LINK de Microsoft no siempre es necesario indicar la clase del segmento de pila. Similar, por lo dems, a PUBLIC.-MEMORY: segmento que el linkador ubicar al final de todos los dems, lo que permitira saber dnde acaba el programa. Si se definen varios segmentos de este tipo el ensamblador acepta el primero y trata a los dems como COMMON. Tngase en cuenta que el linkador no soporta esta caracterstica, por lo que emplear MEMORY es equivalente a todos los efectos a utilizar COMMON. Olvdate de MEMORY.

Elusoindica si el segmento es de 16 bits o de 32; al emplear la directiva .386 se asumen por defecto segmentos de 32 bits por lo que es necesario declarar USE16 para conseguir que los segmentos sean interpretados como de 16 bits por el linkador, lo que permite emplear algunas instrucciones del 386 en el modo real del microprocesador y bajo el sistema operativo DOS.

Por ltimo, 'clase' es un nombre opcional que emplear el linkador para encadenar los mdulos, siendo conveniente nombrar la clase del segmento de pila con 'STACK'.

* ASSUME (Suponer): Indica al ensamblador el registro de segmento que se va a utilizar para direccionar cada segmento dentro del mdulo. Esta instruccin va normalmente inmediatamente despus del SEGMENT. El programa ms sencillo necesita que se suponga CS como mnimo para el segmento de cdigo, de lo contrario el ensamblador empezar a protestar un montn al no saber que registro de segmento asociar al cdigo generado. Tambin convienehacer un assumedel registro de segmento DS hacia el segmento de datos, incluso en el caso de que ste sea el mismo que el de cdigo: si no, el ensamblador colocar un byte de prefijo adicional en todos los accesos a memoria para forzar que stos sean sobre CS. Se puede indicar ASSUME NOTHING para cancelar un ASSUME anterior. Tambin se puede indicar el nombre de un grupo o emplear SEG variable o SEG etiqueta en vez de nombre_segmento:

ASSUME reg_segmento:nombre_segmento[,...]

* PROC-ENDP permite dar nombre a una subrutina, marcando con claridad su inicio y su fin.Aunque es redundante, es muy recomendable para estructurar los programas.

cls PROC ...cls ENDP

El atributo FAR que aparece en ocasiones junto a PROC indica que es un procedimiento lejano y las instrucciones RET en su interior se ensamblan como RETF (los CALL hacia l sern, adems, de 32 bits). Observar que la etiqueta nunca termina con dos puntos.

5.3.5. -DIRECTIVAS DE REFERENCIAS EXTERNAS.

* PUBLIC: permite hacer visibles al exterior (otros ficheros objeto resultantes de otros listados en ensamblador u otro lenguaje) los smbolos -variables y procedimientos- indicados. Necesario para programacin modular e interfaces con lenguajes de alto nivel. Por ejemplo:

PUBLIC proc1, var_x

proc1 PROC FAR

...

proc1 ENDP

var_x DW 0

Declara la variable var_x y el procedimiento proc1 como accesibles desde el exterior por medio de la directiva EXTRN.

* EXTRN: Permite acceder a smbolos definidos en otro fichero objeto (resultante de otro ensamblaje o de una compilacin de un lenguaje de alto nivel); es necesario tambin indicar el tipo del dato o procedimiento (BYTE, WORD o DWORD; NEAR o FAR; se emplea adems ABS para las constantes numricas):

EXTRN proc1:FAR, var_x:WORD

En el ejemplo se accede a los smbolos externos proc1 y var_x (ver ejemplos de PUBLIC) y a continuacin sera posible hacer un CALL proc1 o un MOV CX,var_x. Si la directiva EXTRN se coloca dentro de un segmento, se supone el smbolo dentro del mismo. Si el smbolo est en otro segmento, debe colocarse EXTRN fuera de todos los segmentos indicando explcitamente el prefijo del registro de segmento (o bien hacer el ASSUME apropiado) al referenciarlo. Evidentemente, al final, al linkar habr que enlazar este mdulo con el que define los elementos externos.

* INCLUDE nombre_fichero: Aade al fichero fuente en proceso de ensamblaje el fichero indicado, en el punto en que aparece el INCLUDE. Es exactamente lo mismo que mezclar ambos ficheros con un editor de texto. Ahorra trabajo en fragmentos de cdigo que se repiten en varios programas (como quiz una librera de macros). No se recomiendan INCLUDE's anidados.

5.3.6. -DIRECTIVAS DE DEFINICIN DE BLOQUES.

* NAME nombre_modulo_objeto: indica el nombre del mdulo objeto. Si no se incluye NAME, se tomar de la directiva TITLE o, en su defecto, del nombre del propio fichero fuente.

* GROUP segmento1, segmento2,... permite agrupar dos o ms segmentos lgicos en uno slo de no ms de 64 Kb totales (ojo: el ensamblador no comprueba este extremo, aunque s el enlazador).Ejemplo:

superseg GROUP datos, codigo, pila

codigo SEGMENT

...

codigo ENDS

datos SEGMENT

dato DW 1234

datos ENDS

pila SEGMENT STACK 'STACK'

DB 128 DUP (?)

pila ENDS

Cuando se accede a un dato definido en algn segmento de un grupo y se emplea el operador OFFSET es preciso indicar el nombre del grupo como prefijo, de lo contrario el ensamblador no generar el desplazamiento correcto ni emitir errores!:

MOV AX,dato ; incorrecto!

MOV AX,supersegmento:dato ; correcto

La ventaja de agrupar segmentos es poder crear programas COM y SYS que contengan varios segmentos. En todo caso, tngase en cuenta an en ese caso que no pueden emplearse todas las caractersticas de la programacin con segmentos (por ejemplo, no se puede utilizar la directiva SEG ni debe existir segmento de pila).

* LABEL: Permite referenciar un smbolo con otro nombre, siendo factible redefinir el tipo. La sintaxis es: nombre LABEL tipo (tipo = BYTE, WORD, DWORD, NEAR o FAR). Ejemplo:

palabra LABEL WORD

byte_bajo DB 0

byte_alto DB 0

En el ejemplo, con MOV AX,palabra se acceder a ambos bytes a la vez (el empleo de MOV AX,byte_bajo dara error: no se puede cargar un slo byte en un registro de 16 bits y el ensamblador no supone que realmente pretendamos tomar dos bytes consecutivos de la memoria).

* STRUC -ENDS: permite definir registros al estilo de los lenguajes de alto nivel, para acceder de una manera ms elegante a los campos de una informacin con cierta estructura. Estos campos pueden componerse de cualquiera de los tipos de datos simples (DB, DW, DD, DQ, DT) y pueden ser modificables o no en funcin de si son simples o mltiples, respectivamente:

alumno STRUC

mote DB '0123456789' ; modificable

edadaltura DB 20,175 ; no modificable

peso DB 0 ; modificable

otros DB 10 DUP(0) ; no modificable

telefono DD ? ; modificable

alumno ENDS

La anterior definicin de estructura no lleva implcita la reserva de memoria necesaria, la cual ha de hacerse expresamente utilizando los ngulos '':

felipe alumno

En el ejemplo se definen los campos modificables (los nicos definibles) dejando sin definir (comas consecutivas) los no modificables, crendose la estructura 'felipe' que ocupa 27 bytes. Las cadenas de caracteres son rellenadas con espacios en blanco al final si no alcanzan el tamao mximo de la declaracin. El TASM es ms flexible y permite definir tambin el primer elemento de los campos mltiples sin dar error. Tras crear la estructura, es posible acceder a sus elementos utilizando un (.) para separar el nombre del campo:

MOV AX,OFFSET felipe.telefono

LEA BX,felipe

MOV CL,[BX].peso ; equivale a [BX+12]

* RECORD: similar a STRUC pero operando con campos de bits. Permite definir una estructura determinada de byte o palabra para operar con comodidad. Sintaxis:

nombre RECORD nombre_de_campo:tamao[=valor],...

Dondenombrepermitir referenciar la estructura en el futuro,nombre_de_campoidentifica los distintos campos, a los que se asigna un tamao (en bits) y opcionalmente un valor por defecto.

registro RECORD a:2=3, b:4=5, c:1

La estructuraregistrototaliza 7 bits, por lo que ocupa un byte. Est dividida en tres campos que ocupan los 7 bitsmenossignificativos del byte: el campo A ocupa los bits 6 y 5, el B los bits del byte: el campo A ocupa los bi1 al 4 y el C el bit 0:

6 54 3 2 10

1 10 1 0 1?

La reserva de memoria se realiza, por ejemplo, de la siguiente manera: reg1 registro

Quedandoreg1con el valor binario 1001011 (el campo B permanece inalterado y el A y C toman los valores indicados). Ejemplos de operaciones soportadas:

MOV AL, A ; AL = 5 (desplazamiento del bit

; menos significativo de A)

MOV AL, MASK A ; AL = 01100000b (mscara de A)

MOV AL, WIDTH A ; AL = 2 (anchura de A)

5.3.7. - DIRECTIVAS CONDICIONALES.

Se emplean para que el ensamblador evale unas condiciones y, segn ellas, ensamble o no ciertas zonas de cdigo. Es frecuente, por ejemplo, de cara a generar cdigo para varios ordenadores: pueden existir ciertos smbolos definidos que indiquen en un momento dado si hay que ensamblar ciertas zonas del listado o no de manera condicional, segn la mquina. En los fragmentos en ensamblador del cdigo que generan los compiladores tambin aparecen con frecuencia (para actuar de manera diferente, por ejemplo, segn el modelo de memoria). Es interesante tambin la posibilidad de definir un smbolo que indique que el programa est en fase de pruebas y ensamblar cdigo adicional en ese caso con objeto de depurarlo. Sintaxis:

IFxxx [smbolo/exp./arg.] ; xxx es la condicin

...

ELSE ; el ELSE es opcional

...

ENDIF

IF expresion (expresin distinta de cero)

IFE expresin (expresin igual a cero)

IF1 (pasada 1 del ensamblador)

IF2 (pasada 2 del ensamblador)

IFDEF smbolo (smbolo definido o declarado como externo)

IFNDEF smbolo (smbolo ni definido ni declarado como externo)

IFB (argumento en blanco en macros -incluir ''-)

IFNB (lo contrario, tambin es obligado poner '')

IFIDN , (arg1 idntico a arg2, requiere '')

IFDIF , (arg1 distinto de arg2, requiere '')

5.3.8. - DIRECTIVAS DE LISTADO.

* PAGE num_lineas, num_columnas: Formatea el listado de salida; por defecto son 66 lneas por pgina (modificable entre 10 y 255) y 80 columnas (seleccionable de 60 a 132). PAGE salta de pgina e incrementa su nmero. PAGE + indica captulo nuevo (y se incrementa el nmero).

* TITLE ttulo: indica el ttulo que aparece en la 1 lnea de cada pgina (mximo 60 caracteres).

* SUBTTL subttulo: dem con el subttulo (mx. 60 caracteres).

* .LALL: Listar las macros y sus expansiones.

* .SALL: No listar las macros ni sus expansiones.

* .XALL: Listar slo las macros que generan cdigo objeto.

* .XCREF: Suprimir listado de referencias cruzadas (listado alfabtico de smbolos junto al n de lnea en que son definidos y referenciados, de cara a facilitar la depuracin).

* .CREF: Restaurar listado de referencias cruzadas.

* .XLIST: Suprimir el listado ensamblador desde ese punto.

* .LIST: Restaurar de nuevo la salida de listado ensamblador.

* COMMENT delimitador comentario delimitador: Define un comentario que puede incluso ocupar varias lneas, el delimitador (primer carcter no blanco ni tabulador que sigue al COMMENT) indica el inicio e indicar ms tarde el final del comentario. No olvidar cerrar el comentario!.

* %OUT mensaje: escribe en la consola el mensaje indicado durante la fase de ensamblaje y al llegar a ese punto del listado, excepto cuando el listado es por pantalla y no en fichero.

* .LFCOND: Listar los bloques de cdigo asociados a una condicin falsa (IF).

* .SFCOND: suprimir dicho listado.

* .TFCOND: Invertir el modo vigente de listado de los bloques asociados a una condicin falsa.

5.4. -MACROS.

Cuando un conjunto de instrucciones en ensamblador aparecen frecuentemente repetidas a lo largo de un listado, es conveniente agruparlas bajo un nombre simblico que las sustituir en aquellos puntos donde aparezcan. Esta es la misin de las macros; por el hecho de soportarlas el ensamblador eleva su categora a la de macroensamblador, al ser las macros una herramienta muy cotizada por los programadores.

No conviene confundir las macros con subrutinas: es estas ltimas, el conjunto de instrucciones aparece una sola vez en todo el programa y luego se invoca con CALL. Sin embargo, cada vez que se referencia a una macro, el cdigo que sta representa seexpandeen el programa definitivo, duplicndose tantas veces como se use la macro. Por ello, aquellas tareas que puedan ser realizadas con subrutinas siempre ser ms conveniente realizarlas con las mismas, con objeto de economizar memoria. Es cierto que las macros son algo ms rpidas que las subrutinas (se ahorra un CALL y un RET) pero la diferencia es tan mnima que en la prctica es despreciable en el 99,99% de los casos. Por ello, es absurdo e irracional realizar ciertas tareas con macros que pueden ser desarrolladas mucho ms eficientemente con subrutinas: es una pena que en muchos manuales de ensamblador an se hable de macros para realizar operaciones sobre cadenas de caracteres, que generaran programas gigantescos con menos de un 1% de velocidad adicional.

5.4.1. -DEFINICIN Y BORRADO DE LAS MACROS.

La macro se define por medio de la directiva MACRO. Es necesario definir la macroantesde utilizarla. Una macro puede llamar a otra. Con frecuencia, las macros se colocan juntas en un fichero independiente y luego se mezclan en el programa principal con la directiva INCLUDE:

IF1

INCLUDE fichero.ext

ENDIF

La sentencia IF1 asegura que el ensamblador lea el fichero fuente de las macros slo en la primera pasada, para acelerar el ensamblaje y evitar que aparezcan en el listado (generado en la segunda fase). Conviene hacer hincapi en que la definicin de la macro no consume memoria, por lo que en la prctica es indiferente declarar cientos que ninguna macro:

nombre_simblico MACRO [parmetros]

...

... ; instrucciones de la macro

ENDM

El nombre simblico es el que permitir en adelante hacer referencia a la macro, y se construye casi con las mismas reglas que los nombres de las variables y dems smbolos. La macro puede contener parmetros de manera opcional. A continuacin vienen las instrucciones que engloba y, finalmente, la directiva ENDM seala el final de la macro. No se debe repetir el nombre simblico junto a la directiva ENDM, ello provocara un error un tanto curioso y extrao por parte del ensamblador (algo as como Fin del fichero fuente inesperado, falta directiva END), al menos con MASM 5.0 y TASM 2.0.

En realidad, y a diferencia de lo que sucede con los dems smbolos, el nombre de una macro puede coincidir con el de una instruccin mquina o una directiva del ensamblador: a partir de ese momento, la instruccin o directivamachacadapierde su significado original. El ensamblador dar adems un aviso de advertencia si se emplea una instruccin o directiva como nombre de macro, aunque tolerar la operacin. Normalmente se las asignar nombres normales, como a las variables. Sin embargo, si alguna vez se redefiniera una instruccin mquina o directiva, para restaurar el significado original del smbolo, la macro puede ser borrada -o simplemente porque ya no va a ser usada a partir de cierto punto del listado, y as ya no consumir espacio en las tablas de macros que mantiene en memoria el ensamblador al ensamblar-. No es necesario borrar las macros antes de redefinirlas. Para borrarlas, la sintaxis es la siguiente:

PURGE nombre_simblico[,nombre_simblico,...]

5.4.2. -EJEMPLO DE UNA MACRO SENCILLA.

Desde el 286 existe una instruccin muy cmoda que introduce en la pila 8 registros, y otra que los saca (PUSHA y POPA). Quien est acostumbrado a emplearlas, puede crear unas macros que simulen estas instrucciones en los 8086:

SUPERPUSH MACRO

PUSH AX

PUSH CX

PUSH DX

PUSH BX

PUSH SP

PUSH BP

PUSH SI

PUSH DI

ENDM

La creacin de SUPERPOP es anloga, sacando los registros en orden inverso. El orden elegido no es por capricho y se corresponde con el de la instruccin PUSHA original, para compatibilizar. A partir de la definicin de esta macro, tenemos a nuestra disposicin unanueva instruccin mquina(SUPERPUSH) que puede ser usada con libertad dentro de los programas.5.4.3. -PARMETROS FORMALES Y PARMETROS ACTUALES.

Para quien no haya tenido relacin previa con algn lenguaje estructurado de alto nivel, har un breve comentario acerca de lo que son los parmetros formales y actuales en una macro, similar aqu a los procedimientos de los lenguajes de alto nivel.

Cuando se llama a una macro se le pueden pasar opcionalmente un cierto nmero de parmetros de cierto tipo. Estos parmetros se denominanparmetros actuales. En la definicin de la macro, dichos parmetros aparecen asociados a ciertos nombres arbitrarios, cuya nica misin es permitir distinguir unos parmetros de otros e indicar en qu orden son entregados: son losparmetros formales. Cuando el ensamblador expanda la macro al ensamblar, los parmetros formales sern sustituidos por sus correspondientes parmetros actuales. Considerar el siguiente ejemplo:

SUMAR MACRO a,b,total

PUSH AX

MOV AX,a

ADD AX,b

MOV total,AX

POP AX

ENDM

....

SUMAR positivos, negativos, total

En el ejemplo, a, b y total son los parmetros formales y positivos, negativos y total son los parmetros actuales. Tanto a como b pueden ser variables, etiquetas, etc. en otro punto del programa; sin embargo, dentro de la macro, se comportan de manera independiente. El parmetro formal total ha coincidido en el ejemplo y por casualidad con su correspondiente actual. El cdigo que genera el ensamblador al expandir la macro ser el siguiente:

PUSH AX

MOV AX,positivos

ADD AX,negativos

MOV total,AX

POP AX

Las instrucciones PUSH y POP sirven para no alterar el valor de AX y conseguir que la macro se comporte como unacaja negra; no es necesario que esto sea as pero es una buena costumbre de programacin para evitar que los programas hagan cosas raras. En general, las macros de este tipo no deberan alterar los registros y, si los cambian, hay que tener muy claro cules.

Si se indican ms parmetros de los que una macro necesita, se ignorarn los restantes. En cambio, si faltan, el MASM asumir que son nulos (0) y dar un mensaje de advertencia, el TASM es algo ms rgido y podra dar un error. En general, se trata de situaciones atpicas que deben ser evitadas.

Tambin puede darse el caso de que no sea posible expandir la macro. En el ejemplo, no hubiera sido posible ejecutar SUMAR AX,BX,DL porque DL es de 8 bits y la instruccin MOV DL,AX sera ilegal.

5.4.4. -ETIQUETAS DENTRO