2016-08-08 65 views
-3

Ich habe einige Codes geschrieben diese Aufforderung zu lösen:HLA Assembly rekursive Fibonacci-Programm

Ein HLA Assembler-Programm, das für eine Zahl von dem Benutzer auffordert. Erstellen und rufen Sie eine Funktion auf, die einen Wert in der Fibonacci-Sequenz berechnet. In der Mathematik ist die Fibonacci-Folge nach dem italienischen Mathematiker Leonardo von Pisa benannt, der zu seinen Lebzeiten als Fibonacci bekannt war. Die Fibonacci-Sequenz beginnt mit 1 und 1. Jeder spätere Term in der Sequenz ist die Summe der beiden vorherigen Werte. Die Serie wird also lauten: 1,1,2,3,5,8,13 und so weiter. Um das volle Guthaben zu erhalten, müssen Sie eine Rekursion verwenden, um dieses Problem zu lösen. Erstellen Sie eine Funktion, deren Signatur lautet:

Prozedur fibRec (value: int8); @kein Bildschirm; @kein Rahmen; Hier sind einige Beispiel-Programm Dialoge Ihre Bemühungen führen:

eine Anzahl Stellen: 3 fib (3) = 2

Geben Sie einen Buchstaben: 5 fib (5) = 5

In einem Ich möchte Ihnen die folgenden C-Anweisungen anbieten, die den oben genannten Programmspezifikationen entsprechen. Wenn Sie möchten, verwenden Sie sie als Grundlage für den Aufbau Ihres Assembly-Programms.

und mein Ansatz ist zu versuchen, die C-Implementierung zu verwenden und in HLA umzuwandeln. Wenn ich das Programm starte, bekomme ich eine Endlosschleife (die cmd stürzt ab) wahrscheinlich wegen der Art, wie ich die Rekursion benutzt habe. Ich bin mir nicht sicher, wie man die

sonst result implementieren kann = fibRec (Wert-1) + FibRec (Wert-2);

Teil der C-Implementierung. Hier

ist, was ich habe:

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

klingt wie eine sch Zuordnung. – Mox

+3

Siehe http://stackoverflow.com/a/38795365/224132 für eine rekursive Fib (n) für x86. (Es ist Teil einer Antwort über eine Spielzeug-Asm, aber ich habe ein paar Makros und die gemeinsame Teilmenge dieser Sprache mit x86 verwendet, um eine rekursive Fib (n) zu schreiben, die für beide funktioniert.) andere Leute, schlecht recherchiert und voller irrelevanter Texte. Die gesamte erste Hälfte der Post könnte "Ich habe eine Aufgabe, Fibonacci (n) in HLA zu implementieren". –

Antwort

1

Erfahren Sie, wie Sie den Code debuggen, gibt es offensichtliche Probleme, wenn Sie versuchen würden, über sie zu dem Schritt, wie zu Beginn Sie Benutzereingabe mit dem Wert in CL überschrieben.

Dann in der Prozedur geben Sie den Parameter "Wert", aber arbeiten mit CL statt, überschreiben Inhalt von value (nicht sicher, was es in HLA, Stack Variable oder Speicher?).

Sie verwenden CL/DL 8-Bit-Register für Werte, aber C-Beispiel verwendet int (32b signiert).

Sie verwenden „@noframe“:

Die @NOFRAME Option weist HLA, die Sie nicht wollen, der Compiler automatisch für die Prozedur Eintritts- und Austrittscode zu erzeugen. Dies weist HLA an, die RET-Anweisung (zusammen mit mehreren anderen Anweisungen) nicht automatisch zu erzeugen.

Aber Sie haben nicht "ret();" Am Ende der Prozedur wird die Ausführung mit einem zufälligen Code fortgesetzt, der nach der Prozedur eingefügt wurde.

Und schließlich über Ihr Rekursionsproblem.

ASM ist nicht C, wenn Sie Subroutine aufrufen, sind die Register "live" wie sie sind, die ganze Zeit, nur einzelne von ihnen.

Also das ist ganz falsch:

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

Nach dem ersten sind Ihre CL und DL rufen bereits überschrieben. Die einfachste und einfachste Art, Registerwerte zu sichern, ist die Verwendung von Stack, dh push ecx, edx vor dem Aufruf, dann pop edx, ecx, um sie vom Stapel wiederherzustellen.

Zum Beispiel die fib. Unterprogramm in x86 32b Assembler geschrieben (NASM Intel Syntax So ist es mov destination, source, die andere Art und Weise als der 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 

Yep, so jetzt haben Sie nur die Syntax für HLA zu beheben ... (mehr wie schreiben Sie es um, damit Sie verstehen, wie es funktioniert).

Und lernen, wie Sie Ihren Code debuggen, ich glaube, ich habe vergessen, dies zu erwähnen.

Auch habe ich erwähnt, dass Sie Ihren Code debuggen sollten?

Ich habe diese Mine debuggen, also bin ich 100% sicher, es funktioniert wie erwartet (für kleine "n", wie einige hundert/tausend, nicht sicher, wie groß der Standard-Stack für Linux Elf32 binaries ist, und ich ' Ich werde es nicht versuchen, wenn es beim Stack-Überlauf zum Absturz kommt.

+1

* "HLA wurde ursprünglich als ein Werkzeug entwickelt, um Assemblersprachenprogrammierung zu lehren." * - also ja, fügen Sie C-ähnliche Dinge zu ASM hinzu, um es "einfacher" zu machen ... Ich stimme diesem Ansatz nicht zu. Besonders bei Studenten, die Null (1-2 Semester) Ahnung von C. haben – Ped7g