You are on page 1of 45

ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ Ô¸ Curso de ensamblador Õ¾ ÔÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍÍÍÍÍÍÍÍÍÍÍÍ;

-----------------------------------------------------------------------------³ INDICE ³ 1.- Sistemas n£mericos 2.- Operaciones con bytes 2.1.- AND 2.2.- OR 2.3.- XOR 2.4.- NOT 3.- El juego de registros 4.Comenzamos !!!

5.- Operacines 5.1.- INC y 5.2.- ADD y 5.3.- NEG y 5.4.- MUL y

DEC SUB NOT DIV

6.- Flags 6.1.- Instrucciones de comparaci¢n (CMP y TEST) 7.- Las instrucciones de salto 7.1.- Saltos incondicionales 7.2.- Saltos condicionales 7.3.- Bucles 8.- La pila 8.1.- La orden CALL 9.- Interrupciones 10.- Resto 10.1.10.2.10.3.10.4.10.5.10.6.10.7.10.8.de ¢rdenes XCHG LEA LDS y LES DELAYs Instrucciones de cadena Datos Acceso a puertos I/O Anulaci¢n de interrupciones

11.- Estructura COM 12.- Estructura EXE

13.- Ap‚ndice A: Juego de instrucciones 14.- Ap‚ndice B: Numeraci¢n negativa 15.- Agradecimientos y dedicatorias ------------------------------------------------------------------------------

Sistemas numricos Comencemos por los sistemas de numeraci¢n que m s utilizaremos al programar. El b sico va a ser el sistema hexadecimal, aunque debemos de explicar antes el binario, el sistema de numeraci¢n que utiliza el ordenador. Los n£meros que conocemos est n escritos en base 10. Esto significa que tenemos, desde el 0 hasta el 9, diez s¡mbolos para representar cada cifra. Es decir, cada cifra ir de 0 a 9, y al superar el valor "9", cambiar a 0 y sumar uno a su cifra de la izquierda: 9+1: 10 . El sistema binario utiliza tan s¢lo dos s¡mbolos, el "0" y el "1". Imaginemos que tenemos el n£mero binario "0". Al sumarle una unidad, ‚ste n£mero binario cambiar a "1". Sin embargo, si volvemos a a¤adirle otra unidad, ‚ste n£mero en formato binario ser el "10" ( aumenta la cifra a la izquierda, que era 0, y la anterior toma el valor m¡nimo ). Sumemos ahora otra unidad: el aspecto del n£mero ser "11" ( tres en decimal ). Y podr¡amos seguir: Binario: 0 ; 1 ; 10 ; 11 ; 100 ; 101 ; 110; 111 ; 1000 ; 1001 ; 1010,... Decimal: 0 1 2 3 4 5 6 7 8 9 10 Esto nos permite establecer un sistema bastante sencillo de conversi¢n del binario al decimal; He aqu¡ los valores siendo n el valor de la cifra: Cifra menos significativa: n*2^0 = Segunda cifra: n*2^1 = Tercera cifra: n*2^2 = Cuarta cifra: n*2^3 = 8 si n=1 o 0 si n=0 4 si n=1 o 0 si n=0 2 si n=1 o 0 si n=0 1 si n=1 o 0 si n=0

Etc,... Y as¡ continuar¡amos, aumentando el n£mero al que se eleva 2. Traduzcamos entonces el n£mero binario '10110111' 2^7+ 0 +2^5+2^4+ 0 +2^2+2^1+2^0 1 0 1 1 0 1 1 1 = 128 + 0 + 32 + 16 + 4 + 2 + 1 = 183

De todos modos, ‚sta transformaci¢n la he puesto s¡mplemente para que se comprenda con m s claridad c¢mo funcionan los n£meros binarios. Es mucho m s aconsejable el uso de una calculadora cient¡fica que permita realizar conversiones entre decimales, hexadecimales y binarios. Se hace su uso ya casi imprescindible al programar. La raz¢n del uso de los n£meros binarios es sencilla. Es lo que entiende el ordenador, ya que interpreta diferencias de voltaje como activado ( 1 ) o desactivado ( 0 ), aunque no detallar‚ ‚sto. Cada byte de informaci¢n est compuesto por ocho d¡gitos binarios, y a cada cifra se le llama bit. El n£mero utilizado en el ejemplo, el 10110111, ser¡a un byte, y cada una de sus ocho cifras, un bit. Y a partir de ahora, cuando escriba un n£mero binario, lo har‚ con la notaci¢n usual, con una "b" al final del n£mero ( ej: 10010101b ) Ahora me paso al hexadecimal, muy utilizado en ensamblador. Se trata de un sistema de numeraci¢n en base diecis‚is. Por tanto, hay diecis‚is s¡mbolos para cada cifra, y en vez de inventarse para ello nuevos s¡mbolos, se decidi¢ adoptar las primeras letras del abecedario. Por lo tanto, tendremos ahora: Hex Dec

1 --> 1 2 --> 2 3 --> 3 4 --> 4 5 --> 5 6 --> 6 7 --> 7 8 --> 8 9 --> 9 A --> 10 B --> 11 C --> 12 D --> 13 E --> 14 F --> 15 10 --> 16 11 --> 17 Etc,...

Como vemos, ‚ste sistema nos planteas bastantes problemas para la conversi¢n. Repito lo dicho, una calculadora cient¡fica nos ser casi imprescindible para ‚sto. ¨ Por qu‚ utilizar ‚ste sistema ? Bien sencillo. Volvamos al byte, y traduzcamos su valor m s alto, "11111111". Resulta ser 256. Ahora pasemos ‚sta cifra al sistema hexadecimal, y nos resultar "FF". Obtenemos un n£mero m s comprensible que el binario ( dif¡cil de recordar ), y ante todo mucho m s compacto, en el que dos cifras nos representar n cada byte. Podremos adem s traducir f cilmente el binario a hexadecimal con ‚sta tabla; cada cuatro cifras binarias pueden traducirse al hexadecimal: ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» º Binario º Hexadecimal º ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ 0000 º 0 0001 º 1 0010 º 2 0011 º 3 0100 º 4 0101 º 5 0110 º 6 0111 º 7 1000 º 8 1001 º 9 1010 º A 1011 º B 1100 º C 1101 º D 1110 º E 1111 º F

Por ejemplo, el n£mero binario: 1111001110101110 En hexadecimal ser¡a: 1111 0011 1010 1110 F 3 A E

Para referirnos a un n£mero hexadecimal sin especificarlo, usaremos la notaci¢n que se suele usar al programar, con un 0 al principio ( necesario cuando hay letras ) y una h al final, por ejemplo, el n£mero anterior ser¡a 0F3AEh

ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ Operaciones con bytes ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

Hay cuatro operaciones b sicas que se pueden realizar con un n£mero binario. con lo que cualquiera que la haya estudiado tendr cierta ventaja para entenderla. el resultado es "falso" ( no es verdad que "El hombre es un mam¡fero y respira debajo del agua" ). Para explicarlas. OR. AND 1. es "1" cuando al menos uno de los dos factores . Pongamos un ejemplo m s complejos. resulta que ya que se dan las dos. El hecho de que el hombre sea un mam¡fero es cierto ( 1 ).numero 1 0 1 0 Resultado 1 0 0 0 Vuelvo a la l¢gica para explicarlo m s claramente: Imaginemos la frase: "El hombre es un mam¡fero y camina erguido".numero 1 1 0 0 2. si uno es falso. Por lo tanto. y "0" ( falso ) en el resto de los casos. el resultado es "verdad". el resultado es falso ( no es cierto que "El hombre es un ave y respira debajo del agua" ) OR -El "o" l¢gico. otro ( 1 ). al valor 0 resultado "falso". XOR y NOT AND: --Es un 'y' l¢gico. al unirlos mediante una conjunci¢n ( 'y' o 'AND' ). O sea. queremos realizar un AND l¢gico entre dos bytes: 11011000 AND 01101001 Observemos lo que sucede: 11011000 01101001 -------01001000 216 105 --72 AND En sistema decimal ser¡a: AND (aunque en sistema decimal es m s lioso) Cuando coinciden dos valores de "verdad". y si los dos son falsos. y el de que camine erguido. la oraci¢n es verdadera. llamar&#8218. y al valor 1 "verdadero". y coinciden con operaciones de la l¢gica matem tica. Las operaciones son AND. y el resultado ser "1" si las dos son verdaderas ( si las dos valen "1" ). Se realiza entre dos cifras binarias confrontando cada cifra con su correspondiente. El resultado es "verdadero" cuando al menos uno de los factores es verdadero.

pero nunca las dos o ninguna. al menos una es verdadera.rminos de l¢gica matem tica aplic ndolo a una oraci¢n. Ser¡a como la oraci¢n "O vivo o estoy muerto". y viceversa. por tanto. donde que uno sea cierto no significa que el otro no lo sea. por si alguien no lo conoce. el valor 1 ( verdadero ) queda en las cifras de las que. claro ). Ser¡a como la frase "Voy a buscar el peine o la caja de condones". Se trata de una orden parecida al OR. ser¡a por ejemplo " No es verdad que tenga ganas de estudiar y de no beber ". y en t&#8218.es "1".. XOR --"Or" exclusivo. NOT --Esto se aplica sobre un s¢lo n£mero. negando las otras dos que en caso contrario ser¡an verdad: NOT 11100110 -------00011001 ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ Bytes. tan s¢lo que la verdad de una excluye la de la otra. 10111001 01011101 -------11100100 XOR La orden XOR va a ser bastante £til en encriptaci¢n. es "1" ( verdad ) cuando uno y s¢lo uno de los dos n£meros es verdadero ( y el otro falso. o sea.rminos de l¢gica ser¡a la negaci¢n de una oraci¢n. para que sea cierta se tiene que dar una de las dos.. En t&#8218. confrontadas. S¢lo resulta 0 ( falso ) si los dos n£meros enfrentados son 0 ( falsos ). pero eso ya es otra historia.rminos sean verdaderos. El resultado. quiero detallar el modo de . si el n£mero al que se aplica es 1 el resultado es 0. bits y dem s ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ Tan s¢lo. es cierta la frase. Operemos con los n£meros "10100110" y "01101100": 10100110 01101100 -------11101110 OR Como hemos visto.. es verdadera mientras uno de los t&#8218.

incluyendo lo m s temido por el iniciado en Ensamblador. se toman los 16 bits del registro de segmento y se situan en los 16 bits superiores de la direcci¢n de 20 bits. Ahora querremos m s memoria que 64 Kb. a partir de ahora. como si a¤adi&#8218. Segments y Offsets. 10 decimal o 1010b. Tambi&#8218. el n£mero m ximo de direcciones de memoria a las que podremos acceder ser 1 Mb. binario ). despu&#8218. Un Kbyte es un conjunto de 1024 ( que no 1000 ) bytes. como vimos anteriormente. claro. un MegaByte ser n 1024 kbytes. Otro t&#8218. al igual que la h al final indicando que es un n£mero hexadecimal ).. j*der XD ) 0Ah ( o sea. ... forman un byte. El problema es ordenarlos para que el procesador conozca la direcci¢n de memoria.semos cuatro ceros a la derecha.s de &#8218. Necesitaremos para conocer una posici¢n de memoria pues cuatro bytes combinados de una curiosa manera. vamos con lo interesante. Y para eso tenemos los otros dos bytes.. es de 20 bits. Un conjunto de ocho bits. Y bien. para que lo entiendan los ensambladores. 20 bits no son ni 2 bytes ni 3.stas cosillas. segments y offsets: Resulta que hubo un tiempo. De ellos. puede ser 1 o 0. Y ahora. Su mayor valor puede ser 0FFFFh ( poner un cero delante es una convenci¢n. para localizar un punto en memoria. cuando los dinosaurios dominaban la tierra. en el que a "alguien" se le ocurri¢ que con 640K deber¡a de bastarnos para hacerlo todo. Imaginemos los dos bytes inferiores. o "word". Pero como veremos. Vamos. es palabra.rmino que utilizaremos a menudo.stos dos bytes. llamaremos Offset a la direcci¢n indicada por &#8218. porque creo que no me voy a enterar ni yo: Sea el valor de Segmento ( parezco un libro de matem ticas. sino as¡ como 2 y medio %-). y aqu¡ llegan las cosillas.ste valor de 20 bits el Offset. La unidad m¡nima de informaci¢n es el bit. o 1024*1024=1048576 bytes. y se utiliza por que a menudo se opera con ellas en lugar de bytes. Por lo tanto. que se considera un bloque. dejando los otros cuatro a cero. el de la derecha es el menos significativo ( su valor es menor )..n.almacenamiento del ordenador. y m s engorroso para el programador. Para formar la direcci¢n completa. Igualmente. Y el del Offset digamos que va a valer ( en binario ) 01011111 00001010. y el de m s a la izquierda el m s significativo. Una "palabra". Sumamos entonces a &#8218.. Esto nos da acceso a 64Kb de memoria. resultando la direcci¢n real de memoria Voy a dar una explicaci¢n m s gr fica. Su estado. por aqu¡ vienen los problemas ( y voy a intentar explicarlo lo m s mundanamente posible ) El ancho de bus de direcciones. es un conjunto de dos bytes.

El registro CS es una variable de un tama¤o de dos bytes. Contiene el Segmento actual en que se encuentra el programa. que contienen informaci¢n que puede ser cambiada. indica la direcci¢n de la pr¢xima instrucci¢n que se va a ejecutar. y los dos se referir¡an a la misma posici¢n de memoria f¡sica. La combinaci¢n CS:IP ( tal y como me refer¡ antes en lo de Segments&Offsets ) contiene la direcci¢n en la que el ordenador est interpretando informaci¢n *en el momento*.is observar. •sto significa. de dos bytes tambi&#8218.n son variables de dos bytes. punto de la memoria est y qu&#8218.tera . tiene que ejecutar ? Pues bien. que contiene el Offset actual. el ordenador va interpretando las secuencias de bytes. que indica al ordenador esos sitios en memoria. aunque sea s¡mplemente tener una ligera idea. indica al ordenador en qu&#8218. IP.n. con 4 ceros m s ) ( el offset ) Y &#8218.sta ser¡a la direcci¢n *real* de memoria ( 05FAAh o 24490 Dec ). un etc&#8218.stas alturas: ¨ Y eso del Segment y Offset. as¡ lo tomaremos a partir de ahora ). ser n utilizados para por ejemplo mover datos en memoria. y ( y ahora me pongo como los del Pcman¡a cuando hablan de Windoze95 ) podremos empezar en serio con nuestro lenguaje favorito X-) ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ El juego de registros ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ Quiz alguno de vosotros se est&#8218. El registro DS y el registro ES tambi&#8218. pero necesita "algo" que le indique donde tiene que leer. preguntando a &#8218. Comenzar&#8218. O sea. por ejemplo. por los de segmento y offset actual: CS e IP.La suma para obtener la direcci¢n de memoria ser¡a tal que as¡: 0000 0000 0000 1010 0000 + 0101 1111 0000 1010 -----------------------0000 0101 1111 1010 1010 ( segmento multiplicado*16. y tambi&#8218. la 0400h o 1024d Espero que haya quedado claro. al contrario que todos los libros.n sirven para guardar direcciones de Segmentos. y como curiosidad final. es la variable.sto y mucho m s sirven los registros. bueno. los pares 0040h:0000 ( donde el primero es el Segment y el segundo el Offset. distintos segments y offsets especifican direcciones de memoria distintas. para &#8218. Se trata de una serie de "variables". Lo pr¢ximo ser n los registros.. imprimir cadenas. son iguales que 0000:0400h. qu&#8218. Como podr&#8218. d¢nde se guarda.

AX se divide en AH BH y BL. etc. Pongamos un ejemplo: MOV AX. BX. Luego tenemos una serie de registros que utilizaremos m s comunmente: AX. ya que ser el £nico que permita multiplicaciones y divisiones. y como registro de prop¢sito general al igual que AX. pero &#8218. pero curiosamente la m s utilizada en &#8218. CX y DX CX se suele usar como contador.s. BP. de otros dos bytes de tama¤o.BX Esta ¢rden en lenguaje ensamblador. Se denomina a veces acumulador.stos cuatro registros son diferentes: AX se suele utilizar como prop¢sito general. . y el SP es el que contiene el offset de la pila.sto lo explicar&#8218. SI y DI los utilizaremos a menudo para copiar bytes de un lado a otro. como el resto de registros. y se pueden utilizar divididas longitud un byte. Y comenzaremos con la m s sencilla. y la 'l' a Low ( de menor valor poquillo: AX |-------------| 11010110 10111000 AH AL Las funciones de &#8218. indica funci¢n a las interrupciones. CX y DX. Digamos que son "punteros". m s adelante.ste lenguaje: La orden MOV. CX en CH y CL y DX en DH y DL. copiar el contenido de BX en AX. ÄÄÄÄÄÄÄÄÄÄÄÄÄ La funci¢n de la orden MOV es. alto ( de mayor valor ). contienen dos bytes. se¤alando haciendo el papel de Offset lugares en memoria ( suele combinarse con DS en la forma DS:DX ) Y nos quedan ya s¢lo tres registros.n punteros.largu¡simo. SI y DI. en dos partes de y AL. como su nombre da a entender. para abrir/cerrar archivos. Todas ocupan dos bytes. claro ). La 'H' se refiere ingl&#8218. "mover" un valor. BX nos servir mucho como "handler". que apuntan a cierta zona de memoria ( siempre combinado con otro que haga de Offset. que son tambi&#8218. Lo ilustro un ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ COMENZAMOS !!! ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ Por fin vamos a empezar con ¢rdenes en ensamblador. Ni que decir que. BX en a High en ). y es el m s flexible. DX suele ser el puntero. Igual sucede con BP. cambiando de nombre. El registro SS apunta a la pila. etc. etc.

Vayamos con los ejemplos: MOV AX.ej. A veces para representar un n£mero decimal se pone una 'd' al final ( p.DS ES. El primero era un n£mero hexadecimal. valor en CS:1241h ) Muchas veces.conservando el valor de BX.[BX+3] . o de un registro a memoria. le transferiremos el valor que haya en la posici¢n de memoria CS:BX. En vez de transferir a AX el valor 0EEEEh.0FEA2h MOV BL. 10d ) M s utilidades de MOV.AX AL.ctamente en un registro. Se puede hacer tambi&#8218. transferir¡amos el byte que hay en 0134:03215h y el siguiente a AX.n se puede introducir un valor dir&#8218. que aclaran el tama¤o a transferir: MOV AL. Podemos transferir bytes que est&#8218. MOV [AX].s.[2325h] AX.) ) Tambi&#8218. el segundo decimal ( que no va acompa¤ado por nada para indicarlo ).n podremos usar valores n£mericos: MOV MOV MOV MOV MOV AX.255 MOV DH.CS:1241h ( ( ( ( ( lo que hay en CS:2325h ) el valor en DS:2325h ) el valor en DS:DX ) a DX..n en memoria a un registro.DS:[2325h] AX.BYTE PTR [BX+SI-30h] MOV AX.DS:DX DX.[BX] Y pongamos que en BX est 0EEEEh. se utiliza Word Ptr o Byte Ptr. es posible hacer "sumas" de valores al buscar una direcci¢n en memoria. Otros ejemplos ser¡an: MOV AX.CX Escribir¡amos en la direcci¢n de memoria CS:AX el valor de CX. valor en CS:CX ) a BX. no . no se puede realizar MOV AL. si CS por ejemplo vale 0134h y BX 03215h. He aqu¡ alg£n ejemplo m s: MOV MOV MOV MOV AX.01110101b As¡ de paso pongo ejemplos de como se utiliza la numeraci¢n.BX.DH Como se v&#8218.WORD PTR [BX+DI] Como acabamos de ver.CS:CX BX. Ser¡a el caso de: MOV AX. Y tambi&#8218.n al rev&#8218.AX DX. ya que en AL no cabe BX ( sencillo. y el tercero binario ( con la b al final ).

no ? .mem º MOV SS. Estas dos instrucciones.. º Formatos de la instrucci¢n MOV º Ejemplos º ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ×ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ º MOV reg. nos servir n bastante como contadores ( para bucles ). seguimos adelante.AL º º MOV reg. DEC AX Decrementa AX. le resta uno. de cualquier posici¢n en memoria ) en una unidad.[1234h] º ÓÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÐÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄĽ reg: registro mem:memoria inmed:n£mero inmediato segreg: registro de segmento reg16: registro de 16 bits Y vista la orden MOV.segreg º MOV [SI]. aqu¡ ten&#8218.inmed º MOV BX. Veamos: INC AX Incrementa en uno el valor de AX INC WORD PTR [BX+4] Incrementa la palabra situada en CS:[BX+4] en uno. equivalentes a por ejemplo a "a++" en C.[40FFh] º º MOM mem.) ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ Operaciones ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ Las instrucciones INC y DEC: Son las m s b sicas a la hora de hacer operaciones con registros: INC.0FFFFh º º MOV segreg.mem º MOV CH..ES º º MOV segreg. DEC WORD PTR [BX+4] Decrementa la palabra situada en CS:[BX+4] en una unidad.MOV [BP+SI].reg16 º MOV DS.AH Y para acabar &#8218.reg º MOV AX.inmed º MOV BYTE PTR [DI]. .AX º º MOV mem. incrementa el valor de un registro ( o bueno.reg º MOV [BX]..BX º º MOV mem.is una tablilla de ejemplos sacada de un libro sobre MOVs que se pueden hacer: ÖÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÒÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ&#8226.sta lecci¢n.0 º º MOV reg. sencillo. y DEC lo decrementa.

[BX] ADD AX. Tambi&#8218. o sea. como ser¡a en Basic la ¢rden "REM". se resta al primero el segundo. Resta de CL el valor de DL.BX .que se encuentra en es:[ax] . . NOT y operaciones l¢gicas ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Neg. Y el resto de operaciones l¢gicas tambi&#8218.23h .el valor de DX.y se almacena en la direcci¢n de AX . los comentarios. Tienen dos operandos. como vimos.sta suma en AX . •sto se puede saber mediante los flags.is fijado en que separ&#8218. almacenando . almacen ndose en destino.t&#8218. el primero.en vez de la BX se¤alada anteriormente.el resultado en AX ( siempre en el primer . &#8218.rmino ) . y se almacena en CL .DL SUB [CX].DX SUB CX. Efect£a un AND entre AX y BX. . Lo mismo pero utilizando un valor inmediato .Las instrucciones ADD y SUB ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Se trata de dos operadores que contiene cualquier lenguaje de programaci¢n: la suma y la resta. se suman los dos operandos y se almacena en el primero (destino).tica de complemento a dos tal que : NEG AX o NEG [AX] Not es la que. y se almacena &#8218. Se resta de CX el valor 23h. Bien. de CX . con .stas instrucciones: ADD AX. etc.BX ADD [AX]. Se resta al contenido de la direcci¢n de CX .3 SUB CL. y para la resta. ¨ y si el resultado excede lo que puede contener el byte. Sumar¡a AX y BX y lo guardar¡a en AX .n os habr&#8218. que trataremos m s adelante.n las vimos anteriormente. (o Not AX. "invierte" los valores de los bits.] */" NEG.BX.. Se suman AX y el contenido de la direcci¢n de . uno de destino y otro fuente.. Suma el contenido de la direcci¢n de AX a BX. ahora tan s¢lo su sintaxis: NOT SI NOT Word ptr es:[ax] AND AX. Aqu¡ est n algunos formatos de &#8218. y se almacena en la dir. con un registro) .. Para la suma.. Lo realiza sobre la palabra ( 2 bytes ) .is dado cuenta de una cosa. y queda en CX el . o la palabra ?..resultado Os habr&#8218. o en C la convenci¢n "/* [.sta es la manera en ensamblador de poner comentarios. Pondr&#8218. pone el registro o el lugar al que apunta en memoria en negativo seg£n la aritm&#8218.BX ADD AX.

3 DH. IMUL SI Esto y el ejemplo anterior ser¡a lo mismo. Si el operando es de 8 bits ( 1 byte ).[SI] word ptr ES:[AX]. el acumulador es AX. almacen ndose en el par AX-DX.n tendremos que diferenciar entre dos tipos de multiplicaciones y divisiones que entiende el procesador. va a almacenarlo en AX. MUL y DIV ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄLas pasar&#8218. y los que no. pero AX apunta a un lugar de . y una vez hecho &#8218.sto. el acumulador es AL. Y todo lo dicho para OR y AND vale para XOR.0D533h AX. se devolver¡a en DX.BX AX.memoria . Lo dicho. El resultado se almacena en AX o en el par DX-AX respectivamente.55h .AND [AX]. Tambi&#8218. MUL SI Multiplicar¡a SI por el contenido de AX. s¢lo que operando con . si queremos usar n£meros negativos y tal ). La palabra superior ( de m s valor ). ya que para nuestros objetivos no tienen una necesariedad excesiva. y la inferior en AX. podremos decir que: MUL Byte Ptr [CX] Va a multiplicar el byte que hay en la direcci¢n que marca CX por el contenido que hay en AL. si el operando es de 8 bits o 16 bits.DX [DX].BX AND AX. Los que comienzan con una I operan con n£meros con signo ( &#8218.haya ah¡ y el valor "3" .n podr¡a hacerse en el AND.sto es.[BX] AND Byte ptr [15].confrontan DH y 55h en un OR.BX [AX].BX Byte ptr [15].3 OR OR OR OR AX. Estas operaciones multiplican al acumulador por el operando indicado.Tambi&#8218.0CD32h Multiplicaci¢n y divisi¢n.sto. Un AND en la direcci¢n :0015 con lo que . con n£meros sin signo. de tal manera que las operaciones son realizables entre: Registro Lugar de Registro Lugar de Registro y registro memoria y registro y lugar de memoria memoria y n£mero y n£mero CX. se . al menos a corto plazo. Si el operando es de 16 bits. algo r pido. Visto &#8218.

Vamos a ver alg£n ejemplo que os veo muy perdidos: En la divisi¢n de un n£mero de diecis&#8218. se almacenar¡a en AX el resultado y en DX el resto. el dividendo ha de estar en AX ( y ser 16 bits por tanto ). con lo que cociente y resto ser¡an de 16 bits.n en estilo Basic pero encontrable en otros lenguajes. A las flags. en AL quedar¡a 255 y en AH quedar¡a 1. Se puede dividir tambi&#8218.is en &#8218. el cociente y resto ser n de 8 bits ( 1 byte ). Pues bien.. aunque &#8218. Los que hay is visto un m¡nimo de otros lenguajes recordar&#8218.. .is bits entre otro de 8 bits.ste no est utilizado por completo. y el resto en DX.n£meros con signo. que puede ser un registro o un sitio en la memoria ( y se necesita poner lo de byte ptr ) O sea.ste cap¡tulo del curso de Ensamblador. y el divisor es el operando de la instrucci¢n. los flags y las instrucciones condicionales va a ser lo que os encontr&#8218. quedando el resto en AH. Y ahora pasamos a una parte en la que hay algo de teor¡a y tal. El divisor se indica en el operando. Vamos con el registro de flags. el par ser¡a 3F5555h. a hacer el DIV CL. y el resto en AH. las agrupa un s¢lo registro de 16 bits. por ejemplo en DIV BL. Para la divisi¢n. "banderas". &#8218. Al hacer por ejemplo un: DIV SI Se dividir¡a DX-AX entre SI. o el IF/THEN/ELSE tambi&#8218. almacen ndose el resultado en AX. Si por ejemplo AX valiese 501d y cl valiese 2.. Por ejemplo: Si en DX est el valor 003Fh y en AX 5555h. Se dividir¡a AX entre BL y el resultado quedar¡a en AL. con lo que al dividirlo por SI ( que pongamos que vale 0CCC4h ).is las sentencias FOR y NEXT ( en Basic ). ser¡a tal que: DIV CL o IDIV BYTE PTR ES:[BP] El resultado se devuelve en AL. ÚÄÄÄÄÄÄÄÄÄ¿ ³ FLAGS ³ ÀÄÄÄÄÄÄÄÄÄÙ La explicaci¢n de los "flags" viene a cuento de los saltos condicionales. ya que cada flag ocupa un s¢lo bit.n un n£mero de 32 bits ( 4 bytes ) entre otro de 16 bits ( 2 bytes ). El dividendo ha de estar en AX.ste divisor estar¡a en BL. El dividendo estar¡a formado por el par DX/AX.

n que las instrucciones INC y DEC no afectan a &#8218. AX vale 0FFFFh. ¨ qu&#8218. con lo que podremos ver el resultado. cuando ese n£mero se ha desbordado. y el flag de acarreo . o sea. Aqu¡ explico el significado de cada uno. Cuando se opera y hay acarreo en el £ltimo bit sobre el que se ha operado. Por ejemplo. y como ver&#8218. que como siempre pueden valer uno o cero. Pero de alguna manera nos tenemos que DAR CUENTA de que &#8218. si buscamos el primer archivo del directorio y no hay ninguno. AX vale ahora 0. el flag de acarreo se pone a uno.sto ha sucedido. se activa cuando tras una operaci¢n hay un paso del valor m ximo al m¡nimo o viceversa Este flag nos va a ser tambi&#8218. o al menos de los m s importantes: EL FLAG DE ACARREO ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Hay veces en la operaciones en las que el n£mero se desborda. El flag de acarreo se pone a 0. Veamos los efectos de &#8218.0000h BX. son los flags a todo &#8218.is tambi&#8218.se pone de nuevo a uno SUB AX.50h .acarreo en &#8218. AX vale 0. Al realizar &#8218. el resultado no nos cabr en AX. El registro de flags es como sigue: ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ ³ ± ³ ± ³ ± ³ ± ³ O ³ D ³ I ³ T ³ S ³ Z ³ ± ³ A ³ ± ³ P ³ ± ³ C ³ ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÙ O: Overflow D: Direcci¢n I: Interrupciones rehabilitadas T: Trampa S: Signo Z: Cero A: Acarreo auxiliar P: Paridad C: Acarreo ±: No utilizado Cada cuadrito representa un bit como es f cil adivinar.is cuenta de que cada bit que se utiliza tiene un nombre. tenemos que tener en cuenta que el siguiente n£mero a 0FFFFh es 0000h.1 BX. . Como es l¢gico.sto ? Se trata de varios bits. y el flag sigue inalterado .ste flag. O sea. y el flag de acarreo est a 1 . Imaginemos que tenemos en AX el n£mero 0FFFFh y le sumamos 0CCCCh. Igual pasar si a 0000h le restamos por ejemplo 1 ( el resultado ser 0FFFFh ).n una utilidad.sta suma.stas operaciones: MOV INC DEC ADD MOV ADD AX.Pero bueno. Ahora AX vale otra vez 0FFFFh.n os dar&#8218. no ha habido .n £til al comprobar errores. Tambi&#8218. y dependiendo de su valor indican varias cosas.1 En resumen. el flag de acarreo tambi&#8218. no cabe en el registro o en la posici¢n de memoria. Hay que recordar tambi&#8218.0FFFFh AX AX AX.n .sta operaci¢n . etc.

con lo que podremos usar los saltos condicionales.sto s¢lo tiene efecto cuando EFECTIVAMENTE estamos tratando con n£meros enteros con signo. S¡mplemente se activa cuando el resultado de una operaci¢n aritm&#8218.sto ya se explica m s adelante. que queremos comparar para saber si son iguales. DEC o NEG ) o l¢gica ( AND... el que indica cuando el n£mero es negativo.&#8218. SI es afectado por las instrucciones de decremento e incremento. &#8218. si el flag de cero se pone en uno ). de un SUB CX.tica ( ADD. Por lo tanto. podremos hacer un salto condicional ( &#8218. EL FLAG DE CERO ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ De los m s sencillitos de comprender.AX Si son iguales. INC. Para saberlo. pero &#8218. EL FLAG DE SIGNO ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ A veces interesa conocer cuando un n£mero con signo es negativo o positivo. En realidad es la copia del bit de mayor peso del byte. cuando vale 1 es que el n£mero es negativo y si vale 0 es que es positivo EL FLAG DE DESBORDAMIENTO ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ("Overflow") Se trata de un flag bastante parecido al de acarreo. al contrario que el de acarreo. OR o XOR ) el resultado es un n£mero en complemento a dos. Evidentemente. en complemento a dos. no tendr¡amos m s que restar uno del otro. SUB.tica o l¢gica es cero. Este flag. AX y CX.ste flag se activar . el flag de cero se pondr a uno.sto lo explico en el pr¢ximo n£mero.. A los avispados se os estar ya ocurriendo la gran utilidad del flag. EL FLAG DE PARIDAD ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Se utiliza especialmente en la transmisi¢n de datos para la comprobaci¢n . tenemos por ejemplo dos registros. O sea. pero que act£a con n£meros en complemento a dos y se activa cuando se pasa del mayor n£mero positivo ( 127 en un s¢lo byte ) al menor negativo ( -128 en tama¤o de un byte ). y si el resultado es cero ( o sea. Indica cuando tras una operaci¢n aritm&#8218.

el flag de cero se pondr en uno. Y en el pr¢ximo cap¡tulo veremos como se aplican &#8218. pero creo que su inter&#8218. es ver . y a cero cuando sea impar. con el que podremos cambiar el control a cualquier punto del programa. comprobar. por ejemplo est el flag de interrupci¢n que cuando est activado evita la posibilidad de interrupciones en secciones cr¡ticas de c¢digo. al menos por el momento. y como realizar los saltos comparativos. tiene el mismo formato que el SUB ( por ejemplo CMP AX.BX ).. se puede realizar con el mismo formato de AND. se podr qu&#8218. Es en realidad un SUB del que no se almacena el resultado. Si por ejemplo son iguales. Ser¡a como el "Goto" del Basic. m s flags detalladamente.. tan s¢lo que ninguno de los registros es alterado.s es escaso. aunque s¡ se modifican los flags. INSTRUCCIONES DE COMPARACION ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ No ibamos a terminar la lecci¢n sin ense¤ar nuevas instrucciones ! Nos van a servir bastante para realizar las comparaciones. Se pondr a uno cuando haya un n£mero par de bits. tan s¢lo que no se guarda el resultado. ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ LAS INSTRUCCIONES DE SALTO ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ SALTOS INCONDICIONALES ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Empecemos por el salto sin condiciones. ya que es equivalente a ella. RESTO DE FLAGS ÄÄÄÄÄÄÄÄÄÄÄÄÄÄ No describir&#8218. s¡mplemente transferir el control a otro punto del programa.stos flags. TEST. ya que su importancia es casi nula. La orden es JMP ( de Jump. y son: CMP y TEST CMP compara dos registros..de errores. que cuando est activado provoca una INT 1h cada vez que se ejecuta otra instrucci¢n. o el de trampa. ya que comprueba si el resultado de la £ltima operaci¢n aritm&#8218. salto ) Si record is a &#8218. o un registro y una direcci¢n de memoria.tica o l¢gica realizada tiene un n£mero par o impar de bits puestos a uno.stas alturas los registros CS:IP.

CL vale 22h.CX Ahora voy a comentar un poco el programa.. en el que de paso se repasa un poco: VUELVE: PALANTE: FIN: MOV MOV JMP CMP JMP MOV JMP XOR AX.0CC34h CL.s se realiza un salto a la instrucci¢n etiquetada con "PALANTE". lo que saltar¡a a esa zona. con lo que utilizaremos etiquetas. que pondr el flag de cero a 1 ( recordemos la anterior lecci¢n ). se copia el valor del registro BX en AX..n podremos hacer un MOV AX. Aqu¡ hay un ejemplo.CX cuyo resultado. ¨ Os acord is a£n de los Segments y Offsets ?. que tras el salto a "PALANTE". JMP 542Ah:100h Salta a la direcci¢n 100h pero del segmento 542Ah. Despu&#8218. Tras la primera instrucci¢n. Tambi&#8218.[BX].AX VUELVE CX. Pero es digamos que "algo pesado" calcular en qu&#8218. se saltar a "FIN".lo que hace realmente la instrucci¢n. y tras la segunda. donde tan s¢lo se realizar la orden Xor CX. por eso me ha dado por incluir la orden ) Volvamos con la sintaxis del JMP con algunos ejemplos de como utilizarlo: JMP 100h Salta a la direcci¢n 100h. como hac¡amos antes con un MOV AX. y puede ser llamada desde cualquier lugar del programa. JMP NEAR 55AAh Salto cercano. lejano. y no es m s que incrementar o decrementar IP para llegar a la zona del programa a la que queremos transferir el control ( IP es el Offset que indica la zona de memoria que contiene la siguiente instrucci¢n a ejecutar. as¡ que quiz lo ve is en algunos virus.COM comienza normalmente en esa direcci¢n. Se realiza una comparaci¢n entre AX y BX. Se trata de un salto lejano. por cierto.[PALANTE]. direcci¢n va a estar esa instrucci¢n.AX FIN BX. es poner CX a cero tenga el valor que tenga ( y &#8218. pero asignando a AX el valor que haya en la direcci¢n en la que est "PALANTE". Tranquilidad. es diferente al corto . JMP SHORT 223Ah Salto corto a la direcci¢n 223Ah. AX vale 0CC34h.22h PALANTE BX. y CS el segmento ) El formato m s sencillo para el salto ser¡a JMP 03424h. La etiqueta ha de estar continuada por dos puntos ':'. ahora explico lo de salto corto.. El caso. Un archivo .sto se utilizar bastante programando. y se vuelve a "VUELVE".

Y saltar¡a al contenido en la direcci¢n de memoria a la que apuntan la suma de BX.sta direcci¢n. Salta si el flag de desbordamiento est a .sta instrucci¢n no vale. Adem s. o el FOR. ya que no se especif¡ca si es cercano. Y el lejano se realiza contando como distancia el contenido de cuatro bytes.. el salto dependiendo de que sea cercano. lejano.. cercanos y cortos. Los saltos podr¡an resumirse en un modo "Basic" de la manera IF-THEN-GOTO de tal manera que cuando se cumple una condici¢n se salta a un sitio determinado. si BX valiese 300h y en 300h los dos bytes fuesen 0CC33h. Salta si el flag de desbordamiento est a uno JNO: Jump if not overflow. o sea. pues aqu¡ est lo que suple a &#8218. He aqu¡ los tipos de saltos condicionales ( las letras en may£sculas son las instrucciones ): JO: Jump if overflow. es incorrecto que haya en la direcci¢n 100h una instrucci¢n que diga JMP SHORT 500h. O sea. Sin embargo es un error. ya que la distancia no corresponde a un salto corto. Salta a la direcci¢n contenida en la palabra ( dos bytes ) a la que apunta BX. o sea. y. o sea. si se lee un s¢lo byte. El salto cercano se realiza contando como distancia el contenido de dos bytes.). El salto corto se realiza entre el punto en el que se est y +127 o -128. corto o largo se codifica de manera diferente en modo hexadecimal.tamente en los flags. Se basan compl&#8218. que &#8218. JMP WORD PTR [BX] Ahora si vale .roslos de memoria para poder hacerlos.. el JMP saltar¡a a &#8218... SALTOS CONDICIONALES ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ¨ Record is aquel IF-THEN-ELSE.stas instrucciones en lenguaje ensamblador. Ahora voy a contar algo sobre los saltos lejanos. cercano o lejano. o el WHILE-DO ? Bien. que la cantidad que se puede contener en un byte con signo. que el rango ser¡a desde 32767 a -32768 bytes de distancia. pero est n simplificados de tal manera que no os har falta sab&#8218.SI y 5. paso de calcular la distancia. por ello el rollo de la anterior lecci¢n. o sea. pero es mucha X-) Por ejemplo. A veces es necesario indicar que se trata de salto corto. JMP DWORD PTR [BX+SI+5] Dword son 32 bits. un salto lejano..JMP [100h] Salta a la direcci¢n contenida en 100h.

18h. pero con n£meros con signo. Jump if not Carry. es entonces equivalente a < en una operaci¢n sin signo. JNG: Jump if Lower or Equal. el primer n£mero es inferior al segundo. Jump if Above or Equal y Jump if Not Below. Saltar¡a si en resultado de la comparaci¢n el primer miembro es menor o igual que el segundo ( <= ) JA o JNBE: Jump if Above o Jump if Not Below of Equal. JNB: Otros tres que valen ex ctamente para lo mismo. Salta si el flag de signo est JP.0 JNZ o JNE: Jump if Not Zero o Jump if Not Equal. Significan: Jump if Carry. JNP. JLE. Salta si el flag de paridad est a uno. Vamos. Saltan por lo tanto si al haber una comparaci¢n el flag de acarreo se pone a 1. Salta si el flag de signo est a uno. ya que 13h es menor que 18h. o sea. pero con n£meros con signo. JZ o JE: Jump if Zero o Jump if Equal. Salta si en el resultado de la comparaci¢n. Salta si el flag de paridad est a cero.cero. Saltar¡a en el caso CMP 0. JPE: Jump if Parity o Jump if Parity Even. ya que muchas interrupciones al acabar en fallo encienden el carry flag. JNGE: Jump if Less. o sea. JPO: Jump if Not Parity. pero con n£meros con signo. si las dos instrucciones comparadas son iguales. En la comparaci¢n CMP 0. Salta si en el resultado de la comparaci¢n. est JBE o JNA: Jump if Below or Equal o Jump if Not Above. Salta si en el resultado de la comparaci¢n. JNAE. Salta si el flag de cero est a 1. JGE. Jump if Not Less. JS: Jump if Sign. JL. JG. el primer n£mero es mayor o igual que el segundo. a cero. el primer n£mero es menor o igual que el segundo. es equivelente al operador >=. si las dos instrucciones comparadas no son iguales. Jump if Not Greater of Equal.12h saltar . Saltan por tanto si al haber una comparaci¢n el flag de acarreo vale 0. Jump if Not Greater.0 o CMP 13h. el primer n£mero es mayor que el segundo.n se suelen usar para detectar si hubo fallo en la operaci¢n. Tambi&#8218. para n£meros con signo. JNS: Jump if Not Sign. saltar . JB: Los tres sirven para lo mismo. . que si se compara as¡: CMP 13h. Jump if Not Lower or Equal. JNC. o sea. JAE. Salta si en el resultado de la comparaci¢n. salta si en el resultado de la comparaci¢n el primer miembro es mayor al segundo. Jump if Not Above or Equal y Jump if Below. ya que el segundo operando es MAYOR O IGUAL que el primero. JC. JNL: Jump if Greater or Equal. Salta si el flag de cero a 0. JNLE: Jump if Greater. Jump if Parity Odd. Justo lo contrario que la anterior.

.. aconsejo que os qued&#8218.0005h . etc&#8218.1112h CMP AX. .. y querremos comprobar si son iguales. Por cierto.s de toda &#8218. aunque algunos se usen poco. Vamos con un ejemplo: MOV CX. vuelve al lugar que se indica en su operando decrementando CX en uno. Por lo tanto.Fiuuuuu !!! Menuda lista.sta orden es comparar CX con cero. ahora SI saltar . lo mismo os da usar JG que JNLE por ejemplo. Bueno.BX JE Acaba JB Acaba JG Acaba XOR AX. no pudiendo superar &#8218. tampoco salta . Evidentemente. sigue adelante. o sea.AX XOR BX.sta aridez me temo que voy a tener que poner algunos ejemplos de los m s utilizados: MOV AX. Vamos.sto haya aclarado un poco la utilidad de los saltos. Acaba: Espero que con &#8218. . y para gustos no hay nada escrito. si es igual. o quiz lo hagamos de la memoria. que en los saltos condicionales se puede hacer como en los incondicionales. estamos limitados a saltos cortos.is de cada parrafito con uno. ya que son iguales Esta vez si Ahora BX vale 1110h . por tanto no saltar . de rango a 127 bytes hacia adelante o 128 hacia atr s.tera. que despu&#8218. BUCLES ÄÄÄÄÄÄ He aqu¡ el equivalente al FOR-TO-NEXT en ensamblador.1111h MOV BX. Es mayor.BX tirapalante: Continua: . se trata de la orden LOOP. .BX JB tirapalante HLT DEC BX CMP AX. o sea. No son iguales.sta distancia. halt Ahora BX valdr 1111h Ahora valen igual No saltar . formatos como: JE 0022h JNE 0030h JNO AL Sin embargo.BX JNE Acaba JE Continua DEC BX CMP AX. . pero como veis para una misma instrucci¢n hay varios. . ahora al escribir sabemos cuando uno es menor o mayor. CX ser un contador de las veces que ha de repetirse el bucle. AX y BX valen ahora cero. AX es menor que BX ( toma perogrullada ) Saltar a tirapalante Esta orden bloquea el ordenador. . . si no lo es. Lo que hace &#8218. pero a veces mediante interrupciones sacaremos valores que no conoceremos al ir a programar. No es menor.

que el programa acabar en el grupo de instrucciones de "Acaba" cuando la comparaci¢n de un resultado positivo o cuando el bucle se haya repetido cinco veces. CX se decrementar y saltar a bucle. Entonces nos encontramos con dos ¢rdenes b sicas respecto a la pila. Y en fin. voy a hacerlo lo m s mundanamente posible y sin mucho t&#8218. Ahora. cuando es igual salta a "Acaba". porque las explicaciones muchas veces suelen liar m s sobre una cosa tan sencilla como es &#8218.bucle: Acaba: INC DX CMP DX.0/JNZ par metro. Veamos como funciona &#8218. la orden LOOP es la equivalente a CMP CX. no podemos decir "quiero sacar el valor de DX que he metido antes y que fue el cuarto que met¡".n puede usarse como el JMP.. que van a ser las veces que se repita el bucle. registros que son SS de segmento de pila y SP de Offset de &#8218. como mencion&#8218. Esto significa que al hacer un POP. llegamos al cuerpo del bucle. siglas inglesas que indican 'Last In First Out'. Si llega a la orden LOOP. donde par metro es el operando de LOOP. y el LOOP. Esto se repetir cinco veces.is empezar a programar.n tiene la limitaci¢n de que s¢lo realiza saltos cortos. hemos terminado con los condicionales. que son PUSH y POP. Vamos con unos ejemplitos majos: . Sin embargo. pero luego seguramente usar&#8218. Ya no nos queda mucho. direcci¢n que viene indicada por SS:SP. se sacar el £ltimo valor introducido en la pila. y ya podr&#8218. La ¢rden PUSH empuja una variable a la pila. antes. por ejemplo. La pila es una especie de "almac&#8218.rmino complicado. ÚÄÄÄÄÄÄÄÄÄÄÄ¿ ³ LA PILA ³ ÀÄÄÄÄÄÄÄÄÄÄÄÙ Para explicar &#8218. no podemos sacar el que queramos. Parece muy rido.ste programa. Tambi&#8218.is poco m s que un JZ o JNZ al principio. Se mueve a CX el valor 5h. de la forma: LOOP 0003h LOOP [AL] En resumen.sto. claro..n de variables" que se encuentra en una direcci¢n determinada de memoria. La explicaci¢n de la pila y las interrupciones. La estructura de la pila se denomina LIFO. Se incrementa DX y se compara con 0.sta. y la ¢rden POP la saca. y tambi&#8218..sta parte.0000h JE Acaba LOOP bucle ... En fin.

SP se decrementa en dos apuntando a 0FFFDh. bueno.es el contenido de DX cuando hicimos el PUSH DX . aunque sea un gasto in£til de c¢digo. y el valor se sacar de la pila.044C4h CX . .sto es lo que hace un POP BP.PUSH PUSH POP POP DX CX AX BP . MOV MOV BP.el de pila. ADD Y &#8218.2 . Ahora BP es igual al offset al que apunta SP BP. DX vale ahora 0301 hexadecimal. SUB SP. Mete en la pila el contenido de DX .is a aplicarlo cuando ve is el curso de virus/antivirus: Partamos de que hay cierto valor en la pila que queremos sacar. igual que CS. DX. SP se decrementa en dos. Y ahora el contenido de CX . Ahora DX vale 044C4h Y con &#8218. SI. sin embargo no se puede hacer un POP CS. .2 . lo pongo aqu¡. SP. Ahora saca el £ltimo valor introducido ( CX ) . ser el valor que sacar¡amos . pero ser¡a un buen ejercicio que lo intent rais hacer sin mirarlo y luego lo consult rais. una rutina algo m s detallada: MOV PUSH MOV POP valor DX.sta direcci¢n queda el valor introducido.y lo coloca en AX. Para ver lo que hace un PUSH no habr¡a m s que invertir el proceso. BX. tan s¢lo empujarlo a la pila. s¡mplemente.SP . Para acabarlo. el . . por ejemplo introduciendo DX a la pila.y se lo asigna a BP. que al ser el offset al que apunta . CX vale 0301 hexadecimal. y si no han sido modificados. se incrementar de nuevo en dos el valor de SP. He aqu¡ un ejemplo de lo que hace en realidad un POP en t&#8218. Y ahora BP vale el contenido del offset al . SP. y SP apunta al final.que hab¡amos introducido con anterioridad. DS y ES ). CX.sta instrucci¢n con los registros AX.haciendo un POP BP. . supongo que ya aprender&#8218. CS. Cuando lo saquemos. DS y ES.de la pila.0301h DX DX. y en &#8218. DI. Se puede operar con &#8218. SS es el segmento del programa ( o sea. Cuando por ejemplo ejecutamos un . que busca un POP BP y SUB posterior. sumamos dos al valor de offset .Word ptr [BP] . Cuando empujamos un valor a la pila. a 0FFFFh.que apunta.rminos de MOVs.sto. Empuja DX a la pila. Dije en la segunda l¡nea: SP se decrementa en dos. Ahora. que . Y ahora saca en valor anterior introducido.COM. BP. tiene su aplicaci¢n por ejemplo para saltarse la heur¡stica en un antivirus.

Es una instrucci¢n que nos va a servir para llamar a subrutinas. los del punto en el que est en ese momento el programa ). en la que se . y hace un salto a la direcci¢n indicada. pudi&#8218. sacar tantos valores de la pila como se metan.n: mov Ret ax.30h . Mete CS e IP a la pila y salta a 20h . o sea. s¢lo que sep is eso quebi&#8218. lo hace en el mismo segmento.ndose tambi&#8218. todo .DX Como £ltima recomendaci¢n.n varios formatos: RETN o RETF. pr cticamente no lo usaremos. Veamos un ejemplo: xor Call quebi&#8218. La pila bien aprovechada es fundamental para hacer programas bien optimizados. y la llamada directa lejana. Existe entonces la llamada directa cercana.n Int &#8218. near ) o lejano ( RETF. apuntando a la ¢rden siguiente al Call ).en el pr¢ximo cap¡tulo. y al retornar. direcciones inmediatas o registros. y est relacionada con la pila.n utilizar etiquetas. hay otras dos ¢rdenes interesantes respecto a la pila. el Call ser¡a el 'GOSUB'.n . que empujan el registro ( 16 bits ) de flags y lo sacan. y as¡ retornar al lugar de origen. •sta ¢rden sale al dos. far ). Empuja a la pila los valores de CS e IP ( o sea. seg£n se retorne desde un sitio cercano ( RETN.sto ax. por lo que la incluyo en &#8218.MOV MOV BP.ax . explicar&#8218. Su forma de actuaci¢n es sencilla. Y finalmente. hay que tener bastante cuidado con los PUSH y POP. Es por ejemplo mucho mejor usar un PUSH al principio y un POP al final en vez de dejar partes de c¢digo para almacenar variables.SP Word ptr[BP]. No obstante.sta lecci¢n del curso. Vuelve a la instrucci¢n siguiente al punto . Ax vale ahora 0 quebi&#8218. m s velocidad y menos tama¤o. Cuando encuentre una instrucci¢n RET. La sintaxis del Call es casi la de un Jmp.de llamada. y estar pendiente de que lo que se saca es lo que se tiene que sacar. PUSHF y POPF. Si compar semos un Jmp con un 'GOTO'. en la que s¢lo se introduce IP ( l¢gicamente. respectivamente LA ORDEN CALL ÄÄÄÄÄÄÄÄÄÄÄÄSe trata de una ¢rden que se utiliza para llamar a subrutinas. ya que entre otras cosas las instrucciones PUSH y POP s¢lo ocupan un byte. la mayor¡a de las veces se quedar en RET y punto. sacar CS e IP de la pila. a la de "INT 20h" La ¢rden RET puede tener tambi&#8218. aunque IP aumentado en el tama¤o del call para apuntar a la siguiente instrucci¢n.

acabar con un IRET. para transferir el control del programa al punto que indica esa tabla respecto a la interrupci¢n pedida mediante un 'CALL'. Ah¡ se contienen el CS e IP a los que saltar el programa cuando se ejecute la interrupci¢n. de la que hablar&#8218. Para averiguar cual corresponde a cada interrupci¢n. m s adelante. etc. Y ahora voy a ponerme algo m s mundano.. Y el pr¢ximo cap¡tulo empezamos con interrupciones. a meterlos en la pila.-) ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ INTERRUPCIONES ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ A &#8218. Porque por mucho registro que tenga no voy a escribir por ejemplo un car cter en la pantalla. si no hab&#8218. Bieeeeeen.is diciendo: bueno. hace'. A veces se podr¡an producir confusiones. Comienza en la direcci¢n de memoria 0000:0000 y acaba en la 0000:0400.. Cuando se ejecuta una interrupci¢n.. la direcci¢n de memoria donde est el punto al que salta una INT 21h. son modificables..introducen CS e IP ( y luego se sacan. no hay m s que multiplicar el n£mero de interrupci¢n por cuatro. un 'PUSHF'. por ejemplo la funci¢n 21h est dedicada especialmente a tratamiento de archivos. El formato de la ¢rden es INT X. y despu&#8218. el ordenador empuja todos los flags a la pila. Para utilizarlas. Son principalmente subrutinas de la BIOS o el DOS que pueden ser llamadas por un programa. siendo cada direcci¢n de 4 bytes de longitud.sto al menos saber 'qu&#8218. La primera cosa que tenemos que hacer es saber como funcionan las interrupciones. Cuando la interrupci¢n ha terminado.s mira en la tabla de vectores de interrupci¢n.stas alturas del curso estar&#8218. que ya queda menos para poder programar . que es una combinaci¢n entre 'POPF' y 'RET'. y podremos elegir cual ejecutamos seg£n el valor de AH.is entendido &#8218. pero hay que tener mucho cuidado con ello. Vamos con un ejemplo de uso de una interrupci¢n: . con lo que quiz pueda ser conveniente usar RETN y RETF respectivamente. Por ejemplo. es 0000:21h*4. ¨ pero c¢mo act£o con el exterior ?.. donde X puede ir desde 1 a 255 ( aunque normalmente se escribe en formato hexadecimal ). vale. claro ). Cada interrupci¢n tiene varias funciones. son las interrupciones. he aprendido a mover registros. quiz as¡ adem s los que os hay is perdido pod is retornar m s adelante. La tabla de Vectores de Interrupci¢n es una tabla de direcciones para la direcci¢n a la que debe saltar cada interrupci¢n. tendremos que poner los registros con un determinado valor para que se realice el prop¢sito que buscamos. Estos valores.. pues aqu¡ est . venga.

Ds ya est apuntando a &#8218. Al ir a llamar a la interrupci¢n.con tener AX actualizado para poder . y &#8218. Mov segmento.OFFSET archivo Int 21h Voy a detallar un poco m s. el 0 que va despu&#8218. en operaciones con archivos. si la etiqueta archivo est .significa borrar un fichero .sido variado de ninguna manera. Como DS vale lo mismo que CS si no lo hemos cambiado. La interrupci¢n para ello es la 21h.ejecutar. .ste . no tiene ninguna . Mov dx.OFFSET anterior di. es la direcci¢n de la cadena que contiene la unidad.en :0014h. borrar un fichero. que . .( que aqu¡ es 41h ). Vamos con otro ejemplo. .s¢lo tendremos que asignar Dx . tal y como suced¡a en el anterior ejemplo. indica la funci¢n . Ahora.s es necesario .jmp mesaltomsg . Esto lo hago porque ejecutar el texto . y ES:DI la direcci¢n de la cadena que contiene la nueva unidad. Vamos con el programa: Mov ah. con lo que en AH tendremos que poner ese valor. necesita ciertos par metros.0 . Di apunta al nuevo nombre.ste caso es la 41h. mesaltomsg: mov dx.o sea. y la funci¢n que queremos es la 56h. Como vemos.com'. o no . tan s¢lo hace falta hacer que DX apunte al lugar donde est la cadena de caracteres con el nombre del archivo.usar la interrupci¢n. como . queremos cambiar el nombre de un fichero.offset con la etiqueta archivo.4100h .puede traer consecuencias imprevisibles archivo: db 'c:\command. funcionar .su funci¢n 41h.56h .de dicha interrupci¢n que se quiere . Es no ha . El par DS:DX. Ejecutamos la interrupci¢n 21h en . En dx cargamos la direcci¢n del . no s¢lo basta . No hace falta inicializar al. ese ser ahora el valor . Cuando AH vale 41h.importancia su contenido.sto es que en DS:DX se encuentre la cadena de caracteres que indica el fichero a buscar. funci¢n de borrar fichero. AH . Porque la funci¢n de la Int21h que busco necesita par metros. ¨ por qu&#8218. camino y nombre.OFFSET posterior . camino y nombre del fichero. En &#8218. en dx pongo la direcci¢n del offset de archivo ?.de DX.hicimos antes. mov ax.

. demasiado para ponerlo aqu¡. funciones de dos referidas al disco. cambiar el nombre del archivo berilio. s¡mplemente para orientaros al buscar. Interrupci¢n 17h: Impresora. aqu¡ est n las interrupciones que m s se usan y sus funciones en general. y ocupa cerca de un disco completo.ste se encuentra en el directorio. Interrupciones 25h y 26h: Funciones de dos de acceso directo al disco..rico.Int 21h Int anterior: posterior: 20h db db . cambiar modos de pantalla. cambia su nombre al .archivo de DS:DX...0 En resumen. aunque al final del curso os podr&#8218. Hay innumerables cosas que se pueden hacer con las interrupciones: escribir textos. Recomiendo tener a mano la lista de interrupciones de Ralf Brown. y se actualiza de vez en cuando. gesti¢n de ficheros.com si &#8218. ejecutarlos. escribir y leer sectores... con ella se consigue el acceso a la fecha y hora del sistema. adem s de la gesti¢n de la memoria.com a magnesio. para la gesti¢n de directorios..rselas de memoria.de ES:DI . y algunas de lectura/escritura en el teclado y pantalla. El caso es que es imposible sab&#8218.0 'magnesio. o las gu¡as Norton. que es una aut&#8218. ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ Resto de ¢rdenes ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ Bueno. Para dar una idea en general y que sep is c¢mo buscar lo que necesit is. con largos archivos de texto.. Si en &#8218.ntica biblia de las interrupciones. Interrupci¢n 13h: Funciones de BIOS que se refieren al disco. pues parece que nos vamos acercando al final. La lista de interrupciones de Ralf Brown es f cil de encontrar. gesti¢n de la pantalla en modo gr fico. y es mejor tener una buena obra de consulta al lado. Devuelve el control al Ms-dos.is encontrar m s ejemplos. 'berilio.com'.is. leer del teclado. leerlos. Interrupci¢n 21h: Apuesto a que es la que m s utilizar&#8218.com'. ahora voy a contar con algo de detalle del resto de las ¢rdenes en lenguaje ensamblador las m s importantes y que m s merezcan conocerse: . Interrupci¢n 10h: Gesti¢n de la pantalla en modo alfanum&#8218.ste directorio de halla el . escribir en archivos.

reg ( XCHG AX. Lea SI.XCHG ÄÄÄÄ La funci¢n de xchg es la de intercambiar valores entre registros y memoria.[Sunset+Bp-Si] Pudiendo usar en el operando cualquier direcci¢n de memoria y pudiendo sum rsele registros.stas operaciones: LEA dx. o sea..sto se usan LDS y LES. Si lo hiciesemos con movs quedar¡a tal que as¡: MOV dx.0000:[DI-23] .n que averiguar de alguna manera su segmento. de tal manera que puede funcionar as¡: XCHG reg.si La ¢rden LEA integra &#8218. Para &#8218.stos casos especialmente.mem ( XCHG AX. el lugar donde est la etiqueta "Sunset" m s el valor de bp menos el de si. el Segmento indicado en el operando origen quedar en DS o ES seg£n la ¢rden sea LDS o LES. y como sustituyente al MOV en &#8218.CS:[DI+3] ). al hacer que apuntase hacia un offset que nos interesaba ).bp SUB dx. LDS y LES ÄÄÄÄÄÄÄÄÄ El puntero anteriormente utilizado nos puede servir mucho si lo que pretendemos localizar se halla en el mismo segmento que el programa. pero si est en otro lugar.. Teniendo la misma sintaxis que LEA. tendremos tambi&#8218. sus resultados los ligeramente diferentes. Imaginemos que el offset al que queremos apuntar es Sunset+bp-si.reg o reg.BX ) XCHG mem. sirve al usar como puntero a DX ( recordemos.Word ptr 0000:0084h ) LEA ÄÄÄ "Load Effective Adress".Offset sunset ADD dx. Adem s de ponerse en el operando destino ( SI en el ejemplo anterior ) el Desplazamiento u Offset.. aunque pudiendo poner un registro de segmento ( pej. si hacemos: LDS DX. Por ejemplo.

Su comportamiento depende del flag de direcci¢n del que habl bamos unas lecciones m s atr s.300h La ¢rden rep se repite 300h veces..ctamente con &#8218. Si est a uno el flag. que vienen ahora. y ES tomar el valor de 3342h. Es tan com£n el uso de la B o la W que siempre lo pondr&#8218. y casi siempre adem s una B o una W indicando Byte o Word ( el tama¤o ). lo pone a uno. es la ¢rden REP ( repeat ). encontrar valores determinados o comparar cadenas. DELAYs ÄÄÄÄÄÄ A veces nos puede interesar perder algo de tiempo. CLD: CLear Direction flag. Se repite. y cada vez que lo hace disminuye CX en una unidad. se decrementar en 1 o 2 unidades dependiendo del tama¤o ( byte/palabra ) . Se usa especialmente para ¢rdenes como Movsb.sta ¢rden tiene adem s luego m s utilidades. seg£n sea byte o palabra.stas son: LODSB/LODSW Lee un byte/palabra en la direcci¢n de memoria dada por DS:SI y la almacena dependiendo de su tama¤o en AL o AX.. Igualente suceder LES SI valdr en ES: 0000.stas dos instrucciones: STD: SeT Direction flag. SI aumentar en 1 o 2 unidades ( para poder continuar la operaci¢n de lectura ). y cuando la supera CX vale 0. etc etc. copiar datos de una zona a otra. Las instrucciones que vamos a usar como de cadena siempre tienen una S de String al final. y en DS quedar el segmento en que se encuentra. etc. lo pone a cero.3342h:[Bp] BP. SI. INSTRUCCIONES DE CADENA ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Son un subconjunto de instrucciones muy £tiles para diversas funciones: inicializar zonas de memoria. y &#8218.En DX quedar la direcci¢n a la que apunta DI-23. y que se puede cambiar dir&#8218.. Pero s¡mplemente que entend is que si hago: Mov Rep CX. as¡ ( es mejor especificar para prevenir posibles fallos ) Y &#8218. Si el flag de direcci¢n est a cero.

incrementa DI y SI.buffer movsb 20h db 400h dup (?) Bueno.. y cada vez que lo . Si est a uno. No est permitido hacer xor ds.vectores de interrupci¢n. Si est a uno. A asegurarnos de que el flag de direcci¢n .. mov xor push pop cx. pues espero que con &#8218. que vale 0.si cs es di. pone dx a 0 . . decrecer .. Vamos a asegurarnos de que ES valga CS.STOSB/STOSW Es el equivalente a "grabar" si lo anterior era "cargar". Almacenar el contenido de AL o AX ( como siempre.ste programa ejemplo quede todo clarito :)) . pues bien.dx dx ds .tabla. . .400h dx.ds. dependiendo del tama¤o ) en ES:DI.a cero. B o W ). la repetir CX veces. Por ejemplo.metemos dx.l. por lo que . REP Acabo de hablar sobre &#8218. . MOVSB/MOVSW Mueve el byte o palabra contenido en la direcci¢n de memoria a la que apunta DS:SI a la direcci¢n de memoria de ES:DI. . xor push pop mov rep hace int buffer: si. Si el flag de direcci¢n est a cero.stas ¢rdenes. . Repite &#8218.DS valiendo 0. copiando seg£n si es B o W uno o dos bytes cada vez que se ejecute. y sacamos . Si el flag de direcci¢n est a 0.el segmento en el que est el programa ahora.va a servir para almacenar la tabla de . . SI que valga 0. DI aumentar cada vez que se realice la ¢rden en una o dos unidades ( dependiendo tel tama¤o. si queremos copiar digamos la tabla de vectores de interrupci¢n a un lugar que hemos reservado: cld est&#8218. DI apunta al lugar donde vamos a guardar la . Esto deja un espacio de 400h bytes que nos . Acaba la ejecuci¢n . se decrementar n de igual manera. en la pila.sto 400h veces. o sea. si se utiliza como operando suyo una de &#8218. con cada MOVS que realicemos SI y DI aumentar n en una unidad ( MOVSB ) o dos ( MOVSW ).

Ver&#8218. Voy a mostrar algunos ejemplos: db 'A saco con todos$' DB se refiere a un byte de longitud.is . aunque se pueden usar palabras para su lectura. el valor m ximo de cualquier registro de . Los puertos son todos de ocho bits. que &#8218.'s'.sto colocar¡a cinco '90h' en ese sitio.presentandolo car cter a car cter.'a'.. que es cuando se para. Variaciones sobre el tema. db 'A'. va .sta orden. Define Quadword.esa posici¢n . las instrucciones que permiten mandar y recibir datos de ellos. DATOS ÄÄÄÄÄ Acabamos de ver algo nuevo. o sea. Significa que repite 5 veces el car cter o n£mero que hay entre par&#8218. bien. almacena un n£mero en . y hacer un rep movsw. o sea. al igual que DW o DD es dejar espacio para datos en una determinada zona del programa. dw dup 300h (?) Deja un espacio de trescientas palabras ( seiscientos bytes ) para poder almacenar cosas.sto ha de hacerse siempre.'o' db dup 5 (90h) A ver. &#8218. Su contenido no tiene importancia. Podemos para empezar reducir el 400h a 200h en CX. ¨ verdad ?. Existen 64K puertos. Os dejo que imagin&#8218..n existe DQ. y se usa por ejemplo para guardar una cadena.is que pongo un $ al final de la cadena.' '. dw 0ffffh . palabro. o introducirlos ah¡. que &#8218.sto ha sido m s raro. ¨ qu&#8218.mos de palabra en palabra las instrucciones. el ordenador lee desde el punto indicado hasta el $.ntesis. con lo que trasladar&#8218. significa eso de 'db' que aparece en el anterior problema ? El objetivo de &#8218.'c'.Por supuesto. se trata de lugar de almacenamiento ( como el lugar en el que copiabamos la tabla de vectores en el ejercicio anterior ) Tambi&#8218.) ACCESO A PUERTOS I/O ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ S¡mplemente describir&#8218. es muy mejorable. IN y OUT. ya que al utilizar interrupciones para mostrar una cadena de caracteres por pantalla. W de word.

ndose hacer as¡ ( mediante el registro AX o AL ): OUT DX.Offset..sto casi se ha acabado !.AH desde el puerto DX+1 DX es lo £nico que puede variar siendo otro registro.el puerto DX+1 env¡a AH. recomiendo el primero ). a hacer cosas . IN lee un byte o una palabra del puerto y lo almacena en AX/AL. que "curiosamente" coinciden con 0FFFFh. no se puedan ejecutar interrupciones. Masm.AX . y despu&#8218. A DX manda el contenido de AL. y no queremos que se ejecute una interrupci¢n que tenemos a medio cambiar. debido a que estamos haciendo algo delicado. AL o AX no pueden ser otra cosa. y ale. S¢lo faltan las estructuras de COM y EXE para que pod is empezar a programar.D ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ Õ¾ ESTRUCTURA COM Ô¸ ÔÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ; Los archivos COM tienen como m ximo 65536 bytes de extensi¢n. No tendremos m s que poner la ¢rden CLI O CLear Interrupts.AL OUT DX.DX IN AX. Como antes.is las Interrupciones de Ralph Brown ( ¨ que no las encuentras. y que pill&#8218. Y bueno. manda el valor contenido en AL . como por ejemplo tocando la tabla de vectores de interrupci¢n.. si est n en todos lados ! ? ). que es el m ximo valor que puede tener .s en . leyendo . no se permite en AX/AL OUT manda un byte al puerto. Al puerto DX.ctamente un n£mero ) ANULACION DE INTERRUPCIONES ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Hay veces que necesitamos que mientras se est ejecutando nuestro c¢digo no se puedan ejecutar interrupciones. que consig is un programa ensamblador ( Tasm. Lee del puerto DX y almacena en AL . DX podr¡a si ser otro registro ( o dir&#8218.DX . A86. Observese &#8218.. tal que as¡: IN AL. &#8218. Lee de DX y almacena en AL el valor.sta . pudi&#8218.peculiaridad tanto aqu¡ como en el anterior. que lo que hace es que hasta que encuentre una ¢rden STI ( SeT Interrupts ).

y con el de desplazamiento se podr averiguar el lugar donde se encuentra cualquier cosa en el archivo. y quiz a m s de uno le ayude quit rselos de enmedio. Se trata .l.un registro de 16 bits. o: CODIGO SEGMENT CODE ASSUME DS:CODIGO ES:CODIGO Lo que abre un segmento de c¢digo ( o sea. No son necesarios.COM en lenguaje ensamblador.s de un posible "Entrada ENDP" ENDP Aqu¡ va un ejemplo de programa . a partir del Offset 80h ) Pongo un ejemplo ahora de cabecera. aunque con cosas que se puedan comentar ( para que no se os olviden cosillas mientras ) ----------------.s un programa COM completo pero sencillito. normalmente es . cualquier direcci¢n dentro del COM tendr en com£n el registro de segmento. el Com ). C¢digo . y despu&#8218.CODE TINY . Por lo tanto. que abre el programa. Al final habr¡a que poner un: CODIGO ENDS Justo antes del "END Start" pero despu&#8218.cual empieza el c¢digo. Si hay que cerrar el Start. como MODEL en vez de ser TINY que sea SMALL por ejemplo.n una zona normalmente que va de 0 a 100h en la que tiene el PSP. y hace que los registros de segmento apunten a &#8218.) . Hay m s l¡neas que se pueden poner en la cabecera.COM tiene tambi&#8218. Indica que es peque¤ito . •sta es la direcci¢n a partir de la . El .MODEL . zona de datos en la que entre otras cosas est la Dta ( para trabajar con ficheros.100h para dejar espacio al PSP Entrada ORG 100h Start: jmp [Datos] Entrada PROC [Codigo] Entrada END Start ------------------Entrada es un procedimiento al que se puede llamar con por ejemplo el salto del principio.

Aclaro ahora que mis intenciones no son las de distribuir &#8218. Dx vale 9eh porque es el valor .stas cosas para que la gente suelte virus por ah¡.3eh 21h ah. len equ offset last-100h start: mov xor lea int ah. El caso es que al utilizar interrupciones.start ah.len dx.40h 21h Next: mov int mov int jnb ah. ser peque¤ito y tal. .es encontrar el primer archivo del . para .rest ndole 100h ( el PSP ).de un virus.sobreescribiendo lo que hubiese .ejemplo.3d02h mov dx. y dx la .lo tanto.anteriormente .cantidad de bytes a escribir.c* ( pretende . donde se contienen los datos . La funci¢n 40h de la Int21h consiste en la .funci¢n 4eh de la interrupci¢n 21h. virus segment org 100h assume cs:virus .escritura. que . ya que es de tipo sobreescritura. Nueva orden que no coment&#8218.abrir e infectar. !. virus .principio del programa abierto. Se trata .4fh 21h open_file . lo que ahora presento no llegar¡a precisamente muy lejos. En cx queda la longitud del virus .asignarla.direcci¢n del offset de "last" . algo que podr¡a ser un virus.escritura en el archivo. Por . En dx est la com_mask. o m s bien. y equ se encarga de . y se va a usar la .direcci¢n a partir de la cual se copian.buscar el primer archivo .com_mask 21h open_file: mov ax. Y dx apunta al principio del virus .es una variable que se va a utilizar . La funci¢n 3d abre el archivo.cx dx.del archivo encontrado.de la DTA. a uno indicar¡a s¢lo lectura por . No es muy necesario: CS va a ser el . que . salta a open_file.a 2 indica que se abrir para lectura y .encontrar un com ) .directorio de la forma que hay en la . funci¢n 3eh de la Int21h . es m s. cx indica la . Hace que len valga la .ste c¢digo al .04eh cx. o sea. . es lo ideal para comentar en &#8218.en el programa. Len . Si lo encuentra.ste archivo. Cierra el archivo. Busca el siguiente archivo . y AL puesto .del tama¤o del programa .direcci¢n a la que apunta dx.9eh int 21h Infect: mov lea mov int cx. se copiar todo &#8218.

com_mask: last: db "*. Tama¤o de la cabecera en p rrafos de 16 bytes. Aparte de tener una cabecera especial. Por tanto. Normalmente los linkadores ponen FFFFh aqu¡ para que el DOS de toda la memoria disponible al programa. salta con jnb si no ha habido ning£n fallo. Se trata . SS inicial Descripci¢n Marca de EXE (MZ = 4D5A).n lo infectar . de un byte para marcar el final ( para el equ del principio ) virus ends end start En resumen. M ximo de memoria requerido.opera con .0 db 090h .c*". Si lo encuentra.D ) Offset 00 sean MZ o ZM. 04 06 08 0A 0C 0E . &#8218. Una cosa que os puede parecer curiosa es que use jnb para saber si hay alg£n archivo m s en el directorio. el flag de acarreo se pone a uno. diferenci ndose segmentos de datos. El 0 del . menos la £ltima que ser N£mero total de paginas de 512 bytes N£mero de elementos de la tabla de elementos reubicables.stos dos bytes menos. lo infecta y busca otro.sto lo hace porque cuando el resultado de la interrupci¢n es un error ( como por ejemplo que no haya ning£n archivo ). pueden ocupar m s de un segmento. La cabecera EXE va como sigue ( no es necesario para hacer uno. Es obligatorio que &#8218. lo que hace es buscar el primer archivo que cumpla ser *. Bien.del virus final es necesario siempre que se archivos. pero tampoco se le tienen que hacer ascos a la informaci¢n . sino no funcionar 02 N£mero de bytes en la £ltma p gna del programa Todas las p ginas son de 512 bytes. tambi&#8218. ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ Õ¾ Estructura EXE Ô¸ ÔÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ; Los ficheros EXE tienen una estructura diferente a los Com. as¡ hasta que no quede ninguno.c* del directorio. M¡nimo de memoria requerido adem s de la necesaria para cargar el programa. c¢digo y pila.

la pila DATOS Mensa DATOS CODIGO ASSUME SEGMENT 'DATA' . . LISTADO DE EJEMPLO DE EXE PILA SEGMENT STACK 'STACK' DW 150 DUP (?) ENDS PILA .pila . Vamos con el de c¢digo CS:CODIGO.ax dx.SS:PILA Entrada PROC mov mov lea mov int mov int Entrada ENDP CODIGO ENDS END Entrada . Ponemos 150 palabras ( 300 bytes ) de .DATOS ds. Servicio 4Ch. excluido este campo.10 12 SP inicial Checksum: complemento a 1 de la suma de los valores de 16 bits del programa.sto.ndice A Ô¸ ÔÍÍÍÍÍÍÍÍÍÍÍÍÍ; . Abre ahora el segmento de datos DB 'Esto es un ejemplo EXE$' . El $ al final. . s¡mplemente que os qued&#8218.9 21h ax. Esto ha sido el segmento dedicado a . Valor del segmento DATOS Ahora queda en DS Desplazamiento del mensaje Servicio 9 de la int 21h Imprime el mensaje . . Ahora pongo un listado de t¡pico EXE: . retorna al DOS .mensa ah. 14 16 18 1A Visto &#8218.DS:DATOS.4C00h 21h . Cierra el procedimiento Entrada ÕÍÍÍÍÍÍÍÍÍÍÍ͸ Õ¾ Ap&#8218. que son CS:IP del EXE donde empieza la ejecuci¢n. IP inicial CS inicial Offset de la Tabla de Reubicaci¢n N£mero de Overlays generados. . Fin del programa ax. recordad ! ENDS SEGMENT 'CODE' .is con los offset 14 y 16. S es 0 es un £nico EXE.

AAM Ajusta ASCII despu&#8218. y si lo es. CALL Empuja IP y CS a la pila. AAS Ajusta ASCII despu&#8218. y salta a la direcci¢n que .Juego de instrucciones ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Instrucciones: Mnem¢nico AAA Adjust ASCII after Addition.reg/mem. almacenando en el operando destino el resultado de la suma ADD ADDition. Si se realiza ajuste. &#8218. ADD Suma al operando destino el operando origen. Comprueba si el contenido de AL supera a nueve.s de restar Se emplea despu&#8218. ajuste ASCII despu&#8218. almacenando el resultado en el de destino. suma 10 a AL.s de multiplicar Convierte el n£mero binario de 8 bits en AL en un n£mero BCD no empaquetado de dos d¡gitos en AX.s de sumar. almacenando en el operando destino el resultado. AL debe ser menor que 100 para que el ajuste proporcione un n£mero v lido. Esta instrucci¢n se emplea tras sumar dos n£meros BCD no empaquetados de dos d¡gitos con ADD AX. el flag de acarreo se activa. AH se incrementa si AL fue superior a 9.s de restar dos n£meros BCD no empaquetados con SUB AX. AND Realiza un AND l¢gico entre los dos operandos de la instrucci¢n. Explicaci¢n ADC Add With Carry. suma los dos operandos y el flag de acarreo.sta instrucci¢n suma los dos operandos y almacena el resultado en el de destino.reg/mem. y realiza si es cierto una operaci¢n que consiste en restar 10 de AL. Comrpueba si AL es mayor a 9.

reg/mem. CLD Clear Direction Flag. Verifica si el flag de acarreo auxiliar est a 1 o el contenido de los cuatro bits menos significativos de AL es mayor que 9. DEC Utiliza un operando. o sea. en cuyo caso se suma 60h a AL. en cuyo caso tendr que ser CMPSB o CMPSW ( Byte o Word ). pone e flag de interrupci¢n a cero. El flag de acarreo se activa si se ha realizado la segunda operaci¢n. con lo que no se podr n hacer llamadas a &#8218. pone el flag de acarreo a cero. su byte m s significativo.indica su operando. CMP Resta el operando origen del destino. pone a cero el flag de acarreo. puede usarse sin operandos. dejando cociente y resto. comprueba si el flag de acarreo est activado o el contenido de los 4 bits m s significativos es mayor que 9. lo que har ser copiar el signo de AX. quedando cociente y resto . El acumulador ser AX en caso de divisi¢n de 16 bits y DX-AX en caso de 32 bits. y el de acarreo auxiliar si se realiz¢ la primera. Tras &#8218. CBW Convert Byte to Word. CMPS Comparar cadena. invierte el contenido del flag de acarreo. o con ellos.sto. CLI Clear Interrupts. Los elementos a comparar est n apuntados por ES:DI y DS:DI CWD Convert Word to Double Word. copia el bit de mayor peso de AH en cada uno de los de AL CLC Clear Carry Flag. al que decrementa en una unidad. tan s¢lo que no almacena el resultado. DAA Decimal Adjust AL after Adittion. DIV Divide el acumulador entre el operando. en DX. si actualiz ndose sin embargo los flags. se emplea tras sumar dos n£meros BCD empaquetados de dos d¡gitos con ADD AL.stas hasta llegar a un STI ( Set Interrupts ) CMC CoMplement Carry flag. en cuyo caso se suma 6 a AL.

Si el operando destino es AX. copi ndose en el registro destino. ESC ESCape Sirve para pasar el control del procesador al copro HLT Bloquea el ordenador. almacena un segundo byte en AH ( el operando destino s¢lo puede ser AX o AL. LAHF Copia en AH el contenido del byte menos significativo del registro de flags LDS Load Far Pointer with DS. IDIV Divisi¢n para n£meros con signo IMUL Multiplicaci¢n para n£meros con signo. Cargar puntero lejano con DS. Con &#8218. lee un byte del puerto que especifica el operando origen y lo almacena en AL. INT Llama a la interrupci¢n del operando ( p. se lee una palabra en la direcci¢n indicada por el origen. que se almacena en DS . saca de la pila IP y CS y vuelve al sitio donde se llam¢ a la interrupci¢n ( cada vez que ejecutamos una interrupci¢n.ste IRET ) JMP Puede ser corto.ej. o sea. En caso de que sepamos con seguridad que no es as¡. el ordenador efectua una serie de pasos que acaban con &#8218. transfiriendo el control a otra parte del programa. llama a la interrupci¢n 4 si el flag de desbordamiento ( overflow ) est activado. IRET Interruption Return. cambiando IP y a veces CS con nuevos valores. IN INput from port. cercano o largo. y de nuevo se lee otra.sta instrucci¢n. es un NOP en realidad. sin modificar el estado de los flags.en AL-AH y AX-DX respectivamente. y el origen DX o un n£mero ) INC Incrementa el operando en un byte. INT 21h ) INTO INTerruption on Overflow.

sea byte o palabra. pudi&#8218. si el operando puesto en Mul es de 16 bits. .reg reg.mem mem.reg16 regseg.ndose realizar &#8218. por ejemplo ) LES Load Far Pointer with ES.segrer regseg. si el operando en Mul es de 8 bits. para saber si se opera con bytes o palabras. Cargar direcci¢n efectiva. Igual que LDS. saltar a la direcci¢n indicada en su operando ( por ejemplo. mover cadena Normalmente con el operando B ( byte ) o W ( Word ) de manera que se transfiera un byte o una palabra. el acumulador es AX. MOV Copia el operando origen en el destino. Carga en el acumulador el elemento apuntado por DS:SI. LOOP etiqueta ) mientras CX valga m s de 1. MOVS o XCHG.LEA Load Effective Adress. tan s¢lo que la segunda palabra la almacena en ES.inmed mem. y lo almacena en el destino ( bastante £til con etiquetas.ste sea usado por alg£n evento externo. multiplicar. MOVSB o MOVSW transfieren lo contenido en DS:SI a ES:DI MUL MULtiply. interrupciones.mem MOVS MOVe String. debe de indicarse con B o W. etc LODS LOaD String. y previene del uso del Bus mientras se ejecuta la instrucci¢n para evitar que &#8218. Se trata de una instrucci¢n que se usa precediendo a MOV. cuando su valor llegue a cero el bucle dejar de ejecutarse. LOCK Lock the Bus. ser AL. calcula el offset del operando origen.reg reg.stas combinaciones: reg. cargar cadena Si no hay operandos.inmed reg16. LOOP Bucle. Multiplica el acumulador por el operando .

por ejemplo: 11100100 OR 00101101 ---------11101101 OUT OUTput to port. . en &#8218. y 0 si los dos est n a 0.ste se copia el bit de mayor peso. invierte su valor. Escribe el contenido de AX o AL ( los dos £nicos operandos origen que se pueden usar con &#8218. o sea. o los dos lo est n. Compara uno a uno los bits de igual significaci¢n de los operandos.sta instrucci¢n ) en el puerto especificado por el operando destino ( DX o un n£mero directo ) POP Saca del valor operando de la pila POPF Saca de la pila el registro de flags PUSH Empuja a la pila el valor operando PUSHF Empuja el registro de flags a la pila RCL Rotate with Carry Left ( Rotar a la izquierda con acarreo ) Copia en cada bit del operando el contenido del que se halla a su derecha.stos bits.NEG Averigua el n£mero negativo del operando. El c lculo se realiza invirtiendo todos los bits y sumando uno al resultado. RCR Rotate with Carry Right ( Rotar a la derecha con acarreo ) Copia en cada bit del operando el contenido del que se encuentra a su izquierda. cambiando el valor de &#8218. y en el de menor el contenido del flag de acarreo. y da como resultado 1 si uno de ellos o los dos est a uno. Salida a puerto. NOP No OPeration. y en el bit de mayor peso el contenido del flag de acarreo. en el flag de acarreo el bit de menor peso. no hace nada NOT Invierte los bits del operando ( 1s en 0s y viceversa ) OR Realiza un 'O' l¢gico en los bits del operando.

REPeat if Not Equal ). ROL ROtate Left Copia en cada bit del operando el contenido del que se halla a su derecha.REP REPeat Utilizada sin operandos. REPE y REPNE ( REPeat if Equal. y el de menor se copia al flag de acarreo SBB SuBstract with Borrow Resta el operando origen y el flag de acarreo del operando destino. para realizar CX veces la operaci¢n indicada. para retornar al lugar desde el que se le llam¢. copiando en el bit de menor peso el contenido del de mayor peso ROR ROtate Right Copia en cada bit del operando el contenido del que se halla a su izquierda. SAL Shift Aritmetic Left Su sintaxis es [SAL destino. copiando en el bit de mayor peso el contenido del de menor peso SAHF Store AH in Flags.numero]. almacen ndose el resultado en el operando destino . atendiendo al estado de los flags. Almacenar AH en los flags Copia el contenido de AH en el byte de menor peso del registro de flags. o de IP y CS. RET RETurn Se utiliza para volver de una subrutina llamada con un Call. repite una operaci¢n tantas veces como el valor de CX. copiando en cada uno el contenido de aquel que estaba a su derecha. El byte de menor peso se pone a cero.s. aunque poco efectivamente ). pero al rev&#8218. y el mayor se copia en el flag de acarreo. cada bit copia el valor del de su izquierda.sta instrucci¢n.n con operandos como MOVSW por ejemplo.n dos variantes de &#8218. o sea. el de mayor peso queda a cero.sta ¢rden saca de la pila el valor de IP. Se utiliza tambi&#8218. Existen tambi&#8218. mueve los bytes del registro hacia la izquierda. SAR Shift Aritmetic Right Realiza las mismas operaciones que SAL. decrement ndolo cada vez ( puede usarse como delay. &#8218.

que se usar en lugar de ES SUB SUBstract. conserv ndose el resultado en &#8218. pero s¡ modifica los flags. Su funci¢n es copiar el contenido del acumulador ( AL o AX ) en ES:DI. y en funci¢n de ello actualiza los flags. no almacena los resultados. byte o palabra ( esencialmente si no se especifica ning£n operando ). resta El objetivo de &#8218. TEST TEST. Examinar cadena Se acompa¤a de una B o W detr s cuando no existe operando para indicar el tama¤o ( Byte o Word ) Resta el operando destino. que sustituir a ES como prefijo del operando destino. WAIT El computador entra en un estado de espera. Comparar Compara mediante un AND l¢gico los operandos origen y destino. Activa las interrupciones.ste operando destino. El operando puede llevar un prefijo de segmento. Activar flag de direcci¢n. que se ver activado cuando el 'test' input en el microprocesador sea . DI ir increment ndose/decrement ndose.SCAS SCAn String. SHL SHift Left Igual que SAL SHR SHift Right Ex ctamente igual que SAR STC SeT Carry flag. STI SeT Interrupts.sta instrucci¢n consiste en restar al operando destino el contenido del origen. que est indicado por ES:DI del acumulador ( sin realizar almacenamiento del resultado ). Activar flag de acarreo Activa el flag de acarreo ( lo pone a uno ) STD SeT Direction flag. Activar interrupciones. STOS STOre String Normalmente se usa con B o W al final para indicar el tama¤o. Lo pone a uno. El operando puede llevar prefijo de segmento.

ÓÄÄÄÄÄÄÄÄÄÄÄÄÄĽ NUMERACION NEGATIVA Bien. ¨ Como se representan mediante lenguaje ensamblador los n£meros negativos ? El sistema utilizado es el denominado 'aritm&#8218.ste cometido. por ejemplo en un XCHG AX.stas instrucciones un tanto curiosas. registro XOR ÖÄÄÄÄÄÄÄÄÄÄÄÄ&#8226. Si al n£mero binario 00000000 le restamos 00000001. tras la operaci¢n BX contendr¡a al antiguo AX. he preferido incluirlo como ap&#8218. ya que en un byte al pasar del n£mero m s bajo a uno "negativo".tica de complemento a dos'. Ser¡a tal que as¡: 11010101 01011011 ---------10001110 registro. Ö½ APENDICE B Ó&#8226. resultando un 1 tan s¢lo si uno y s¢lo uno de los dos bits comparados es 1. Para ello entonces.sta es una parte del curso que quiz debiera haber ido antes. pero por su complicaci¢n para la gente en fase de aprendizaje. y cero en el resto de los casos. y vicecersa. Se pas¢ bastante tiempo pensando en cu l ser¡a el m&#8218. que -x+x sumasen 0. Se puede indicar un operando para especificar el segmento en vez de DS XOR eXclusive OR Realiza un OR ( O ) excluyente entre el origen y el destino.activado. &#8218. almacena en AL un byte de la direcci¢n de memoria formada por DS y la suma de BX y AL. XCHG eXCHanGe ( intercambiar ) Intercambia los valores de los registros. hagamos una prueba.todo ideal para realizar &#8218. . siendo condici¢n principal que las sumas y restas diesen resultados l¢gicos. por ejemplo. XLAT Una de &#8218. sale el n£mero m s alto.BX. o sea. el resultado ser 11111111. compara uno a uno los bits de los dos operandos.ndice.

o sea. &#8218. y sumadle uno. as¡ como 11111110 al -2. 11111111 representar al '-1'. y se le suma 1. y &#8218. que sabemos que es negativo ( si estamos trabajando con n£meros negativos ) por el 1 en el bit de mayor peso: Se le da la vuelta: 01000100. As¡ visto. el n£mero 10111011.sto nos permitir comprobar cuando un n£mero es negativo tan s¢lo viendo si su primer bit est o no. o de lo que sea ). a uno. ¨ cu l es la manera m s r pida de saber el valor de un n£mero negativo ? Es bien f cil. 68 decimal. el n£mero 10111011 cuando trabajemos con n£meros con signo es el -69 ----------------------JoHN E.Por tanto.sto... el 01111111. dad la vuelta a todos los bits del byte ( o de la palabra.. Por tanto. y as¡ hasta llegar al 10000000.stas ser¡an algunas representaciones: 00000001 00000011 01111111 11111111 11111110 10000000 ----> ----> ----> ----> ----> ----> 1 3 127 -1 -2 -128 Y visto &#8218. P. que ser el -128. RiAÑo. ser el 127 entonces. El n£mero ex ctamente anterior.ej.com ©20003© . E-mail: sk8er_boi_7th@hotmail. ese ser el n£mero representado sin signo.