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