更新日: 2023 年 4 月 11 日
DBRA
DBRA
デクリメント相対分岐 (でぃーぶら)
DBRA.W Dr,<label>
68000/68010/68020/68030/68040/68060 の命令 DBF.W Dr,<label> の別名
命令コード
アドレス | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
+0 | 0 | 1 | 0 | 1 | 0 | 0 | 0 | 1 | 1 | 1 | 0 | 0 | 1 | レジスタr | ||
+2 | ワードオフセット |
実行時間
68000 | 68010 | 68020 | 68030 | 68040 | 68060 |
---|---|---|---|---|---|
分岐10 通過14 (2/0) | 分岐10 通過14 (2/0) | 🚧 | 🚧 | 🚧 | 予測通り分岐1 予測通り通過1 予測なし分岐3 予測なし通過7 (2/0) |
コンディションコード
フラグ | 入力 | 出力 |
---|---|---|
X | 使用しない | 変化しない |
N | ||
Z | ||
V | ||
C |
解説
- 命令の先頭アドレスに 2 を足して相対分岐のベースアドレスとします。
- ワードオフセットをロングワードに符号拡張してロングワードオフセットとします。
- 相対分岐のベースアドレスにロングワードオフセットを足して分岐先のアドレスとします。
- Dr の下位ワードから 1 を引きます。上位ワードは変化しません。
- 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