CUESTIÓN D

Resolver Una Ecuación de Segundo Grado


Programa x86 (Descargar ejecutable)     (Descargar Fuente)
.Const

.Data
aa DQ 0
bb DQ 0
cc DQ 0
cuatro DQ 4.0
dos DQ 2.0
deter DQ 0
solucion DQ0


.Code

start:
;Inicio del programa principal.


 Invoke puts, "--- Calculo de ecuaciones de segundo grado ---"
 Invoke puts, "-------------- aX^2 + bX + c = 0 -------------"

repetir_a:
 Invoke printf, "Introduzca el valor de 'a' (a<>0): "
 Invoke scanf, "%f", Addr aa
 cmp d[aa], 0   ;comparamos el valor introducido con cero
 je > division_por_cero  ;Salta a la etiqueta division_por_cero si 'a'=0

 Invoke printf, "Introduzca el valor de 'b' : "
 Invoke scanf, "%f", Addr bb
 Invoke printf, "Introduzca el valor de 'c' : "
 Invoke scanf, "%f", Addr cc
 Invoke determinante ;calculamos el determinante que nos será devuelto en la pila (Pila:P0=determinante)
 fldz    ;Introducimos un cero (Pila:P0=0, P1=determinante)
 fcomi st0, st1  ;comparamos el determinante con cero (Pila:P0=0, P1=determinante)

 je > una_solucion ;Saltamos si el determinante vale cero

 ja > raiz_compleja ;Saltamos si el determinante es negativo

 ;Seguimos si la ecuación tiene dos soluciones
 fincstp   ;desplaza una posición la pila (Pila:P0=determinante, P1=0)
 Invoke puts, "La ecuación tiene dos soluciones."
 mov esi, 0   ;Inicializamos ESI a cero para que nos sirva como contador
 fsqrt   ;calculamos la raiz cuadrada del determinante (Pila:P0=raiz_determinante, P1=0)
 fst q[deter] ;almacenamos la raiz cuadrada del determinante
 finit   ;inicializamos la pila flotante (Pila vacía)
 fld q[deter] ;introducimos la raiz del determinante en la pila (Pila:P0=raiz_determinante)

soluciones:
 fld d[bb]  ;introducimos en la pila el valor de 'b' (Pila:P0=b, P1=raiz_determinante)
 fchs   ;cambiamos el signo a 'b' (Pila:P0=-b, P1=raiz_determinante)
 fmul   ;multiplicamos -b*determinante (Pila:P0=-b*raiz_determinante)
 fld d[aa]  ;introducimos en la pila el valor de 'a' (Pila:P0=a, P1=-b*raiz_determinante)
 fld q[dos]  ;introducimos un 2 en la pila (Pila:P0=2, P1=a, P2=-b*raiz_determinante)
 fmul    ;multiplicamos 2*a (Pila:P0=2*a, P1=-b*raiz_determinante)
 fdiv   ;dividimos (-b*determinante)/(2*a) (Pila:P0=(-b*raiz_determinante)/(2*a))
 fst q[solucion] ;almacenamos la solucion en memoria
 Invoke printf, "x=  %f ", [solucion]
 inc esi   ;sumamos 1 al contador
 cmp esi, 2  ;comprobamos si el contador vale 2
 je > fin  ;salta cuando ESI valga 2
 finit   ;inicilizamos la pila flotante(Pila vacía)
 fld q[deter]  ;introducimos la raiz del determinante en la pila (Pila:P0=raiz_determinante)
 fchs   ;cambiamos el signo al determinante (Pila:P0=-raiz_determinante)
 jmp soluciones ;salta para calcular la segunda solución



division_por_cero:
 Invoke puts, "--- El valor de 'a' no puede ser cero ---"
 Jmp < repetir_a ;Volvemos a pedir que introduzcan el valor de 'a'

una_solucion:
 finit    ;Inicializamos la pila flotante
 fld d[bb]  ;introducimos en la pila el valor de 'b' (Pila:P0=b)
 fchs   ;cambiamos el signo a 'b' (Pila:P0=-b)
 fld d[aa]  ;introducimos en la pila el valor de 'a' (Pila:P0=a, P1=-b)
 fld q[dos]  ;introducimos un dos en la pila
 fmul   ;multiplicamos 2*a (Pila:P0=2*a, P1=-b)
 fdiv   ;dividimos -b/(2*a) (Pila:P0=-b/(2*a))
 fst q[solucion] ;almacenamos la solucion en memoria
 Invoke printf, "--- La ecuación tiene una única solución: %f", [solucion]
 jmp > fin

raiz_compleja:
 Invoke puts, "--- La ecuación no tiene solución en el conjunto de los números reales."

fin:
 Invoke system, "pause"
 Xor Eax, Eax
 Invoke ExitProcess, Eax

;Fin del programa principal

;Subprogramas:

determinante:
 finit   ;inicializamos la pila
 fld d[bb]  ;almacenamos en la pila el valor de b (Pila:P0=b)
 fld d[bb]  ;almacenamos otra vez el valor de b (Pila:P0=P1=b)
 fmul   ;multiplicamos b*b. (Pila:P0=b*b)
 fld q[cuatro] ;almacenamos en la pila el 4 (Pila:P0=4, P1=b*b)
 fld d[aa]  ;almacenamos en la pila el valor de a (Pila:P0=a, P1=4, P2=b*b)
 fld d[cc]  ;almacenamos en la pila el valor de c (Pila:P0=c, P1=a, P2=4, P3=b*b)
 fmul   ;multiplicamos a*c (Pila:P0=a*c, P1=4, P2=b*b)
 fmul   ;multiplicamos (a*c)*4 (Pila:P0=4*(a*c), P1=b*b)
 fsub   ;restamos (b*b)-(4*(a*c)) (Pila:P0=(b*b)-(4*(a*c))
 fst q[deter]  ;guardamos el resultado en memoria
 ret