1
int X = 0;
int Y = 1;
while(X <= 10 ){
    if(X%2 == 0)
        Y = Y * X;
    else 
        Y++;

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

This is what I have for my Easy68k code.

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

I'm not exactly sure what is incorrect about my code but I have a feeling it is an issue at the beginning of the loop section. I have followed along with the code but I still cannot figure out where it is going wrong. When I run it, it outputs Y is: 10. D1 and D2 are also both A or 10. Any help is appreciated.

3 Answers3

1

After doing the division and swap you still have both result and remainder of the division in d3. This means it will never be zero and the comparison is always false. You need to zero the upper part with and or use a form.of cmp that only uses the lower part.

Just a note: when you are doing remainders of powers of two you can also skip the division and use and directly with the value minus one. In this case the remainder of division by two is the same as and with the value 1.

Sami Kuhmonen
  • 30,146
  • 9
  • 61
  • 74
  • Thank you, it works now. I'm new to stackoverflow so a quick question: Am I suppose to answer my own question with the working code or edit my original post to include the working code? – NobodyKnows Apr 05 '16 at 05:34
  • @NobodyKnows No, if an answer is the right one you choose it with the check mark and you may upvote questions that helped. The check mark shows that that answer is the solution to your problem. Your question should stay at as it is since it shows the original problem, unless the fix is something major and the answers don't clearly explain it, but that's rare. – Sami Kuhmonen Apr 05 '16 at 05:39
0

Rather than using divu a more efficient and faster mechanism to do the same as x%2 is simply to check the status of bit 0. This will also yield a bit less code. This obviously only works for a mod of 2 and any other values will require another approach (possibly even the dreaded divide :) )

Changing your existing code to read (trimmed for brevity):

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 be significantly faster to execute (on real hardware).. not that you are likely to notice :)

This works because mod 2 essentially tells you if a number is even or odd, which can be done very cheaply by simply looking to see if bit 0 is set

HTH

Graeme
  • 1,643
  • 15
  • 27
0

Answering on 'what is incorrect':

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

divu.w and divs.w commands on 68000 take full 32-bit word from second argument and divide it by 16-bit word specified in first argument. Your code doesn't bother to clear high 16 bits of d3 before division. So the change is obvious:

LOOP CLR.L   D3        ;Find the remainder
     ;all the same from here on
lvd
  • 793
  • 3
  • 12