2016-08-08 2 views
-3
Fibonacci

J'ai écrit un code pour résoudre cette invite:Assemblée HLA récursif Programme

Créer un programme de langue HLA Assemblée qui demande un numéro de l'utilisateur. Créez et appelez une fonction qui calcule une valeur dans la séquence Fibonacci. En mathématiques, la séquence de Fibonacci est nommée d'après le mathématicien italien Leonardo de Pise qui était connu de son vivant comme Fibonacci. La séquence de Fibonacci commence par 1 et 1. Chaque terme plus tard dans la séquence est la somme des deux valeurs précédentes. Donc, la série sera: 1,1,2,3,5,8,13 et ainsi de suite. Afin de recevoir un crédit complet, vous devez utiliser récursion pour résoudre ce problème en créant une fonction dont la signature est:

procédure fibRec (valeur: int8); @nodisplay; @pas de cadre; Voici quelques dialogues de programme par exemple pour guider vos efforts:

fournir un numéro: 3 fib (3) = 2

Fournir une lettre: 5 fib (5) = 5

Dans un Pour vous aider à vous concentrer sur l'élaboration d'un programme d'assemblage, j'aimerais vous proposer les énoncés C suivants qui correspondent aux spécifications du programme énoncées ci-dessus. Si vous le souhaitez, utilisez-les comme base pour construire votre programme d'assemblage.

SAMPLE C CODE: 
------------------------ 
int main() 
{ 
    int value; 
    printf("Provide a value: "); 
    scanf("%d", &value); 
    int f = fibRec(value); 
    printf("fib(%d) = %d\n", value, f); 
    return(0); 
} 

int fibRec(int value) 
{ 
    int result = 1; 
    if (value == 1 || value == 2) // base case 
     result = 1; 
    else 
     result = fibRec(value-1) + fibRec(value-2); 
    return(result); 
} 

et mon approche est d'essayer d'utiliser l'implémentation C et de le convertir en HLA. Lorsque j'exécute le programme, j'obtiens une boucle infinie (le cmd se bloque) probablement à cause de la façon dont j'ai utilisé la récursivité. Je ne suis pas sûr comment mettre en œuvre le

d'autre résultat = fibRec (valeur-1) + fibRec (valeur-2);

partie de l'implémentation C.

Voici ce que j'ai:

program fib; 
#include("stdlib.hhf"); 

static 
     value : int8; 
     //returnAddress : dword; 
     //temp: int16; 


procedure fibRec(value : int8); @nodisplay; @noframe; 

begin fibRec; 

     mov(CL, value); 
     mov(1, DL); 

     cmp(CL, 1); 
     je Res1; 
     cmp(CL, 2); 
     je Res1; 

     jmp Else1; 

     //else result = fibRec(value-1) + fibRec(value-2); 
Else1: 

     //mov(1, DL); 

     dec(CL); 
     call fibRec; 

     sub(2, CL); 
     call fibRec; 

     add(CL, DL); 

     jmp ProgExit; 

Res1: 
     mov(1, DL); 
     jmp ProgExit; 

ProgExit: 


end fibRec; 


///////////////////////////////////////////////////////////////////////////////////////////////////// 

begin fib; 

    stdout.put("Provide a value: "); 
    stdin.get(value); //CHANGED TO IVALUE 

    mov(CL, value); //SAVES THE INPUT TO A REGISTER 


    call fibRec; // MUST CALL THE PROCEDURE 
    stdout.put("fib("); 
    stdout.puti8(value); 
    stdout.put(") = "); 
    stdout.put(DL); 



end fib; 
+0

ressemble à une affectation sch. – Mox

+3

Voir http://stackoverflow.com/a/38795365/224132 pour un Fib récursif (n) pour x86. (Cela fait partie d'une réponse à propos d'un jouet asm, mais j'ai utilisé quelques macros et le sous-ensemble commun de ce langage avec x86 pour écrire un Fib récursif (n) qui fonctionnera pour les deux.) Quoi qu'il en soit, downvoted d'autres personnes, mal documentées, et plein de beaucoup de texte non pertinent. La première moitié du message pourrait être "J'ai une mission pour implémenter Fibonacci (n) dans HLA". –

Répondre

1

Découvrez comment déboguer votre code, il y a des problèmes évidents si vous essayez d'enjamber, comme au début, vous écrasez l'entrée utilisateur avec une valeur en CL.

Ensuite, dans la procédure que vous spécifiez le paramètre « valeur », mais travailler avec CL à la place, le contenu de value écraser (pas sûr de ce qu'il est en HLA, la variable pile ou mémoire?).

Vous utilisez des registres CL/DL 8 bits pour les valeurs, mais l'exemple C utilise int (signé 32b).

Vous utilisez « @noframe »:

L'option @NOFRAME indique HLA que vous ne voulez pas le compilateur pour générer automatiquement l'entrée et le code de sortie de la procédure. Cela indique à HLA de ne pas générer automatiquement l'instruction RET (avec plusieurs autres instructions).

Mais vous n'avez pas "ret();" à la fin de votre procédure, de sorte que l'exécution se poursuivra sur un code aléatoire en place après votre procédure.

Et enfin à propos de votre problème de récurrence.

ASM n'est pas C, lorsque vous appelez sous-routine, les registres sont "live" comme c'est, tout le temps, seulement un seul ensemble d'entre eux.

c'est donc tout à fait tort: ​​

dec(CL); 
    call fibRec; 
    sub(2, CL); 
    call fibRec; 
    add(CL, DL); 

Après d'abord appeler votre sont déjà écrasées CL et DL. Le moyen le plus simple et le plus simple de conserver les valeurs de registre est d'utiliser la pile, c'est-à-dire push ecx, edx avant l'appel, puis pop edx, ecx pour les restaurer à partir de la pile.

Par exemple, le fib. sous-programme écrit en assembleur x86 32b (NASM Intel syntaxe Il est donc mov destination, source, l'autre façon que votre HLA!):

fibRecursion: 
    ; expects unsigned "n" (1+) in eax, returns fibonacci(n) in eax 
    ; will crash on large "n" due to stack overflow 
    cmp eax,2 
    ja moreThanTwo 
    mov eax,1   ; n: 0, 1 and 2 returns "1" 
    ret 
moreThanTwo: 
    push edx   ; preserve edx 
    dec eax 
    push eax   ; store n-1 in stack 
    call fibRecursion ; eax = fib(n-1) 
    xchg eax,[esp]  ; store fib(n-1) in stack, get n-1 into eax 
    dec eax 
    call fibRecursion ; eax = fib(n-2) 
    pop edx   ; edx = fib(n-1) 
    add eax,edx  ; eax = fib(n) = eax+edx 
    pop edx   ; restore edx 
    ret 

Eh oui, maintenant il vous suffit de fixer la syntaxe pour HLA ... (Plus réécrivez-le, alors assurez-vous de comprendre comment cela fonctionne).

Et apprendre à déboguer votre code, je pense que j'ai oublié de le mentionner.

Également j'ai mentionné que vous devriez déboguer votre code? J'ai fait déboguer cette mine, donc je suis sûr à 100% qu'elle fonctionne comme prévu (pour un petit "n", comme quelques centaines/milliers, je ne sais pas quelle est la taille de la pile par défaut pour les binaires linux elf32, et je '' je ne vais pas essayer quand il va planter sur le débordement de la pile).

+1

* "HLA a été conçu à l'origine comme un outil pour enseigner la programmation en langage assembleur." - Alors oui, ajoutez des choses en C à ASM, pour le rendre "plus facile" ... Je ne suis pas d'accord avec cette approche. Surtout avec des étudiants qui ont zéro indice (1-2 semestres) sur C. – Ped7g