Реализация цикла while в 68k - PullRequest
0 голосов
/ 08 июля 2019

Переведите следующий код на язык ассемблера и покажите окончательное значение Y. (2 балла)Я НЕ УВЕРЕН, ЕСЛИ МОЙ ВЫХОД ПРАВ.РЕЗУЛЬТАТ 3712

*-----------------------------------------------------------
* Title      :
* Written by :
* Date       :
* Description:
*-----------------------------------------------------------
    ORG    $1000
START:                  ; first instruction of program

* Put program code here

  MOVE.W  #1,D1           ;PUT 0 IN D1 (X)
  MOVE.W  #2,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
     BNE     NOTEQUAL   ;If NOT equal, then go to NOT 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

NOTEQUAL 
      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

* Put variables and constants here

MESSAGE DC.W    'Y is: ',0

    END    START        ; last line of source

1 Ответ

2 голосов
/ 10 июля 2019

Это приведет к неожиданным результатам, если верхнее слово D3 содержит данные больше 1.

LOOP CLR.W   D3      ; D3 = [**** 0000]
     MOVE.W  D1,D3   ; D3 = [****    X]
     DIVU    #2,D3   ; if D3.h > 1, division overflows and D3 does not change
     SWAP    D3      ; Lower word is (X%2) or random data

Если вы действительно хотите использовать DIVU, обязательно очистите длинный регистр (с clr.l d3 или на самом деле быстрее moveq #0,d3). Просто очищать нижнее слово бессмысленно, если потом перезаписать его.

Но, как сказал @PeterCordes, DIVU очень неэффективно для проверки младшего бита (я не буду указывать на другие недостатки в вашем коде). Лучше использовать btst #0,d1 (устанавливает флаг Z, если бит пуст). Альтернативы:

  • and.w число 1 со значением, которое вы хотите проверить. Также устанавливает флаг Z, если младший бит пуст
  • Сдвиг значения вправо (устанавливает флаг C, если был установлен младший бит)

Конечно, вы также можете частично развернуть цикл и использовать тот факт, что (X%2) != 0 верно для каждой другой итерации. И вы можете полностью развернуть цикл и напрямую переместить результат в свою цель (это то, что смогут сделать большинство оптимизирующих компиляторов: https://godbolt.org/z/VGecJ3).

...