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 NRO1 | Signo NRO2 | |NRO1| > |NRO2| | Signo de NRO3 | Valor de NRO3 |
---|---|---|---|---|
Positivo | Positivo | Sí | Positivo | |NRO1|+|NRO2| |
Positivo | Positivo | No | Positivo | |NRO1|+|NRO2| |
Positivo | Negativo | Sí | Positivo | |NRO1|-|NRO2| |
Positivo | Negativo | No | Negativo | |NRO2|-|NRO1| |
Negativo | Positivo | Sí | Negativo | |NRO1|-|NRO2| |
Negativo | Positivo | No | Positivo | |NRO2|-|NRO1| |
Negativo | Negativo | Sí | Negativo | |NRO1|+|NRO2| |
Negativo | Negativo | No | Negativo | |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 NRO1 | Signo NRO2 | Signo NRO3 | Valor absoluto NRO3 |
---|---|---|---|
Positivo | Positivo | Positivo | |NRO1|*|NRO2| |
Positivo | Negativo | Negativo | |NRO1|*|NRO2| |
Negativo | Positivo | Negativo | |NRO1|*|NRO2| |
Negativo | Negativo | Positivo | |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 NRO1 | Signo NRO2 | Signo NRO3 | Valor absoluto NRO3 |
---|---|---|---|
Positivo | Positivo | Positivo | |NRO1|/|NRO2| |
Positivo | Negativo | Negativo | |NRO1|/|NRO2| |
Negativo | Positivo | Negativo | |NRO1|/|NRO2| |
Negativo | Negativo | Positivo | |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.