countersince January 6, 2001X68000 LIBRARYEnglish
更新日: 2023 年 4 月 11 日
X68000 LIBRARY > 資料室 > 命令セットリファレンス(準備中) > D > DBRA

DBRA

DBRA

デクリメント相対分岐 (でぃーぶら)


DBRA.W Dr,<label>

68000/68010/68020/68030/68040/68060 の命令 DBF.W Dr,<label> の別名

命令コード

アドレス1514131211109876543210
+00101000111001レジスタr
+2ワードオフセット

実行時間

680006801068020680306804068060
分岐10
通過14
(2/0)
分岐10
通過14
(2/0)
🚧🚧🚧予測通り分岐1
予測通り通過1
予測なし分岐3
予測なし通過7
(2/0)

コンディションコード

フラグ入力出力
X使用しない変化しない
N
Z
V
C

解説

  1. 命令の先頭アドレスに 2 を足して相対分岐のベースアドレスとします。
  2. ワードオフセットをロングワードに符号拡張してロングワードオフセットとします。
  3. 相対分岐のベースアドレスにロングワードオフセットを足して分岐先のアドレスとします。
  4. Dr の下位ワードから 1 を引きます。上位ワードは変化しません。
  5. Dr の下位ワードが $FFFF にならなかったとき分岐先のアドレスへ分岐します。

メモ

X680x0 では空の DBRA ループが 1 ミリ秒間に何周するかが動作速度の基準のひとつになっています。その値が X68000 XVI 以降の機種(IPLROM 1.1 以上)の BIOS ワークエリアの $0CB8 に格納されており、それを X68000 では 12/1000 倍、X68030 では 6/1000 倍すると MPU の動作周波数(MHz)が求まります。

サンプルプログラム

DBRA ループ。繰り返す回数が 65536 回までのとき。

;----------------------------------------
;1から1000までの数の合計を求める
;       sum=0
;       for k=1 to 1000
;               sum=sum+k
;       next
;       print sum
;----------------------------------------
        moveq.l #0,d0           ;d0.l:sum=0→?
        moveq.l #1,d1           ;d1.l:k=1→1000
        move.w  #1000-1,d2      ;d2.w:DBRAループカウンタ。999→0
loop:                           ;-----------+DBRAループ
        add.l   d1,d0           ;sum=sum+k  |
        addq.w  #1,d1           ;k=k+1      |
        dbra.w  d2,loop         ;-----------+
        bsr     print_d0_l

DBRA ループ。繰り返す回数が 65536 回より多いとき。

;----------------------------------------
;1から1000000までの数の合計を求める
;       sum=0
;       for k=1 to 1000000
;               sum=sum+k
;       next
;       print sum
;----------------------------------------
        moveq.l #0,d0           ;d0d1.q:sum=0→?
        moveq.l #0,d1
        moveq.l #0,d2           ;d2.l:0
        moveq.l #1,d3           ;d3.l:k=1→1000000
        move.l  #1000000-1,d4   ;d4.l:DBRAループカウンタ。999999→0
        swap.w  d4
upper_loop:                     ;------------------------------+上位のDBRAループ
        swap.w  d4              ;                              |
lower_loop:                     ;-----------+下位のDBRAループ  |
        add.l   d3,d1           ;sum=sum+k  |                  |
        addx.l  d2,d0           ;           |                  |
        addq.l  #1,d3           ;k=k+1      |                  |
        dbra.w  d4,lower_loop   ;-----------+                  |
        swap.w  d4              ;                              |
        dbra.w  d4,upper_loop   ;------------------------------+
        bsr     print_d0d1_q