0.- MOTIVACION.El lenguaje ensamblador continúa siendo imprescindible para imple-mentar fragmentos de código donde la velocidad del ejecutable y/omiten la inclusión directa en el código fuente de sentencias ensu tamaño sean críticos. Afortunadamente, muchos compiladores per-ensamblador, de forma que ya no es necesario en la mayor parte detablecerse desde el entorno de desarrollo y van implícitas en laslos casos el uso de ensambladores. Como ventaja adicional, no esnecesario conocer las directivas de ensamblador, ya que pueden es-directivas del compilador, por ejemplo, el compilador Pascal de1.-REGISTROS DEL 8086.Borland o el compilador C/C++ de la misma compañía.Aún así, a muchos programadores les resulta difícil renunciar alcontrol absoluto de la máquina que permite el lenguaje ensambla-CX, DX, SI, DI, BP, SP. Existe tambien un registro IP (Instructiondor.El 8086 dispone de ocho registros de propósito general, que pode-mos considerar como memorias implementadas sobre la misma CPU deregistros de segmento, llamados CS, DS, SS, ES y un registro deacceso muy rápido. Estos registros reciben los nombres de AX, BX, Pointer)que apunta a la siguiente instrucción a ejecutar, formandocontinuación. Aparte de los registros generales y de IP, existensu dirección junto con el registro CS, que citaremos a flags, cuyos bits no son accesibles directamente y que reflejanuna buena práctica de programación usarlos para lo que fueronlos resultados de distintas operaciones.Cualquiera de los registros de propósito general puede usarse paraescribir a/desde memoria, realizar operaciones, como punteros oprincipalmente concebidos.contadores, pero cada uno tiene una personalidad especial, y esMOV DS,AXAX se usa siempre en multiplicaciones y divisiones y es el maseficiente para operaciones aritméticas y de movimiento de datos.memoria. Por ejemplo, para cargar en AL el contenido de la posi-BX se usa como puntero, y junto con DS referencia posiciones de ción de memoria número 9: MOV AX,0 MOV BX,9DX es el único registro que puede usarse para acceder a puertos.MOV AL,[BX]CX se usa principalmente como contador en los bucles. Estos sontan frecuentes que existe una instrucción especial, LOOP, quedistinto de cero:comprueba su valor, volviendo al principio del bucle si es MOV CX,10 BUCLE: instrucciones LOOP BUCLEsucesivas de memoria cuando se usa con instrucciones de cadena:Por ejemplo, para escribir 62H en la dirección de puerto 1000H: MOV AL,62H MOV DX,1000H OUT DX,ALSI se usa como puntero. Su nombre proviene de Source Index, y seusa principalmente con instrucciones de cadena: CLDcarga en AX el valor de la posición 20 de memoria. SI se incrementaMOV AX,0 MOV DS,AX MOV SI,20 LODSBcesivas de memoria.en una unidad. En combinación con LOOP permite leer posiciones su-STOSBDI tambien se usa como puntero. Permite escribir en posiciones CLD MOV DX,0 MOV ES,DX MOV DI,2048la, y por ello no debe modificarse salvo que se sepa exactamenteescribe el contenido de AL en 0000:2048. Mientras que DI usa a EScomo segmento, SI usa a DS.de DI cuando se usa con funciones de cadena. BP actua tambien co-BX, DI y SI actuan como punteros relativos a DS, o a ES en el casoSP es entre los registros de uso general el mas específico, ya quemo puntero, pero relativo al segmento de pila SS. no se recomienda su uso, pues apunta al extremo superior de la pi-De esta forma, el armazón de un programa en ensamblador es el si-que se está haciendo. 2.-ESTRUCTURA DE UN PROGRAMA EN ENSAMBLADOR.Expondremos brevemente la estructura de un programa fuente en en-samblador. Este está compuesto por una serie de segmentos para lados.pila, el código y los datos. Los segmentos no pueden estar anida- Cada uno comienza con el nombre del segmento seguido de la pala-palabra ENDS.bra SEGMENT y alguna o algunas cadenas exigidas por el enlazador. Cada segmento termina con el nombre del segmento seguido de la El programa termina con la palabra END seguida del nombre del pun-labra) seguida del número de palabras que vamos a reservar y lato de entrada al programa. guiente:PILA SEGMENT STACK 'STACK'. .DATOS SEGMENT 'DATA'PILA ENDS . .CODIGO SEGMENT 'CODE'DATOS ENDS . .donde [ENTRADA] es el nombre del punto donde se inicia la secuen-CODIGO ENDS END [ENTRADA] cia de instrucciones.forma habitual de hacerlo es mediante la sentencia DW (define pa-Dentro del segmento de pila, se establece el tamaño de ésta. La sentencia DUP (?). Así:ca el número de veces a incluir consecutivamente expresión2 en elPILA SEGMENT STACK 'STACK'DW 100H DUP(?)establece un segmento de pila con un tamaño de 100H palabras (512PILA ENDSbytes), sin especificar el contenido inicial.Las directivas que se emplean habitualmente para establecer eltamaño de la pila son:DW Define Word 2 Bytes.DB Define Byte 1 Byte.DQ Define cuádruple palabra 8 Bytes.DD Define doble palabra 4 Bytes.La [directiva] puede ser DB, DW, DD, DQ. La expresión puede ser:La sintaxis de DUP es expresión1 DUP expresión2. expresión1 indi- segmento. Cuando expresión2 es (?) indicamos que no es importantepila queda inicializada a ceros o a cualquier otro valor particu-el contenido inicial. No se debe cometer el error que con (?) la lar.Vayamos por partes: [nombre] es un campo opcional pero absoluta-Pasemos al segmento de datos. La sintaxis de las líneas conteni- das en este segmento es [nombre] [directiva] expresión(es).. Una cadena entre comillasmente conveniente, ya que especificándolo nos podremos referir después a la dirección de la variable simplemente nombrándola. . Un valor numéricoapuntarán durante la ejecución los diferentes registros de segmen-. Una tabla de valores separados por ","Así, son válidas las líneas siguientes:Nada DW (?)Mensaje DB 'Hola' Peso DB 70La última línea se puede simplificar con DUP en la forma siguien-Vector DB 0,0,0,13,120,76,76,76,76,76,76 te:Considérese la variable como un puntero a un dato del tipo defi-Vector DB 3 DUP(0),13,120,6 DUP(76)El segmento de código suele tener una primera línea con la direc-nido por D[X], y el valor especificado a continuación como el va- lor apuntado.datos. De esta forma, el segmento de código de un programa .COMtiva ASSUME, que informa al ensamblador de los segmentos a los que to. Por ejemplo:ASSUME CS:CODIGO, DS:DATOS, SS:PILASi deseamos generar un ejecutable de tipo COM, es necesario cum-plir ciertas normas. La primera es que el programa fuente debela pila. La otra limitación es que el punto de entrada debe estarcontener un solo segmento, donde residirán el código, los datos y en el desplazamiento 100H de dicho segmento. La directiva ORG 100HLo habitual es que a continuación forzemos un salto al verdaderoindica al ensamblador que continúe el ensamblado a partir de la dirección dada por el argumento, en este caso 100H. punto de entrada, estando el espacio intermedio ocupado por loscontrol al sistema operativo. La encargada de realizar esta tareacomenzaría:CODIGO SEGMENT 'CODE'ASSUME CS:CODIGO, DS:CODIGO, SS:CODIGOORG 100H Inicio: JMP Entrada .Entrada PROC. ; espacio para los datos . . . . Entrada ENDPUn dato a tener en cuenta es que somos responsables de iniciali-CODIGO ENDS END Iniciopor ejemplo, para inicializar el registro DS:zar correctamente los registros para que apnten a los segmentos, MOV AX,DATOSpara terminar el programa, liberando la memoria y devolviendo elMOV DS,AX Por otro lado, siempre será necesario llamar a una función del DOSconstante y, por defecto, BX indica desplazamientos respecto ales la función 4CH de INT 21H, de manera que al final del segmentode código será preciso introducir las siguientes dos líneas:Existen dieciseis formas de referenciar una posición de memoria.MOV AH,4CH INT 21H 3.-MODOS DE DIRECCIONAMIENTO.que se construyen, pues, en realidad, todas se forman mediante laNo nos ocuparemos aquí de sus denominaciones, sino de la forma en+ + desplcombinación de unos pocos elementos. Así, se podía escribir simbólicamente BX SI4.1. Instrucciones de transferencia de datos.BP DI donde despl es una constante o una expresión resoluble en unasegmento DS, mientras que BP indica desplazamientos respecto alsegmento SS.mento de datos. Se dan una serie de formas equivalentes para refe-Como ilustración, sea una cadena de caracteres definida en el seg-CADENA DB 'ABCDEFGHIJKL',0renciar al elemento número ocho de la cadena: .DATA .CODE MOV AX,@DATA MOV DS,AX ...MOV BX,OFFSET CADENAMOV SI,OFFSET CADENA + 8 MOV AL,[SI] ... MOV BX,8 MOV AL,[CADENA+BX] ... MOV AL,[BX+8] ...Todos los ejemplos anteriores se han puesto con la instrucción MOVMOV SI,8 MOV AL,[CADENA+SI] ... MOV BX,3 MOV SI,4 MOV AL,[CADENA+BX+SI+1] 4.- JUEGO DE INSTRUCCIONESMOV AX,Datosque es con diferencia la mas usada en cualquier programa. Hay quetener en cuenta sin embargo algunas cosas que no pueden hacerseEn primer lugar, no pueden moverse datos directamente entre doscon la instrucción MOV. posiciones de memoria. Así MOV Datos1,Datos2 es una expresión ile-En segundo lugar, no se pueden mover datos directamente de un re-gal. En su lugar se escriben las dos líneas: MOV AX,Datos2 MOV Datos1,AXEn tercer lugar, no se puede mover una constante directamente a ungistro de segmento a otro. MOV DS,ES es ilegal. En su lugar pode- mos escribir: MOV AX,ES MOV DS,AXPUSH AXregistro de segmento. MOV DS,Datos es ilegal. En su lugar escriba- mos MOV DS,AX Finalmente, no se puede usar CS como operando.MOV pertenece a un primer grupo de instrucciones de transferenciade datos, entre la memoria y los registro y a/de los puertos desiguientes:entrada/salida. Las instrucciones mas usadas de este grupo son las PUSH, POP y sus variantes para almacenar o extraer datos de la pi-contenidos. Describiremos brevemente cada una de ellas.la. IN, OUT para obtener datos de un puerto o enviarlos. LEA, LDS, LES para mover direcciones de variables, en lugar de susrealizarán en orden inverso a las instrucciones PUSH. Por ejemplo,PUSH se usa para guardar en la pila un dato, y POP para recuperar- lo. Como la pila tiene estructura LIFO, las instrucciones POP seAlgunos ejemplos pueden ser los siguientes:si se quieren guardar los registro AX y BX y recuperarlos después, la secuencia correcta es PUSH BX . . POP BX POP AXPUSH y POP también son adecuados para transferir el contenido deun registro a otro, por ejemplo PUSH AX POP BXse necesita guardar todos los registro generales para recuperarlostransfiere AX a BX. Este método es sin embargo mas lento. A vecesPOP, se usan las instrucciones PUSHA y POPA. Además de aportar co-después. En lugar de escribir una serie de PUSH y otra serie denes se ejecutan más rápido. Cuando se quiere guardar el registromodidad al programador y legibilidad al programa, estas instruccio- de indicadores, se usan las formas PUSHF y POPF.IN acumulador,puertoLas instrucciones de entrada/salida IN/OUT se usan para comunicar- se con los periféricos del sistema, y tienen el formato OUT puerto,acumuladordonde registro es un registro de propósito general de 16 bits ydonde el acumulador es AX o AL según se trata de bytes o palabras.IN AL,200 ; pasa a AL el contenido del puerto 200OUT 20H,AX ; envía al puerto 20H el contenido de AXLas instrucciones de transferencia de direcciones permiten códigofuente mas compacto sobre todo cuando se trata con direccionamien-MOV AL,[BX+SI+20]tos indexados. Por ejemplo, consideremos la instruccióndo le suma 20, usando el valor obtenido como desplazamiento dentroEl micro toma el valor de BX, le suma el valor de SI y al resulta-MOV DX,BXdel segmento DS para acceder a un byte y transferirlo al registro AL. Esta instrucción lleva implícitas las operaciones:conjunto, llamada LEA (Load Effective Address) para cargar un des-ADD DX,SI ADD SI,20 Existe una instrucción mas rápida y compacta que sustituye a este plazamiento. Su sintaxis estambién en una unidad. El resulta se trunca al número de bits delLEA registro,mem16 mem16 es un operando de memoria de tipo palabra. Por ejemploLEA DX,[BX+SI+20]transfiere a DX el desplazamiento BX+SI+20. La variante LDS es si-milar. Su sintaxis es LDS reg16,mem32de orden mas bajo en el registro especificado, y los mas altos enLee una palabra doble de 32 bits de la memoria y carga los 16 bitsSupongamos que queremos cargar el segmento de Tabla_, definida co-DS. Similar a la anterior es LES: funciona exactamente igual salvo que los 16 bits mas altos los guarda en ES.MOV AX,SEG Etiquetamo Etiqueta DD Tabla_ en DX, y su desplazamiento en BX. Una forma de hacerlo es mediante la serie MOV BX,DESPL Etiqueta MOV DX,AXra incrementa el operando en una unidad. La segunda lo decrementaLa mejor forma de hacerlo es mediante LDS BX,Etiqueta 4.2. Instrucciones aritméticas. Las instrucciones aritméticas mas simples son INC y DEC. La prime-de menor tamaño. En este caso pondríamos a cero BH mediante unaoperando. Así, si todos los bits del operando están a 1, el opera-dor INC los pasará a todos a cero. El bit adicional necesario paranunca modificará AH.representar el resultado correcto se pierde. De esta forma, INC AL Las instrucciones suma y resta son ADD y SUB, y su sintaxis esalmacenado en destino. En el segundo, fuente se resta de destino,ADD destino,fuente SUB destino,fuente En el primer caso, se suma fuente a destino, y el resultado quedade aritmética sobre número fijo de bits, los acarreos se pierden.y el resultado queda almacenado en destino. En principio, los ope- randos fuente y destino han de ser del mismo tamaño, y al tratarseADD BL,AX. En estos casos se procede a la extensión del operandoA veces sin embargo es necesario operar sobre números de distinto tamaño en bits. Por ejemplo, no es posible escribir directamenteel operando, y puede ser un registro de 8 bits o un operando deinstrucción MOV o mediante un XOR. Pero esto es válido solo cuandoestamos tratando con números sin signo. Para extender un númeroCWD (Convert Word to Double word).con signo se recurre a los operadores CBW (Convert Byte to Word) yse hace entre AL y un operando cualquiera de ocho bits, registro oLas instrucciones de multiplicación y división son MUL y DIV, y usan el acumulador en todos los casos. La multiplicación de 8 bitsEl resultado es de 32 bits, de los cuales los 16 menos significa-memoria, y el resultado es de 16 bits, quedando almacenado en AX. ¿Que ocurre cuando se multiplica AX por otro operando de 16 bits ? tivos se almacenan en AX y los mas significativos en DX.sin signo MUL operandoCuando se divide un operando de 16 bits entre otro de 8, se obtie- ne un cociente de 8 bits y un resto también de 8 bits. El dividen- do se ha de encontrar en AX, mientras que el divisor se indica enmemoria. El cociente se devuelve en AL y el resto en AH. En formasimbólica podríamos poner AX ¦ Divisor +------Cuando se divide un número de 32 bits entre otro de 16 bits, co-AH ALde encontrarse en DX, y los menos significativos en AX. El divisorciente y resto son de 16 bits. Los 16 bits mas significativos hangistro de 16 bits o un operando de memoria de 16 bits. El cocientese indica en el operando, y al igual que antes, puede ser un re- de 16 bits se devuelve en AX, y el resto en DX. Simbólicamente:cación y división. Uno para operandos con signo y otro para ope-DX¦AX ¦ Divisor +------ DX AX Existen en realidad dos juegos de instrucciones para la multipli-instrucciones a utilizar. La sintaxis es:randos sin signo. Es el programador quien decide si los operandos representan números con signo o sin signo, y por tanto el juego de DIV operandoSi el resultado es distinto de cero, el bit n-simo de reg se esta-con signo IMUL operandoIDIV operandoOtro conjunto de instrucciones son las de manipulación de bits,que a su vez puede dividirse en operaciones lógicas, de desplaza-miento y de rotación. Expondremos sólo las primeras. Estas sonlógicas del mismo tamaño. La sintaxis esAND, OR y XOR y efectúan las mismas operaciones que las funciones AND destino,fuente OR destino,fuentequier registro: XOR reg,reg es igual que MOV reg,0 , pero es masXOR destino,fuente La instrucción XOR es especialmente útil para poner a cero cual- rápida.ejemplo, para comprobar si el bit n-simo de un registro se encuen-La instrucción AND pone a cero ciertos bits, de forma que se puede efectuar una determinada operación con el resto de los bits. Por4.3. Instrucciones de transferencia de controltra a 1, basta hacer AND reg,mascara, donde mascara es un número binario donde todos los bits son cero, menos el n-simo, que vale 1. ba a uno.[destino] es la dirección de comienzo. La última instrucción de unLas instrucciones que conforman un programa se almacenan en ordencorrelativo en la memoria, pero, salvo en los casos mas sencillos,distintas partes de la secuencia. Las instrucciones de control seno se ejecutan linealmente, sino que el control se transfiere a pueden dividir en: . Transferencia incondicional4.3.1. Transferencia incondicional. Transferencia condicional . Bucles Analizaremos cada uno de estos grupos, presentando las instruccio- nes mas frecuentes.conjunto de instrucciones que se ejecutan mas de una vez pero queDentro del primer grupo contamos con las instrucciones CALL, RET y JMP. La primera se usa para llamar a un procedimiento, esto es, un se escriben una sola. Este conjunto de instrucciones se almacenanprocedimiento es RET, que devuelve el control al programa princi-en memoria a partir de una posición dada, y cada vez que se nece- sita ejecutarlas, se transfiere el control a la primera instruc- ción de la serie mediante la instrucción CALL [destino], dondeinstrucciones siguientespal. Cuando se llama a CALL, la primera tarea que realiza es guar-dar en la pila la dirección de la siguiente instrucción, para re-procedimiento. El operando de CALL es habitualmente una etiqueta ,cuperarla y continuar el programa cuando se termine de ejecutar el indicando la dirección origen del procedimiento, pero también pue-de CALL y RET es:den hacerse llamadas indirectas a través de un registro o un ope- rando de memoria. No entraremos en este punto. El esquema general CALL etiqueta instrucciones siguientes .Es posible anidar procedimientos, de forma que un procedimiento. etiqueta: MIPROC PROC instrucciones siguientes . RET MIPROC ENDP pueda llamar a otro, y así sucesivamente. El nivel de anidamientoMIPROC1 PROCsolo está limitado por el tamaño de la pila, donde se guardan las direcciones de retorno. Por ejemplo: CALL etiqueta1 instrucciones siguientes . . etiqueta1: . CALL etiqueta2efectúa el salto, se consumen solo tres ciclos de reloj. Los sal-.RETMIPROC1 ENDPetiqueta2:instrucciones siguientesMIPROC2 PROC .MIPROC2 ENDP. RETLa instrucción JMP (jump, saltar) se usa para transferir el con-trol al punto del programa que se desee. Cuando la dirección des-salto, este se llama corto. En caso contrario, cercano, si destinotino se encuentra en el rango -128,127 bytes de la instrucción de se encuentra dentro del mismo segmento y lejano si se encuentra en4.3.2. Transferencia condicionalotro segmento. Los saltos lejanos se generan especificando el seg- mento y desplazamiento del destino. El juego de instrucciones para transferencia condicional es espe-programas de forma que, siempre que sea posible, se ejecute el ca-cialmente rico. El ensamblador reconoce algunas instrucciones de transferencia condicional con varios mnemónicos, con objeto de fa- cilitar la tarea al programador. Es un buen hábito construir losCasi todas las veces, las condiciones de salto en un programa sonso esperado si no se efectúa el salto. La razón es que, si no se tos condicionales son siempre cortos, y su sintaxis esdonde [mnemonico] es de una a tres letras y destino_corto es unaJ[mnemonico] destino_cortoetiqueta situada en el rango -128,127 bytes desde la instrucciónde salto. Las únicas condiciones que pueden comprobarse son el es-nales se refieren a la última operación efectuada. Existen tantastado de los flags, lo que equivale a decir que los saltos condicio- instrucciones de salto como flags, pero las mas utilizadas sontos se puede superar usando la instrucción JMP. Consideremos lasJZ salta si cero JNZ salta si no cero La limitación de los saltos condicionales de que sean saltos cor-en generar un salto con la condición contraria por encima de uninstrucciones J[x],JN[x], donde J[x] salta si el flag "x" está a uno y JN[x] salta si el flag "x" está a cero. La técnica consiste JMP a la dirección deseada. Por ejemplo, para implementarJB destino[fuenteJ[x] etiqueta_lejana escribimos JN[x] etiqueta JMP etiqueta_lejana etiqueta:del tipo A]B , A[B , A=B , A[]B , A]=B y A[=B. Por exigencias dela aritmética de complemento a dos, existen en realidad dos juegosde instrucciones, según que se comparen números con signo o sin él.Para comparaciones de números sin signo, se emplean en los mnemó- nicos las letras A (de Above, por encima) y B (de Below, por deba-tantes comprueban los flags de cero, acarreo y desbordamiento, quejo), y para las comparaciones de números con signo las letras G (de Greater, mayor) y L (de Less, menor). Las instrucciones resul- han sido previamente establecidos mediante una instrucción CMP. LaBX[AX, las instrucciones adecuadas sonsintaxis de esta instrucción es CMP destino,fuente y compara destino con fuente. Por ejemplo, si queremos comparar los números sin signo contenidos en AX y BX y saltar a etiqueta si CMP BX,AXJNE destino[]fuenteJB etiqueta y si los números tienen signo, la secuencia es: CMP BX,AX JL etiqueta Los mnemónicos mas usados son .para números sin signo JA destino]fuente JE destino=fuentedenas o para buscar un valor concreto en una zona de memoria.JBE destino[=fuenteJAE destino]=fuenteJG destino]fuente.para números con signoJNE destino[]fuenteJE destino=fuenteJLE destino[=fuenteJL destino[fuente4.3.3. Instrucciones de bucleJGE destino]=fuenteLas instrucciones de bucle hacen que se repitan fragmentos de có-digo un número prefijado de veces. Una forma de hacerlo es median-comienzo:te el contador y un salto condicional al final del bucle MOV CX,repeticiones . .señada para este propósito:. DEC CX JNZ comienzo Este fragmento puede compactarse usando la instrucción LOOP, di-LOOP comienzo ; si CX[]0, salta a comienzoMOV CX,repeticiones comienzo: . . .Las instrucciones de cadena se utilizan habitualmente para inicia-; de lo contrario, sigue en esta línea 4.4. Instrucciones de cadena.trucción LODS. La instrucción mas usada es MOVS (MOVe String), lalizar una zona de memoria a un mismo valor, para mover un bloque contiguo de datos de una zona a otra de memoria, para comparar ca-El funcionamiento de este conjunto de instrucciones depende del"flag de dirección", cuyo valor puede ser alterado por las dos ins-trucciones siguientes CLD: CLear Direction flagLas instrucciones de cadena tienen mnemónicos que terminan con laSTD: SeT Direction flagda caso. Ya que pueden actuar sobre bytes o palabras, es necesarioletra "S", y operan sobre los registros que se especificarán en ca-La instrucción LODS (LOaD String), en sus versiones LODSB y LODSW,indicar este extremo, lo que se conseguirá escribiendo la letra "B" o "W" tras la "S" del mnemónico.cero, SI se incrementa en 1 o 2, y si está a 1 se decrementa en 1se usa para cargar un byte o palabra desde la dirección indica- da por DS:SI en AL o AX. Si el flag de dirección se encuentra ade la misma forma que LODS y almacena el contenido del registroo 2. De esta forma puede recorrerse la memoria en uno u otro sen- tido. La instrucción complementaria es STOS (STOre String). Se usa AL o AX en la dirección de memoria especificada por ES:DI. El re-+-----------+ STOSgistro DI se altera según la misma lógica que el SI con la ins- cual sirve para trasladar uno (MOVSB) o dos bytes (MOVSW).Esta instrucción lee un dato de DS:SI y lo almacena en ES:DI. Des-pués, los registro SI y DI se modifican según la misma lógica quePara efectuar operaciones repetitivas con estas funciones, podemospara las instrucciones LODS y STOS. implementar un bucle que repitiera un número prefijado de veces lagestionar explícitamente los registro SI y DI porque estos se ac-operacion a realizar con estas instrucciones. No sería necesario tualizan automáticamente. Sin embargo, el lenguaje ensambladorcadena que vayamos a usar, antes de la misma. Obsérvese el frag-permite hacer esto mismo de forma mas compacta mediante la ins- trucción REP. Esta instrucción se coloca en la misma línea que la instrucción de mento de código siguiente:MOV DI,5678H ; desplazamiento. Dirección de comienzoCLD ; incrementa DI cada vez MOV AX,1234H ; segmento en que escribe MOV ES,AX ; STOS almacena en ES:DI XOR AL,AL ; pone AL a cerolos siguientes:MOV CX,200D ; inicializa CX a 200D REP STOSB ; ejecuta 200D veces la orden STOSB ; ahora, CX=0 y DI=5678H+200D En resumen: ¦ AX ¦ AL ¦ -----------] ES:DI [----++-----------+ ¦MOVS+-----------+ LODS ¦+-----------+¦ AX ¦ AL ¦ [----------- DS:SI -----+comparar dos cadenas. Sus mnemónicos son SCAS (SCAn String),y CMPSExisten dos instrucciones más que permiten examinar una cadena yLa instrucción SCASB es equivalente a CMP AL,ES:[DI], mientras que(CoMPare String). Ambas admiten las "versiones" para byte y pala- bra añadiendo las terminaciones B y W.las operaciones anteriores.SCASW es equivalente a CMP AX,ES:[DI]. El resultado de estas ope- ración altera los flags y DI se actualiza según la lógica vista entre DS:[SI] y ES:[DI], es decir, CMP DS:[SI],ES:[DI]. Al igual queLa sintaxis CMPSB o CMPSW es CMPS mem1,mem2, donde mem1 y mem2 son operandos de memoria. En concreto, CMPS realiza la comparación en- en el caso anterior, estas instrucciones alcanzan su máxima utili-REPNE (REPeat while Not Equal).dad al usarlas en combinación con los operadores REPZ (REPeat whi- le Zero, repetir mientras cero) y REPNZ (REPeat while Not Zero). REPZ y REPNZ admiten los sinónimos REPE (REPeat while Equal) y Los usos mas comunes de las instrucciones que hemos presentado sonENTRADA: AH=2 (nº de servicio)* Encontrar el primer elemento distinto del contenido del acu-mulador dentro de un bloque. Para esto se usa REPZ SCAS.usa REPZ CMPS.* Encontrar el primer elemento diferente entre dos cadenas. Se* Encontrar el primer elemento igual entre dos cadenas: REPNZ* Encontrar la primera ocurrencia del contenido del acumulador dentro de un bloque: REPNZ SCAS. CMPS.efecto, el PC almacena en la ROM BIOS una enorme cantidad de proce-5.- USO DE INTERRUPCIONES La filosofía del PC es ésta: dejar que la BIOS haga el trabajo. Endeterminada interrupción. Cada interrupción tiene un número y ofre-dimientos que podemos usar en nuestro provecho, simplemente invo- cándolos. El lenguaje ensamblador permite pasar el control a unación puede o no devolver valores.ce diversos servicios. El número de servicio se especifica en AH, y en otros registros se especifican otros parámetros. La interrup- La instrucción en ensamblador que permite ejecutar interrupcioneslumna determinadas. En este caso:es INT, y su sintaxis es INT [nº función]. Por ejemplo, la función 10H tiene muchos servicios útiles para controlar el video. Uno de estos servicios consiste en posicionar el cursor en una fila y co- BH=página de video en la que fijar posiciónMENSAJE DB 'ESTO ES UN MENSAJE $'DH=fila DL=columnaPor ejemplo, para colocar el cursor en la fila 10, columna 15, elSALIDA: No tieneMOV AH,2 ; nº de serviciofragmento de código apropiado seríaMOV DH,0AHMOV BH,0 ; suponemos que 0 es el nº de página activa MOV DL,0FH INT 10Hy servicios de la ROM BIOS. La lista de funciones es tan extensaExiste abundante bibliografía donde se recogen todas las funciones que puede hacer creer que el emsamblador es mas complicado de loescribir un programa en ensamblador con la dificultad para retenerque lo es realmente, al menos al nivel que será usado en este curso. Pero el alumno no deberá confundir la dificultad para o incluso solo localizar la función que en un momento dado sirva a- Siempre será preciso terminar un programa, para lo que se recurrenuestros propósitos. Solo a modo de ilustración, se exponen a continuación las funciones mas usuales que aparecen cuando se empieza a programar en ensamblador: a la funcion 4CH de INT 21H: MOV AH,4CHdonde [MENSAJE] se ha definido en el segmento de datos medianteINT 21H - Casi siempre será preciso mandar mensajes a la pantalla, para lo que se usa la función 9: MOV DX,OFFSET [MENSAJE] MOV AH,9 INT 21H una linea del estilo destandard:y $ es el carácter que necesita la función 9 para identificar elfinal de la cadena.no en cada línea, y por eso se añaden al mensaje los caracteresCuando hay varios mensajes que mostrar, lo normal es escribir u-MENSAJE DB 'ESTO ES UN MENSAJE',10,13,'$'10 y 13, que significan respectivamente salto de línea y salto de carro:de INT 10H realiza el trabajo. Para ello, BH contendrá el núme-- Cuando se quiere mostrar un mensaje, muchas veces se desea colo- carlo en una posición determinada de la pantalla. La función 02H- Ocurre casi siempre que al iniciar un programa deseamos limpiarro de la página de pantalla, DH la línea y DL la columna, de 0 a 24 y de 0 a 79 respectivamente. la pantalla. Para ello, sobreescribimos con espacios en blanco yMOV DI,0 ; apuntamos ES:DI al inicio de la RAM de videolos atributos que deseemos la RAM de video, que en adaptadores a color comienza en la direccion 0B800H: MOV AX,0B800H MOV ES,AX MOV AL,32 MOV AH,07H ; carácter 32, gris sobre negro- Tambien es frecuente leer una cadena de caractéres de la entradaMOV CX,2000 ; 2000 caracteres REP STOSW - Casi siempre será preciso leer un carácter desde teclado, de lo que se encarga la función 1. El resultado queda almacenado en AL: MOV AH,1 INT 21H MOV AH,3FHEn el apéndice A se da una relación de las funciones BIOS.MOV BX,0 MOV CX,[LONGITUD MAXIMA]MOV DX,[DESTINO DE LA CADENA]INT 21H AND AX,AX3FH es la función del DOS que permite leer cadenas. Si BX=0, seleen desde entrada standard, que es el teclado. La longitud[DESTINO DE LA CADENA] que es OFFSET [VARIABLE DE CADENA]. Comomáxima se encuentra en CX, y la cadena leida va a parar a AX guarda la longitud de la cadena leida, AND AX,AX comprueba siMOV CX,[LONGITUD CADENA]se ha leido algún carácter. - Igualmente frecuente es la escritura de una cadena en la salida standard: MOV AH,40H MOV BX,1MOV DX,OFFSET [CADENA]INT 21H
martes, 5 de marzo de 2019
BREVE RESUMEN DE LENGUAJE ENSAMBLADOR
Suscribirse a:
Comentarios de la entrada (Atom)
Unidad No.3: Mejora programa # 9: Letras de colores(Versión Ingrid Sauceda)
Ejecución del programa: Código: include 'emu8086.inc' Mostrar Macro Mensaje LEA DX,Mensaje ;mandamos el mensaje a leer MO...
-
EDICION Los archivos fuente de código ensamblador deben estar en formato ASCII standard. Para esto puede usarse cualquier editor que ...
-
INTERRUPCIÓN Una interrupción consiste en un mecanismo que provoca la alteración del orden lógico de ejecución de instrucciones como resp...
-
MENSAJES EN EL MONITOR Todos los gráficos y el texto que se muestran en el monitor se escriben en la RAM de visualización de video, pa...
No hay comentarios.:
Publicar un comentario