Material Teórico para Taller de Microprocesadores I INTRODUCCIÓN AL ENSAMBLADOR: El lenguaje ensamblador, o assembler, es un lenguaje de programación de bajo nivel que permite escribir código máquina mediante expresiones abreviadas (mnemotécnicos) para los computadores, microprocesadores, microcontroladores y otros circuitos integrados programables. Implementa una representación simbólica de los códigos de máquina binarios y otras constantes necesarias para programar una arquitectura dada de CPU y constituye la representación más directa del código máquina específico para cada arquitectura legible por un programador. PROCESOS PARA LA CREACIÓN DE UN PROGRAMA: Para la creación de un programa es necesario seguir cuatro pasos: 1. Diseño del algoritmo y del diagrama de bloques 2. Codificación del algoritmo (elaboración del código fuente) 3. Prueba del programa 4. Depuración del programa Un algoritmo es un conjunto prescrito de instrucciones o reglas bien definidas, ordenadas y finitas que permite realizar una actividad mediante pasos sucesivos que no generen dudas a quien deba realizar dicha actividad. Ejemplo de un algoritmo para una lámpara eléctrica que no funciona: El diagrama de bloques de un sistema electrónico es la representación gráfica de las partes o etapas que hacen posible el funcionamiento de ese sistema, este funcionamiento se divide en bloques que representen partes o etapas específicas del sistema en cuestión, y que, además, definen la organización de todo el circuito electrónico interno, sus entradas, procesos y sus salidas. Ejemplo de un diagrama de bloques para un inversor: En la etapa de diseño se plantea el problema a resolver y se propone la mejor solución, creando diagramas de flujo y diagramas de bloques utilizados para el mejor planteamiento del requerimiento y su solución. La codificación del programa consiste en escribir el programa en algún lenguaje de programación (en este caso en ensamblador emu8086), tomando como base la solución propuesta en el paso anterior. La prueba del programa consiste en verificar que el programa funcione sin errores, o sea, que haga lo que tiene que hacer. La última etapa es la eliminación de las fallas detectadas en el programa durante la fase de prueba. La corrección de una falla normalmente requiere la repetición de los pasos comenzando desde el primero o el segundo. ENSAMBLADOR EMU8086 Este programa es sumamente útil para aquellos que quieran aprender lenguaje ensamblador (Assembler), ya que incorpora un editor avanzado, un ensamblador, una PC virtual y tutoriales paso a paso. De esta manera, es posible ejecutar código fuente sobre un emulador 8086, siendo el código de máquina totalmente compatible con las generaciones siguientes de microprocesadores Intel. Al hacer doble clic en el icono del emu8086 aparecerá una ventana como la de la figura 3 Luego de elegir el tipo de programa a crear aparecerá una ventana como la de la figura 5, la cual no es más que un editor de textos con varias herramientas que permiten y ayudan el desarrollo del código fuente. Algunas de estas son file, edit, assembler, math, ascii code, help, new, open, examples, LA ESTRUCTURA DEL ENSAMBLADOR EMU8086: En el lenguaje ensamblador las líneas de código constan de dos partes, la primera es el nombre de la instrucción que se va a ejecutar y la segunda son los parámetros del comando u operando. Por ejemplo: ADD ah, bh Aquí "ADD" es el comando a ejecutar (en este caso una adición o suma) y tanto "ah" como "bh" son los parámetros. El nombre de las instrucciones en este lenguaje puede estar formado de 2 a 6 letras, a estas instrucciones también se les llama nombres mnemónicos o códigos de operación, ya que representan alguna función que habrá de realizar el procesador. Existen algunos comandos que no requieren parámetros para su operación, así como otros que requieren solo un parámetro. Algunas veces se utilizarán las instrucciones como sigue: ADD al, [170]. Los corchetes en el segundo parámetro nos indican que vamos a trabajar con el contenido de la casilla de memoria número 170 y no con el valor 170, a esto se le conoce como direccionamiento directo (en la instrucción viene la dirección del objeto). MOVIENTO DE LOS DATOS: En todo programa es necesario mover datos en la memoria y en los registros de la CPU; existen diversas formas de hacer esto: Puede copiar datos de la memoria a algún registro De registro a registro De un registro a una pila De la pila a un registro Además es posible transmitir datos hacia dispositivos externos así como recibir datos de dichos dispositivos. Estos movimientos de datos están sujetos a reglas y restricciones. Algunas de ellas son las que se citan a continuación. No es posible mover datos de una localidad de memoria a otra directamente, es necesario primero mover los datos de la localidad origen hacia un registro y luego del registro a la localidad destino. No se puede mover una constante directamente a un registro de segmentos, primero se debe mover a un registro de la CPU. INSTRUCIONES PARA MOVIMIENTOS DE DATOS Las instrucciones de transferencia de datos copian datos de un sitio a otro y son: MOV, XCHG,XLAT, LEA, LDS, LES, LAHF, SAHF, PUSH, PUSHF, POP, POPF. LA INSTRUCION MOV Realiza la transferencia de datos del operando de origen al destino. MOV admite todos los tipos de direccionamiento. Ambos operandos deben ser del mismo tamaño y no pueden estar ambos en memoria. Ejemplos del uso de la instrucción MOV MOV MOV MOV MOV MOV MOV MOV MOV MOV reg, reg ; reg es cualquier registro. mem, reg ; mem indica una posición de memoria reg, mem mem, dato ; dato es una constante reg, dato seg-reg, mem ;seg-reg es un registro de segmento seg-reg, reg mem, seg-reg reg, seg-reg MODOS DE DIRECCIONAMIENTO Se entiende por modos de direccionamiento a las diferentes formas que pueden tomar los parámetros de las instrucciones del procesador. A continuación se presentan los cuatro principales modos de direccionamiento: 1. 2. 3. 4. Direccionamiento inmediato Direccionamiento de registro Direccionamiento directo Direccionamiento indirecto INMEDIATO El modo de direccionamiento INMEDIATO es utilizado cuando se hace referencia a un valor constante. Este se codifica junto con la instrucción. Es decir dicho parámetro representa a su valor y no a una dirección de memoria o un registro que lo contiene. Ej: MOV Ax, 500 En este ejemplo el número 500 es un parámetro inmediato. REGISTRO Un parámetro que direcciona a un registro está utilizando el modo de direccionamiento REGISTRO. Ej: MOV Ax, Bx En este ejemplo los dos parámetros direccionan un registro. DIRECTO Se utiliza el modo directo cuando se referencia a una dirección de memoria y la misma esta codificada junto con la instrucción. Ej: MOV Al, [127] En este ejemplo el desplazamiento de la dirección de memoria se codifica junto con la instrucción y el segmento se asume a DS. INDIRECTO Se utiliza el modo indirecto cuando se referencia a una dirección de memoria a través de uno o varios registros. Ej: MOV Al, [Bx] Aquí el offset de la dirección de memoria está contenido en el registro Bx y al igual que el caso anterior como no se especifica el segmento se asume DS. La tabla 1 indica los registros de segmento así como los registros puntero y a cual registro base apunta cada registro puntero por defecto. Una referencia a memoria se forma con un segmento y un desplazamiento ej: ES:BX, CS:IP , DS:BX+SI+5 • Algunos registros tienen asociado un segmento por defecto (Por lo que no es necesario ponerlos explícitamente) DS es segmento por defecto de BX, SI y DI ES es segmento por defecto de DI (en operaciones de cadena) SS es segmento por defecto de SP y BP CS es segmento por defecto de IP OPERACIONES LÓGICAS Y ARITMÉTICAS: Las instrucciones de las operaciones lógicas son: AND, NOT, OR y XOR, éstas trabajan sobre los bits de sus operandos. Para verificar el resultado de operaciones recurrimos a la instrucción CMP. Las instrucciones utilizadas para las operaciones algebraicas son: para sumar ADD, para restar SUB, para multiplicar MUL y para dividir DIV. Casi todas las instrucciones de comparación están basadas en la información contenida en el registro de banderas. Normalmente las banderas de este registro que pueden ser directamente manipuladas por el programador son la bandera de dirección de datos DF, usada para definir las operaciones sobre cadenas. Otra que también puede ser manipulada es la bandera IF por medio de las instrucciones STI y CLI, para activar y desactivar respectivamente las interrupciones. A continuación explicaremos brevemente las intrucciones aritméticas y lógicas por separado: OPERACIONES ARITMÉTICAS: Las operaciones en aritmética binaria a entera permiten a la CPU realizar cálculos con números enteros positivos y negativos con una representación en complemento a 2. • NEG operando: cambia el signo del operando. Equivaldría al NOT del número y le sumaría 1. • ADD destino, fuente: destino = destino + fuente. • ADC destino, fuente: destino = destino + fuente + carry (acarreo). • SUB destino, fuente: destino = destino - fuente. • SBB destino, fuente: destino = destino - (fuente + acarreo). • MUL operando: multiplica sin considerar el signo. Multiplica el acumulador {AL} o {AX} por el operando fuente. Si el operando fuente es de tipo byte, el resultado se almacena en AX y si es de tipo palabra el resultado se almacena en AX la parte inferior y en DX la palabra superior. Si tipo fuente = byte: AX = AL * fuente (multiplicación sin signo) Si tipo fuente = palabra: DX, AX = AX * fuente (multiplicación sin signo) Si mitad superior (CF: acarreo) del resultado = 0 En CC CF = 1 • IMUL operando: multiplica considerando el signo. • DIV operando: divide sin considerar el signo, un número contenido en el acumulador entre el operando fuente. El cociente se almacena en el acumulador. El resto se almacena en la extensión del acumulador. Si la extensión de AX será DX (que ocurrirá cuando sea de tipo palabra), la operación y la extensión de AL será AH. AX AX AL DX • IDIV operando: igual que el DIV pero considerando el signo. • CBW: pasa de byte a palabra el contenido del acumulador. • CWD: pasa de palabra a doble palabra el contenido del acumulador. • INC destino: incrementa el destino. • DEC destino: decrementa el destino. OPERACIONES LÓGICAS: Se usan para realizar operaciones a nivel de bits. • NOT operando: cambia los bits 1 por 0 y viceversa y devuelve el resultado en el mismo operando. AL = F2h AL 1111 0010 NOT AL; NOT AL 0000 1101 = Odh • OR destino, fuente: operación o lógico inclusivo. El resultado se almacena en destino. AX = FEDCh= 1111 1110 1101 1100 BX = 1234 h = 0001 0010 0011 0100 OR AX, BX 1111 1110 1111 1100 = FEFC h • AND destino, fuente: la operación Y lógica entre 2 operandos, el resultado se deja en destino. AX = FEDC h 1111 1110 1101 1100 BX = 1234 h 0001 0010 0011 0100 ADD AX, BX 0001 0010 0001 0100 = 1214 h • XOR destino, fuente: la operación o lógico exclusiva; el resultado se deja en destino. AX = FEDC h 1111 1110 1101 1100 BX = 1234 h 0001 0010 0011 0100 XOR AX, BX 1110 1100 1110 1000 = ECE8 h