PBN © Jaime Alberto Parra Plaza CLASE 9 INSTRUCCIONES ARITMÉTICAS. GENERACIÓN DE EXPRESIONES
PBN © Jaime Alberto Parra Plaza La instrucción básica en programación es la asignación mediante la cual se ordena a una variable tomar determinado valor. Físicamente esto corresponde a escribir en una posmem el valor indicado. En forma general, el valor se obtiene al evaluar una expresión. Un ejemplo sería: z = a * b / ( sin(c) + 1/d )
PBN © Jaime Alberto Parra Plaza EXPRESIONES: Una expresión se construye realizando operaciones entre variables y constantes. Las operaciones son del tipo: operador aritmético, evaluación de función, búsqueda en tabla, etc. Una expresión siempre produce como resultado una constante que se obtiene cambiando cada variable por su valor actual y evaluando el conjunto.
PBN © Jaime Alberto Parra Plaza Un microprocesador convencional sólo viene dotado para realizar operaciones aritméticas. Para el caso del 8086, los operandos sólo pueden ser de tipo carácter o de tipo entero, esto significa que si se desea realizar operaciones sobre números reales o funciones como raíz cuadrada o tangente, debe crearse una función específica para hacer tal labor.
PBN © Jaime Alberto Parra Plaza INSTRUCCIONES ARITMÉTICAS: a. Suma: ADD, ADC, INC, AAA, DAA b. Resta: SUB, SBB, DEC, NEG, CMP, AAS, DAS c. Multiplicación: MUL, IMUL, AAM d. División: DIV, IDIV, AAD, CBW, CWD
PBN © Jaime Alberto Parra Plaza INSTRUCCIÓN DE SUMA (ADD): Sintaxis: ADD destino, origen Propósito: Suma destino y origen y guarda el resultado en destino. Ejemplos: ADD AX, BX ADD AX, var16 ADD BYTE PTR [SI], cte8 ADD WORD PTR [BX], cte16 ADD CL, CH
PBN © Jaime Alberto Parra Plaza INSTRUCCIÓN DE INCREMENTO (INC): Sintaxis: INC destino Propósito: Destino se incrementa en 1. Ejemplos:INC DH INC var16 INC [BX][DI]
PBN © Jaime Alberto Parra Plaza INSTRUCCIÓN DE RESTA (SUB): Sintaxis: SUB destino, origen Propósito: Resta de destino a origen y guarda el resultado en destino. Ejemplos: SUB AL, cte8 SUB WORD PTR [DI], cte16 SUB BYTE PTR var8[BX], cte8 SUB CX, BX
PBN © Jaime Alberto Parra Plaza INSTRUCCIÓN DE DECREMENTO (DEC): Sintaxis: DEC destino Propósito: Destino se decrementa en 1. Ejemplos:DEC AL DEC var16 DEC var8[SI]
PBN © Jaime Alberto Parra Plaza INSTRUCCIÓN DE MULTIPLICACIÓN SIN SIGNO (MUL): Sintaxis: MUL operando Propósito: Multiplica el operando con el acumulador y guarda el resultado en el acumulador. Ejemplos:MULvar8 MUL CX MUL var16 MULvar8[SI][BI]
PBN © Jaime Alberto Parra Plaza El nombre acumulador se aplica a tres entidades: AL, AX y la pareja DX,AX. Se sobreentiende cual es a partir del tamaño de los operandos implicados. AL es el acumulador de 8 bits (Acc8), AX lo es para operaciones de 16 bits (Acc16) y DX,AX lo es para 32 bits (Acc32). De aquí surge que la multiplicación tenga dos casos:
PBN © Jaime Alberto Parra Plaza Caso a: Multiplicación sobre bytes: MUL oper8 Acc16 AL * oper8 Caso b: Multiplicación sobre words: MUL oper16 Acc32 AX*oper16
PBN © Jaime Alberto Parra Plaza INSTRUCCIÓN DE MULTIPLICACIÓN CON SIGNO (IMUL): Igual a MUL, pero los operandos se asumen signados.
PBN © Jaime Alberto Parra Plaza Ejemplo de multiplicación sin signo: MUL BL AHALBL antes??H45H82H después
PBN © Jaime Alberto Parra Plaza Ejemplo de multiplicación sin signo: MUL BL AHALBL antes??H45H82H después23H0AH82H
PBN © Jaime Alberto Parra Plaza Ejemplo de multiplicación con signo: IMUL BL AHALBL antes??H45H82H después
PBN © Jaime Alberto Parra Plaza Ejemplo de multiplicación con signo: IMUL BL AHALBL antes??H45H82H despuésDEH0AH82H
PBN © Jaime Alberto Parra Plaza INSTRUCCIÓN DE DIVISIÓN SIN SIGNO (DIV): Sintaxis: DIV operando Propósito: Divide el acumulador entre el operando y guarda el resultado en el acumulador. Ejemplos:DIVvar8 DIV CX DIV var16 DIVvar8[SI][BI]
PBN © Jaime Alberto Parra Plaza Caso a: División word/byte: DIV oper8 AL Acc16 / oper8 AH Acc16 % oper8 Caso b: División double/word: DIV oper16 AX Acc32 / oper16 DX Acc32 % oper16
PBN © Jaime Alberto Parra Plaza INSTRUCCIÓN DE DIVISIÓN CON SIGNO (IDIV): Igual a DIV, pero los operandos se asumen signados.
PBN © Jaime Alberto Parra Plaza Ejemplo de división sin signo: DIV BL AHALBL antes12H45H82H después
PBN © Jaime Alberto Parra Plaza Ejemplo de división sin signo: DIV BL AHALBL antes12H45H82H después7FH23H82H
PBN © Jaime Alberto Parra Plaza Ejemplo de división con signo: IDIV BL AHALBL antes12H45H82H después
PBN © Jaime Alberto Parra Plaza Ejemplo de división con signo: IDIV BL AHALBL antes12H45H82H después0FHDBH82H
PBN © Jaime Alberto Parra Plaza EXPRESIONES ARITMÉTICAS: Una expresión aritmética consta de constantes y variables operadas mediante sumas, restas, multiplicaciones y divisiones, tal como la siguiente: a + b * (5 - c/2) + (7 - x) / (y + 4)
PBN © Jaime Alberto Parra Plaza Las expresiones son útiles en un lenguaje de programación para realizar asignaciones y para realizar condiciones que permiten tomar decisiones. Ejemplo: z = a + 5*x;/* expresión de asignación */ if (b + c > d*3 - 9) /* expresión condicional */
PBN © Jaime Alberto Parra Plaza La clave para poder implementar una expresión en ensamblador es entender que el microprocesador sólo puede manejar una variable al tiempo. En consecuencia, una expresión que contenga N variables requerirá, como mínimo, de N instrucciones del microprocesador para llevarla a cabo.
PBN © Jaime Alberto Parra Plaza EJEMPLO 1:int x, y, z; z = x + y; Aquí se tienen 3 variables, o sea que se requerirán 3 o más instrucciones. El orden de tareas es: Primero hacer la suma Luego la asignación
PBN © Jaime Alberto Parra Plaza Suma: Como son dos variables, se debe guardar una en un registro y después hacer la suma con la otra. La suma debe hacerse de forma que el destino sea un registro para que no se altere el valor original de las variables: MOV CX, x ADDCX, y
PBN © Jaime Alberto Parra Plaza Asignación: Puesto que el resultado final de la expresión siempre debe quedar en un registro, el paso último es transferir dicho valor a la variable que guardará el resultado: MOVz, CX
PBN © Jaime Alberto Parra Plaza USO DE REGISTROS PARA EVALUAR EXPRESIONES: Para evaluar una expresión es casi imperativo el uso de registros, por la limitación ya establecida de una sola variable en cualquier instrucción. Es conveniente prestar atención a las siguientes recomendaciones:
PBN © Jaime Alberto Parra Plaza La anchura del registro debe corresponderse con el tipo de la variable con que se relaciona. En particular, se tienen registros de 8 y de 16 bits, válidos para interactuar con caracteres o enteros. Variables de más tamaño requieren conjuntos de registros.
PBN © Jaime Alberto Parra Plaza Cuando las variables en juego son punteros o variables compuestas (arreglos, matrices, cadenas, estructuras, etc.) la indexación debe hacerse con los registros capacitados para tal fin: BX, SI, DI y BP
PBN © Jaime Alberto Parra Plaza Algunas operaciones sólo admiten el uso de registros específicos, así que debe tenerse en cuenta esto antes de asignar tareas a los diferentes registros. En particular, se tiene que el acumulador es el registro requerido para multiplicación y división.
PBN © Jaime Alberto Parra Plaza La evaluación de una expresión debe hacerse siguiendo el orden de precedencia típico para las operaciones matemáticas: Paréntesis Función Incremento/Decremento Multiplicación/División Suma/Resta Si existen varias operaciones de la misma precedencia, se evaluarán de izquierda a derecha.
PBN © Jaime Alberto Parra Plaza El resultado de una expresión debe ajustarse al tamaño de la variable destino, lo cual puede implicar el truncamiento del resultado, con pérdida de información. Esto no debe preocupar al momento de realizar la expresión, pues es tarea del programa (y obviamente del programador) evaluar posteriormente si el valor es correcto.
PBN © Jaime Alberto Parra Plaza Por más compleja que sea una expresión, la cantidad de registros es suficiente para poder almacenar los resultados parciales, así que sólo en caso extremo se debe recurrir a la pila para tal efecto.
PBN © Jaime Alberto Parra Plaza EJEMPLO 2: char a[10], b[7][7], d; int w, x, y; d = x * (a[5] - 4/(y-b[3][w])); Como existen varios paréntesis, el contenido de cada uno se considera como una expresión en si mismo. Se empieza siempre evaluando el paréntesis más interno.
PBN © Jaime Alberto Parra Plaza Primer paréntesis: y - b[3][w] Como b es una variable compuesta, se usa el direccionamiento basado-indexado. En BX se ubica el valor de la fila (3), afectado por el total de columnas. La w se coloca en SI o en DI. Puesto que este resultado debe usarse como operando más adelante, el registro donde se guarda queda inhabilitado para el resto de la expresión.
PBN © Jaime Alberto Parra Plaza MOVCL, BYTE PTR y MOVBX, 21 MOVSI, w SUBCL, b[BX][SI] El resultado se guarda en CL. Como y es una variable entera, se fuerza su cambio a char con el qualificador byte ptr.
PBN © Jaime Alberto Parra Plaza División: 4 / {resultado anterior} Por ser una división, el dividendo debe ubicarse en el acumulador. Como se espera un resultado tipo byte, la división es de la forma word/byte.
PBN © Jaime Alberto Parra Plaza MOVAX, 4 IDIVCL Como las variables son signadas, se escoge la orden de división correspondiente; el resultado queda en AL. Puesto que la siguiente operación no es producto ni división no es necesario transferir este resultado a otro registro.
PBN © Jaime Alberto Parra Plaza Resta: a[5] - {resultado anterior} a es una variable arreglo, pero el índice es una constante, así que no se requiere direccionamiento por registros.
PBN © Jaime Alberto Parra Plaza MOVCL, a[5] SUBCL, AL CL ya había sido usado para albergar el primer paréntesis. A pesar de que existen otros registros vacíos se volvió a usar CL para indicar el método usual, que consiste en acostumbrarse a usar la menor cantidad posible de registros.
PBN © Jaime Alberto Parra Plaza Multiplicación: x * {resultado anterior} Por ser un producto, necesariamente debe colocarse uno de los operandos en el acumulador. Se ubicará a x dado que el otro operando ya está en CL.
PBN © Jaime Alberto Parra Plaza MOVAL, BYTE PTR x IMULCL De nuevo se usa un casting para acondicionar los operandos al tamaño requerido. El resultado final está ahora en AL (a pesar de que el resultado del producto se ubica en AX).
PBN © Jaime Alberto Parra Plaza Asignación final: d = {resultado anterior} Simplemente se transfiere el valor obtenido a la variable destino: MOVd, AL
PBN © Jaime Alberto Parra Plaza PREGUNTA: ¿Qué ajustes deben realizarse para poder dividir números de igual longitud (es decir, byte/byte o word/word), para números con y sin signo?. ¿Qué mecanismo puede emplearse para dividir números de longitud mayor a 32 bits?
PBN © Jaime Alberto Parra Plaza