viernes, 16 de enero de 2015

Programa Fibonacci en x86/ARM [x86]

Parte x86


Algoritmo para calcular el valor de la sucesión de Fibonacci de una posición dada

Elección de los registros:


-dh: Hará las funciones de contador del bucle para llegar a la posición

MOV dh, 2

-dl: Almacenará la posición dada por teclado.

pusha
Invoke scanf, "%d", ADDR posicion
add esp, 8
popa

MOV dl, [posicion]

-Eax: Contendrá el resultado, el número que ocupa la posición dada, y de registro auxiliar para
mover f(n-2) y f(n-1)

-Ebx: Será el registro que contenga el valor de f(n-2)

MOV Ebx, 0

-Ecx: Será el registo que contendrá el valor de f(n-1)

MOV Ecx, 1


Llamadas a las subrutinas:


En este caso, el selector se comportará como un switch, dependiendo de que posición queramos calcular.

-Case_1:

  MOV Eax, 0
  JP > Fin_Switch

En caso de querer calcular la posición primera, se irá al caso 1 del switch, donde pondrá el registro de la solución a 0 y saltará al final del switch.

CMP dl, 1
JNG > Case_1


-Case_2:

  MOV Eax, 1
  JP > Fin_Switch

Si se quiere conocer la segunda posición, se saltará al caso dos donde se pondrá el registro solución a 1 y se saltará al final del switch.

CMP dl, 2
JE > Case_2

-Case_3:

MOV dh, 2
MOV Eax, 0
MOV Ebx, 0
MOV Ecx, 1
while:
  CMP dh, dl
  JGE > Fin_Switch

ADD Ebx, Ecx
MOV Eax, Ebx
MOV ebx, ecx
MOV ecx, eax
ADD dh, 1
JMP < while

En caso de querer saber una posición mayor que la tercera, el algoritmo irá calculando el número desde la tercera posición, y actualizando el contador hasta llegar a la posición dada.

CMP dl, 2
JE > Case_2
JG > Case_3

El caso 3:

MOV dh, 2
MOV Eax, 0
MOV Ebx, 0
MOV Ecx, 1
while:
  CMP dh, dl
  JGE > Fin_Switch

ADD Ebx, Ecx
MOV Eax, Ebx
MOV ebx, ecx
MOV ecx, eax
ADD dh, 1
JMP < while


Lo primero que ocurre en este caso es que se inicializan los registros necesarios, tras ello entra en un bucle while.

MOV dh, 2
MOV Eax, 0
MOV Ebx, 0
MOV Ecx, 1
while:

Una vez dentro del bucle while, lo primero que hace es comprobar si se cumple la condición de parada, que la posición actual, dh, sea mayor o igual que la posición dada, dl. Sí es así salta al final del switch.

  CMP dh, dl
  JGE > Fin_Switch

De no cumplirse la condición de parada, entra en el cuerpo del bucle, realizando la suma de f(n-1) + f(n-2)
y actualizando los registros, f(n-2) será f(n-1) y f(n-1) será f(n-1) + f(n-2)

ADD Ebx, Ecx
MOV Eax, Ebx
MOV ebx, ecx
MOV ecx, eax

Una vez realizado el cálculo de la posición, se incrementa la posición actual en uno y se salta al inicio del while.

ADD dh, 1
JMP < while

Continuará así hasta que llegue a la posición dada.

Fin_Switch:

Una vez terminado el caso correspondiente se salta al final del switch.

-Fin_Switch:
 pusha
Invoke printf, "El numero que ocupa la posicion %d es : %d ", [posicion], Eax
add esp, 12
popa
Xor Eax, Eax
Invoke system, "pause"
Invoke ExitProcess, Eax

Aquí se guardarán lo registros para llamar a la funcion de printf de c que imprimirá por pantalla la posición dada y el número que ocupa dicha posición en la sucesión. Tras ello se recuperan los registros y se procede a finalizar el programa.

Damián Nimo Márquez

No hay comentarios:

Publicar un comentario