Make your own free website on Tripod.com

TECNICAS DIGITALES III

TRABAJO PRACTICO NÚMERO 1 - 1997

Calculadora con 8051 (Primera parte)

Utilizar el siguiente formato para los números (21 bytes por número):

Las variables NRO1, NRO2 y NRO3 (de 21 bytes cada uno) estarán en XRAM.
Todas las variables que representen números en este formato deberán estar en un segmento con alineación INPAGE.

Ejercicio 1: Hacer una subrutina SUMA que sume dos números en este formato:

Entrada:NRO1: Sumando.
NRO2: Sumando.
Salida:NRO3: Suma.
Carry = 1: Hubo Overflow
Carry = 0: No hubo Overflow.

IMPORTANTE: Tener en cuenta que cualquiera de los números puede ser negativo. Usar la tabla siguiente:

Signo NRO1Signo NRO2|NRO1| > |NRO2|Signo de NRO3Valor de NRO3
PositivoPositivoPositivo|NRO1|+|NRO2|
PositivoPositivoNoPositivo|NRO1|+|NRO2|
PositivoNegativoPositivo|NRO1|-|NRO2|
PositivoNegativoNoNegativo|NRO2|-|NRO1|
NegativoPositivoNegativo|NRO1|-|NRO2|
NegativoPositivoNoPositivo|NRO2|-|NRO1|
NegativoNegativoNegativo|NRO1|+|NRO2|
NegativoNegativoNoNegativo|NRO1|+|NRO2|

Si el resultado es cero, poner el signo en positivo.

Ejercicio 2: Hacer una subrutina RESTA que cambie de signo a NRO2 y ejecute la subrutina SUMA.

Ejercicio 3: Hacer una subrutina MULT que multiplique dos números en este formato.

Entrada:NRO1: Factor.
NRO2: Factor.
Salida:NRO3: Producto.
Carry = 1: Hubo Overflow
Carry = 0: No hubo Overflow.

IMPORTANTE: Tener en cuenta que cualquiera de los números puede ser negativo. Usar la tabla siguiente:

Signo NRO1Signo NRO2Signo NRO3Valor absoluto NRO3
PositivoPositivoPositivo|NRO1|*|NRO2|
PositivoNegativoNegativo|NRO1|*|NRO2|
NegativoPositivoNegativo|NRO1|*|NRO2|
NegativoNegativoPositivo|NRO1|*|NRO2|

Si el resultado es cero, poner el signo en positivo.

Para realizar la multiplicación de la forma mas sencilla posible (aunque no sea la más óptima), hacer lo siguiente:

Considerar cada número como si fuera un entero de 20 dígitos. si M y N son los factores, P es el producto, Pi (con 0 <= i < 40) es un dígito del producto y (A*B)L representa el dígito menos significativo del producto A*B y (A*B)H representa el dígito más significativo de A*B:

T = 0
P = 0
Para i = de 0 a 19
    Para j = de 0 a 19
        Hallar Mi * Nj
        (Mi * Nj)H = (Mi * Nj)H + T
        Pi + j = Pi + j + (Mi * Nj)L Pi + j + 1 = Pi + j + 1 + (Mi * Nj)H + Carry de la suma anterior
        T = Carry de la suma anterior
    Siguiente j
Siguiente i

Para hallar el producto Mi * Nj no puede utilizarse la instrucción MUL del procesador pues se están multiplicando dígitos.

Una vez hallado el producto de 40 dígitos, debe verificarse que los diez dígitos más significativos valgan cero. De no ser así hay Overflow (hay que retornar con Carry = 1). El valor que debe almacenarse en NUM3 esta formado por los 20 dígitos centrales del producto.

Ejercicio 4: Hacer una subrutina DIVISION que divida dos números en este formato.

Entrada:NRO1: Dividendo.
NRO2: Divisor.
Salida:NRO3: Cociente.
Carry = 1: Hubo Overflow o división por cero.
Carry = 0: No hubo Overflow.

IMPORTANTE: Tener en cuenta que cualquiera de los números puede ser negativo. Usar la tabla siguiente:

Signo NRO1Signo NRO2Signo NRO3Valor absoluto NRO3
PositivoPositivoPositivo|NRO1|/|NRO2|
PositivoNegativoNegativo|NRO1|/|NRO2|
NegativoPositivoNegativo|NRO1|/|NRO2|
NegativoNegativoPositivo|NRO1|/|NRO2|

Para realizar la división, utilizar el siguiente pseudocódigo (M19-0 = Dividendo, D19-0 = Divisor, C19-0 = Cociente):

Si D = 0, indicar Overflow y salir.
C = 0                    ; Inicializar el cociente a cero.
Si M = 0, no indicar Overflow y salir.
Poner el signo del cociente según la tabla.
T = 10                   ; Inicializar exponente del cociente
Mientras D19 = 0 hacer :  ; Normalizar divisor.
    D = D * 10           ; Por cada ciclo que pase por aquí significa que el divisor era
    T = T + 1            ; más pequeño, por lo que el cociente es más grande.
Fin Mientras
Mientras M19 = 0 hacer :  ; Normalizar dividendo.
    M = M * 10           ; Por cada ciclo que pase por aquí significa que el dividendo era
    T = T - 1            ; más pequeño, por lo que el cociente es más pequeño.
Fin Mientras
D20 = 0                   ; Los cálculos se harán con 21 dígitos.
Si M < D:
    M = M * 10 (21 bytes)
    T = T - 1
Fin Si
Si T >= 20, indicar Overflow y salir.
Si T < 0, no indicar Overflow y salir.
Para i = de T a 0 (hacia abajo)
    R = -1
    Hacer
        R = R + 1
        M = M - D (21 bytes)
    hasta que haya carry.
    M = M + D (21 bytes)
    Ci  = R
Siguiente i
No indicar Overflow.

Ejercicio 5: Hacer una subrutina llamada RAIZ, que calcule la raíz cuadrada de un número.

Entrada:NRO1: Radicando.
Salida:NRO3: Raíz.
Carry = 1: El radicando era negativo.
Carry = 0: Se pudo calcular la raíz cuadrada.

Para hallar la raíz cuadrada, utilizar el siguiente pseudocódigo (si M19-0 es el radicando y R19-0 la raíz):

Si M es negativo, indicarlo y salir.
R = 0
Para i = 19 a 0 (hacia abajo)
    Si Mi > 0:
        Si i es impar:                  ; Inicializar x0
            R(i-1)/2 + 5 = 5
        Caso contrario:
            Ri/2 + 5 = 2
        Fin Si
        Para i = 1 a 10                 ; Realizar las iteraciones.
            TEMP = M / R (usando subrutina DIVISION)
            TEMP = TEMP + R
            R = TEMP / 2
        Siguiente i
        Indicar que se pudo calcular la raíz cuadrada
        Salir
   Fin Si
Siguiente i
Indicar que se pudo calcular la raíz cuadrada
Salir

En este pseudocódigo se utiliza el método iterativo de Newton para hallar la raíz cuadrada de n:

xi + 1 = 0,5(xi + n/xi)

IMPORTANTE: Como se está utilizando la subrutina DIVISION para calcular la raíz cuadrada, las variables M y R deberán copiarse a otro sector de memoria XRAM.

Para aprobar este trabajo práctico las subrutinas serán probadas en el simulador del 8051 para verificar su correcto funcionamiento.