2016-04-05 10 views
1
int X = 0; 
int Y = 1; 
while(X <= 10){ 
    if(X%2 == 0) 
     Y = Y * X; 
    else 
     Y++; 

    X++; 
} 
cout << "Y is: " << Y; 

Das ist, was ich für meinen Easy68k-Code habe.Easy68k, Implementierung dieser While-Schleife

ORG $1000 
START:     ; first instruction of program 

MOVE.W #0,D1   ;PUT 0 IN D1 (X) 
MOVE.W #1,D2   ;PUT 1 IN D2 (Y) 

LOOP CLR.W D3  ;Find the remainder 
    MOVE.W D1,D3 
    DIVU #2,D3 
    SWAP D3 

    CMP  #0,D3  ;Compare remainder with 0 
    BEQ  EQUAL  ;If equal, then go to equal 

    ADD.W #1,D2  ;Y++ 
    ADD.W #1,D1  ;X++ 

    CMP  #11,D1  ;Compare D1 with 11 
    BEQ  DONE  ;If D1 equals 11, break loop.  
    BRA  LOOP 


EQUAL MULU.W D1,D2  ;Multiply D1 and D2 and store it in D2 
     ADD.W #1,D1  ;X++ 
     CMP  #11,D1 ;Compare D1 with 11 
     BEQ  DONE  ;If D1 equals 11, break loop. 
     BRA  LOOP 


DONE LEA MESSAGE,A1 
    MOVE.W #14,D0 
    TRAP #15 

    MOVE.W D2,D1 

    MOVE.W #3,D0 
    TRAP #15 


    SIMHALT    ; halt simulator 

MESSAGE DC.W 'Y is: ',0 


    END START  ; last line of source 

Ich bin mir nicht ganz sicher, was ist mit meinem Code falsch ist, aber ich habe das Gefühl, es ist ein Thema, zu Beginn des Schlaufenteils. Ich bin dem Code gefolgt, aber ich kann immer noch nicht herausfinden, wo es falsch läuft. Wenn ich es laufe, gibt es Y ist: 10. D1 und D2 sind auch beide A oder 10. Jede Hilfe wird geschätzt.

Antwort

1

Nach der Division und Tausch haben Sie immer noch Ergebnis und Rest der Division in d3. Dies bedeutet, dass es niemals Null sein wird und der Vergleich immer falsch ist. Sie müssen den oberen Teil mit and auf Null stellen oder ein Formular verwenden, das cmp verwendet, das nur den unteren Teil verwendet.

Nur ein Hinweis: Wenn Sie Reste von Zweierpotenzen machen, können Sie auch die Division überspringen und and direkt mit dem Wert minus eins verwenden. In diesem Fall entspricht der Rest der Division durch zwei dem and mit dem Wert 1.

+0

Vielen Dank, es funktioniert jetzt. Ich bin neu bei stackoverflow, also eine kurze Frage: Soll ich meine eigene Frage mit dem Arbeitscode beantworten oder meinen Originalbeitrag bearbeiten, um den Arbeitscode einzuschließen? – NobodyKnows

+0

@NobodyKnows Nein, wenn eine Antwort die richtige ist, wählen Sie sie mit dem Häkchen und Sie können Fragen auffrischen, die Ihnen geholfen haben. Das Häkchen zeigt, dass diese Antwort die Lösung für Ihr Problem ist. Ihre Frage sollte so bleiben, wie sie ist, da sie das ursprüngliche Problem zeigt, es sei denn, die Behebung ist etwas Wichtiges und die Antworten erklären es nicht klar, aber das ist selten. –

0

Anstatt divu zu verwenden, ist ein effizienterer und schnellerer Mechanismus für x% 2 einfach, den Status von Bit 0 zu überprüfen Dies wird auch etwas weniger Code ergeben. Dies funktioniert natürlich nur für eine Mod von 2 und alle anderen Werte werden einen anderen Ansatz (möglicherweise sogar die gefürchtete divide :))

Ändern Ihres vorhandenen Code zu lesen (getrimmten der Kürze halber) erfordern:

LOOP CLR.W D3  ;Find the remainder 
    MOVE.W D1,D3 
    btst #0,d3  ; Test bit 0 
    BEQ  EQUAL  ;If equal, then go to equal 
    ... 

Will deutlich schneller zu sein (auf echte Hardware) .. nicht, dass Sie wahrscheinlich bemerken werden :)

Dies funktioniert, weil Mod 2 im Wesentlichen sagt Ihnen, ob eine Zahl gerade oder ungerade ist, die sehr billig durch einfaches Suchen getan werden kann um festzustellen, ob das Bit 0 gesetzt ist

HTH

0

Beantwortung auf 'was ist falsch':

LOOP CLR.W D3  ;Find the remainder 
    MOVE.W D1,D3 
    DIVU #2,D3 

divu.w und divs.w Befehle auf 68000, um alle 32-Bit-Wort aus dem zweiten Argument und teilen sie durch 16-Bit-Wort in der ersten Argument angegeben. Ihr Code stört nicht, hohe 16 Bits von d3 vor der Division zu löschen. So die Änderung ist offensichtlich:

LOOP CLR.L D3  ;Find the remainder 
    ;all the same from here on