はじめに
「M68000 ファミリのビットフィールド命令がよくわからない」という声を耳にすることがあるので、今回はビットフィールド命令について解説する。
ビットフィールド命令は MC68020 で新設された命令だ。MC68020〜MC68060 で使うことができるが、残念ながら MC68000 では使うことができない。そのためビットフィールド命令は MC68000 のユーザにはほとんど馴染みがないものだが、他の人が作ったプログラムを解析しているときに知らない命令が出てくると困ってしまうので、一応どんなものか知っておいて損はないと思う。
ビットフィールド命令の動作は Motorola などのマニュアルを見てもよくわからなかったという人もいると思う。ここではなるべくわかるように説明したい。
目次
ビットフィールド
ビットフィールドとは、データレジスタまたはメモリ上の連続する 1〜32 ビットの領域である。C を使いこなしている人なら、構造体のビットフィールドメンバ 1 個分の領域を想像すればよい。一般的に、メモリにデータを格納するときはバイト境界に合わせて格納したほうが効率がよくなるものだが、限られた領域により多くのデータを詰め込みたい場合にはバイト境界に構わず配置されたビットフィールドを利用することがある。
簡単なビットフィールドの例を示そう(図の中の細い縦線はバイト境界、太い縦線はビットフィールドの境界)。
D0 レジスタの下位側に幅が 10 ビットのデータを 3 個充填する
ビット 31 2423 1615 8 7 0
│ │ │ │ │
┌─┰─────┬───┰───┬─────┰─┬───────┐
D0│ ┃ ┃ ┃ │
└─┸─────┴───┸───┴─────┸─┴───────┘
┃←───X───→┃←───Y───→┃←───Z───→┃
ビット 3029 2019 10 9 0
|
メモリ上に幅が 10 ビットのデータを 3 個充填する
ビット 7 0 7 0 7 0 7 0
アドレス │ │ │ │
│ +0 │ +1 │ +2 │ +3 │
┰───────┬─┰─────┬───┰───┬─────┰─┬
メモリ┃ ┃ ┃ ┃
┸───────┴─┸─────┴───┸───┴─────┸─┴
┃←───X───→┃←───Y───→┃←───Z───→┃
ビット 7 6 5 4 3 2 1
|
それぞれ、X、Y、Zの 3 個が幅が 10 ビットのビットフィールドであると言える。
ビットフィールド命令
ビットフィールド命令とは、その名の通り「ビットフィールドを扱う命令」である。MC68000〜MC68060 で使うことができるビット操作命令(
BCHG/
BCLR/
BSET/
BTST)が 1 ビットの領域を扱うのに対して、MC68020〜MC68060 で使うことができるビットフィールド命令は 1〜32 ビットの任意の幅の領域(ビットフィールド)を扱うことができる。
ビットフィールドを扱うということは、レジスタやメモリ上で、バイト境界に関係なく任意の位置から始まる任意の幅の領域を読み出したり書き換えたりするということだ。ビット操作命令と同様に、ビットフィールドと同じバイトに含まれているビットであってもビットフィールドの外側ならばその内容はビットフィールド命令によって使用されることも変化することもない。ビットフィールド命令は、ビット単位で指定された範囲のビットフィールドだけを操作してくれる便利な命令なのだ。
個々のビットフィールド命令については後で詳しく説明することにして、先にビットフィールド命令に指定するビットフィールド・オペランドについて解説しよう。
ビットフィールド・オペランド
ビットフィールド命令では、ソースオペランドまたはデスティネーションオペランドのどちらかでビットフィールドを指定しなければならない。そのオペランドをここではビットフィールド・オペランドと呼ぶことにしよう。アセンブラでは、ビットフィールド・オペランドを次のようなフォーマットで記述する。
<ea>{offset:width}
<ea> は他の命令のオペランドの説明でも使われる実効アドレス(effective address)の指定だ。ビットフィールド・オペランドに指定できるアドレッシングモードは、データレジスタ直接、アドレスレジスタ間接(ポストインクリメント、プレデクリメントを除く)、絶対アドレス、プログラムカウンタ間接(一部のビットフィールド命令を除く)である。
「
{」「
:」「
}」の 3 つの文字は実際にアセンブラのプログラムに記述する文字だ。ビットフィールド・オペランドにはこれらの記号がなければならない。なお、他の種類のオペランドと同様に、これらの記号の前後に余計な空白を入れてはいけない。
offset には、
<ea> で指定した実効アドレスの最上位ビットからビットフィールドの開始位置までのオフセット(ビット数)を 0〜31 の定数で指定する。イミディエイトオペランドと同様に、定数の場合は手前に「
#」を付けてもよい。
offset のところにデータレジスタを指定すると、実行時のそのデータレジスタの下位 5 ビットの内容がオフセットになる(下位 5 ビット以外のビットは無視される)。
width には、ビットフィールドの幅(ビット数)を 1〜32 の定数で指定する。イミディエイトオペランドと同様に、定数の場合は手前に「
#」を付けてもよい。
width のところにデータレジスタを指定すると、実行時のそのデータレジスタの下位 5 ビットの内容(0 は 32 と見なされる)がビットフィールドの幅になる(下位 5 ビット以外のビットは無視される)。
!!!注意!!!
ビット操作命令のビット位置の指定と異なり、ビットフィールドの開始位置を示す
offset の値は最上位ビットからのオフセットである。ビット番号ではない。例えば、ビット操作命令
BTST.L #0,D0
でテストされるビットは
D0 レジスタの最下位ビットだが、ビットフィールド・オペランド
D0{0:1}
は
D0 レジスタの最上位ビットを示している。
D0 レジスタの最下位ビットを示すビットフィールド・オペランドは
D0{31:1}
である。
実効アドレスがデータレジスタの場合
最初に挙げたビットフィールドの例をもう一度見てみよう。
D0 レジスタの下位側に幅が 10 ビットのデータを 3 個充填する
ビット 31 2423 1615 8 7 0
│ │ │ │ │
┌─┰─────┬───┰───┬─────┰─┬───────┐
D0│ ┃ ┃ ┃ │
└─┸─────┴───┸───┴─────┸─┴───────┘
┃←───X───→┃←───Y───→┃←───Z───→┃
ビット 3029 2019 10 9 0
|
これにビットフィールドのオフセットと幅を書き加えると次のようになる。
オフセット
0 7 8 1516 2324 31
ビット 31 2423 1615 8 7 0
│ │ │ │ │
┌─┰─────┬───┰───┬─────┰─┬───────┐
D0│ ┃ ┃ ┃ │
└─┸─────┴───┸───┴─────┸─┴───────┘
┃←───X───→┃←───Y───→┃←───Z───→┃
ビット 3029 2019 10 9 0
オフセット1 2 1112 2122 31
┃←─ 10ビット ─→┃←─ 10ビット ─→┃←─ 10ビット ─→┃
|
X、Y、Zを示すビットフィールド・オペランドは、次のようになる。
X … オフセット 2 から 10 ビット … D0{2:10}
Y … オフセット 12 から 10 ビット … D0{12:10}
Z … オフセット 22 から 10 ビット … D0{22:10}
ところで、言うまでもないことだが、データレジスタは 32 ビットしかない。それでは、次のビットフィールド・オペランドは何を意味しているだろうか。
D0{16:32}
オフセットが 16 で幅が 32 ビット。これではビットフィールドが
D0 レジスタの最下位からはみ出してしまう。こういうときは、
D0 レジスタを横に 2 つ並べて考えればよい。
│ D0 │ D0 │
ビット 31 1615 031 1615 0
┌───┬───┰───┬───┬───┬───┰───┬───┐
│ ┃ │ ┃ │
└───┴───┸───┴───┴───┴───┸───┴───┘
┃ D0{16:32} ┃
|
このように、ビットフィールドがデータレジスタの最下位からはみ出したら最上位に戻ってくればよいのだ。ビットフィールド・オペランド
D0{16:32} は、
D0 レジスタの上位ワードと下位ワードを入れ換えたものということになる。
実効アドレスがメモリの場合
ここでも最初に挙げた例を見てみよう。
メモリ上に幅が 10 ビットのデータを 3 個充填する
ビット 7 0 7 0 7 0 7 0
アドレス │ │ │ │
│ +0 │ +1 │ +2 │ +3 │
┰───────┬─┰─────┬───┰───┬─────┰─┬
メモリ┃ ┃ ┃ ┃
┸───────┴─┸─────┴───┸───┴─────┸─┴
┃←───X───→┃←───Y───→┃←───Z───→┃
ビット 7 6 5 4 3 2 1
|
ここでは、+0 で示したアドレスが
A0 で指されている場合を考えてみる。オフセットとビットフィールドの幅も書き加えよう。
ビット 7 0 7 0 7 0 7 0
│ (A0) │ 1(A0) │ 2(A0) │ 3(A0) │
┰───────┬─┰─────┬───┰───┬─────┰─┬
メモリ┃ ┃ ┃ ┃
┸───────┴─┸─────┴───┸───┴─────┸─┴
┃←───X───→┃←───Y───→┃←───Z───→┃
ビット 7 6 5 4 3 2 1
オフセット
0 1 2 3 4 5 6
┃←─ 10ビット ─→┃←─ 10ビット ─→┃←─ 10ビット ─→┃
|
X、Y、Zを示すビットフィールド・オペランドは、次のようになる。
X … (A0) のオフセット 0 から 10 ビット … (A0){0:10}
Y … 1(A0) のオフセット 2 から 10 ビット … 1(A0){2:10}
Z … 2(A0) のオフセット 4 から 10 ビット … 2(A0){4:10}
実は、これらのビットフィールド・オペランドは、次のように書くこともできる。
X … (A0) のオフセット 0 から 10 ビット … (A0){0:10}
Y … (A0) のオフセット 10 から 10 ビット … (A0){10:10}
Z … (A0) のオフセット 20 から 10 ビット … (A0){20:10}
ビット操作命令ではメモリに関するビット番号の指定は 0〜7 の範囲でしか指定できないので、MC68000 のアセンブラに慣れていると、ビットフィールド・オペランドのオフセット 10 や 20 という表記には少々違和感を感じるものだ。実効アドレスで指定されたアドレスの 1 バイトは操作の対象にすらなっていないのだ。
このように、ビットフィールド・オペランドの実効アドレスがメモリの場合は、メモリ上の任意のアドレスの任意のビットからビット番号降順、アドレス昇順で最大 32 ビットまでの領域(ビットフィールド)が操作の対象になる。データレジスタの場合と違い、ある領域の最下位からはみ出して同じ領域の最上位に戻ってくるということはない。
ビットフィールド命令の種類
ビットフィールド命令には次の 8 種類がある。
なお、ビット操作命令と違ってビットフィールド命令にはオペレーションサイズがない。ビットフィールド命令にオペレーションサイズを書くとエラーになるので注意。
続いて、個々のビットフィールド命令について解説する。
BFCHG(Test Bit Field and Change)
BFCHG は、
BCHG のビットフィールド版。ビットフィールド全体をビットごとに反転する。
・文法
BFCHG <ea>{offset:width}
・機能
ビットフィールドの内容をテストしてフラグを設定する。
ビットフィールドの中のすべてのビットを反転(0→1、1→0)する。
・アドレッシングモード
BFCHG 命令で使用できるアドレッシングモードは以下の通り。
データレジスタ直接
アドレスレジスタ間接(ポストインクリメント、プレデクリメントを除く)
BFCHG (An){offset:width}
BFCHG (d16,An){offset:width}
BFCHG (d8,An,Xi){offset:width}
BFCHG (bd,An,Xi){offset:width}
BFCHG ([bd,An,Xi]){offset:width}
BFCHG ([bd,An,Xi],od.W){offset:width}
BFCHG ([bd,An,Xi],od.L){offset:width}
BFCHG ([bd,An],Xi){offset:width}
BFCHG ([bd,An],Xi,od.W){offset:width}
BFCHG ([bd,An],Xi,od.L){offset:width}
BFCHG (bd,An){offset:width}
BFCHG ([bd,An]){offset:width}
BFCHG ([bd,An],od.W){offset:width}
BFCHG ([bd,An],od.L){offset:width}
絶対アドレス
BFCHG (xxx).W{offset:width}
BFCHG (xxx).L{offset:width}
・フラグの変化
操作前のビットフィールドの内容に応じてフラグが変化する。詳細は後述。
・例
BFCHG D0{0:16}
D0 の上位ワードがビット反転される
BFCLR(Test Bit Field and Clear)
BFCLR は、
BCLR のビットフィールド版。ビットフィールド全体をクリアする。
・文法
BFCLR <ea>{offset:width}
・機能
ビットフィールドの内容をテストしてフラグを設定する。
ビットフィールドの中のすべてのビットをクリア(0→0、1→0)する。
・アドレッシングモード
BFCLR 命令で使用できるアドレッシングモードは以下の通り。
データレジスタ直接
アドレスレジスタ間接(ポストインクリメント、プレデクリメントを除く)
BFCLR (An){offset:width}
BFCLR (d16,An){offset:width}
BFCLR (d8,An,Xi){offset:width}
BFCLR (bd,An,Xi){offset:width}
BFCLR ([bd,An,Xi]){offset:width}
BFCLR ([bd,An,Xi],od.W){offset:width}
BFCLR ([bd,An,Xi],od.L){offset:width}
BFCLR ([bd,An],Xi){offset:width}
BFCLR ([bd,An],Xi,od.W){offset:width}
BFCLR ([bd,An],Xi,od.L){offset:width}
BFCLR (bd,An){offset:width}
BFCLR ([bd,An]){offset:width}
BFCLR ([bd,An],od.W){offset:width}
BFCLR ([bd,An],od.L){offset:width}
絶対アドレス
BFCLR (xxx).W{offset:width}
BFCLR (xxx).L{offset:width}
・フラグの変化
操作前のビットフィールドの内容に応じてフラグが変化する。詳細は後述。
・例
BFCLR D0{0:16}
D0 の上位ワードがクリアされる
BFEXTS(Extract Bit Field Signed)
BFEXTS は、ビットフィールドの内容を符号つき整数と見なして取り出す。
・文法
BFEXTS <ea>{offset:width},Dn
・機能
ビットフィールドの内容をテストしてフラグを設定する。
ビットフィールドの内容を符号つき整数と見なして取り出し、32 ビットに符号拡張して
Dn に格納する。
・アドレッシングモード
BFEXTS 命令で使用できるアドレッシングモードは以下の通り。
データレジスタ直接
アドレスレジスタ間接(ポストインクリメント、プレデクリメントを除く)
BFEXTS (An){offset:width}
BFEXTS (d16,An){offset:width}
BFEXTS (d8,An,Xi){offset:width}
BFEXTS (bd,An,Xi){offset:width}
BFEXTS ([bd,An,Xi]){offset:width}
BFEXTS ([bd,An,Xi],od.W){offset:width}
BFEXTS ([bd,An,Xi],od.L){offset:width}
BFEXTS ([bd,An],Xi){offset:width}
BFEXTS ([bd,An],Xi,od.W){offset:width}
BFEXTS ([bd,An],Xi,od.L){offset:width}
BFEXTS (bd,An){offset:width}
BFEXTS ([bd,An]){offset:width}
BFEXTS ([bd,An],od.W){offset:width}
BFEXTS ([bd,An],od.L){offset:width}
絶対アドレス
BFEXTS (xxx).W{offset:width}
BFEXTS (xxx).L{offset:width}
プログラムカウンタ間接
BFEXTS (d16,PC){offset:width}
BFEXTS (d8,PC,Xi){offset:width}
BFEXTS (bd,PC,Xi){offset:width}
BFEXTS ([bd,PC,Xi]){offset:width}
BFEXTS ([bd,PC,Xi],od.W){offset:width}
BFEXTS ([bd,PC,Xi],od.L){offset:width}
BFEXTS ([bd,PC],Xi){offset:width}
BFEXTS ([bd,PC],Xi,od.W){offset:width}
BFEXTS ([bd,PC],Xi,od.L){offset:width}
BFEXTS (bd,PC){offset:width}
BFEXTS ([bd,PC]){offset:width}
BFEXTS ([bd,PC],od.W){offset:width}
BFEXTS ([bd,PC],od.L){offset:width}
・フラグの変化
操作前のビットフィールドの内容に応じてフラグが変化する。詳細は後述。
・例
BFEXTS D0{16:8},D0
D0 の下位ワードの上位バイトを 32 ビットに符号拡張して D0 に格納し直す
BFEXTU(Extract Bit Field Unsigned)
BFEXTU は、ビットフィールドの内容を符号なし整数と見なして取り出す。
・文法
BFEXTU <ea>{offset:width},Dn
・機能
ビットフィールドの内容をテストしてフラグを設定する。
ビットフィールドの内容を符号なし整数と見なして取り出し、32 ビットにゼロ拡張して
Dn に格納する。
・アドレッシングモード
BFEXTU 命令で使用できるアドレッシングモードは以下の通り。
データレジスタ直接
アドレスレジスタ間接(ポストインクリメント、プレデクリメントを除く)
BFEXTU (An){offset:width}
BFEXTU (d16,An){offset:width}
BFEXTU (d8,An,Xi){offset:width}
BFEXTU (bd,An,Xi){offset:width}
BFEXTU ([bd,An,Xi]){offset:width}
BFEXTU ([bd,An,Xi],od.W){offset:width}
BFEXTU ([bd,An,Xi],od.L){offset:width}
BFEXTU ([bd,An],Xi){offset:width}
BFEXTU ([bd,An],Xi,od.W){offset:width}
BFEXTU ([bd,An],Xi,od.L){offset:width}
BFEXTU (bd,An){offset:width}
BFEXTU ([bd,An]){offset:width}
BFEXTU ([bd,An],od.W){offset:width}
BFEXTU ([bd,An],od.L){offset:width}
絶対アドレス
BFEXTU (xxx).W{offset:width}
BFEXTU (xxx).L{offset:width}
プログラムカウンタ間接
BFEXTU (d16,PC){offset:width}
BFEXTU (d8,PC,Xi){offset:width}
BFEXTU (bd,PC,Xi){offset:width}
BFEXTU ([bd,PC,Xi]){offset:width}
BFEXTU ([bd,PC,Xi],od.W){offset:width}
BFEXTU ([bd,PC,Xi],od.L){offset:width}
BFEXTU ([bd,PC],Xi){offset:width}
BFEXTU ([bd,PC],Xi,od.W){offset:width}
BFEXTU ([bd,PC],Xi,od.L){offset:width}
BFEXTU (bd,PC){offset:width}
BFEXTU ([bd,PC]){offset:width}
BFEXTU ([bd,PC],od.W){offset:width}
BFEXTU ([bd,PC],od.L){offset:width}
・フラグの変化
操作前のビットフィールドの内容に応じてフラグが変化する。詳細は後述。
・例
BFEXTU D0{16:8},D0
D0 の下位ワードの上位バイトを 32 ビットにゼロ拡張して D0 に格納し直す
BFEXTU D0{16:32},D0
D0 の上位ワードと下位ワードを入れ換える
BFFFO(Find First One in Bit Field)
BFFFO は、ビットフィールドの中で最初の 1 のビットを探す。
・文法
BFFFO <ea>{offset:width},Dn
・機能
ビットフィールドの内容をテストしてフラグを設定する。
ビットフィールドの中で最も上位にある 1 のビットの位置のオフセット(
offset と同様に実効アドレスの最上位ビットからのオフセット)を 32 ビットにゼロ拡張して
Dn に格納する。ビットフィールドの中の最上位のビットが立っているときは、
Dn には
offset の値が入る。ビットフィールドの中のすべてのビットが 0 のときは、
Dn には
offset+
width の値が入る。
・アドレッシングモード
BFFFO 命令で使用できるアドレッシングモードは以下の通り。
データレジスタ直接
アドレスレジスタ間接(ポストインクリメント、プレデクリメントを除く)
BFFFO (An){offset:width}
BFFFO (d16,An){offset:width}
BFFFO (d8,An,Xi){offset:width}
BFFFO (bd,An,Xi){offset:width}
BFFFO ([bd,An,Xi]){offset:width}
BFFFO ([bd,An,Xi],od.W){offset:width}
BFFFO ([bd,An,Xi],od.L){offset:width}
BFFFO ([bd,An],Xi){offset:width}
BFFFO ([bd,An],Xi,od.W){offset:width}
BFFFO ([bd,An],Xi,od.L){offset:width}
BFFFO (bd,An){offset:width}
BFFFO ([bd,An]){offset:width}
BFFFO ([bd,An],od.W){offset:width}
BFFFO ([bd,An],od.L){offset:width}
絶対アドレス
BFFFO (xxx).W{offset:width}
BFFFO (xxx).L{offset:width}
プログラムカウンタ間接
BFFFO (d16,PC){offset:width}
BFFFO (d8,PC,Xi){offset:width}
BFFFO (bd,PC,Xi){offset:width}
BFFFO ([bd,PC,Xi]){offset:width}
BFFFO ([bd,PC,Xi],od.W){offset:width}
BFFFO ([bd,PC,Xi],od.L){offset:width}
BFFFO ([bd,PC],Xi){offset:width}
BFFFO ([bd,PC],Xi,od.W){offset:width}
BFFFO ([bd,PC],Xi,od.L){offset:width}
BFFFO (bd,PC){offset:width}
BFFFO ([bd,PC]){offset:width}
BFFFO ([bd,PC],od.W){offset:width}
BFFFO ([bd,PC],od.L){offset:width}
・フラグの変化
操作前のビットフィールドの内容に応じてフラグが変化する。詳細は後述。
・例
MOVE.L #$00084210,D0
BFFFO D0{4:20},D0
ビットフィールドの内容は $00842 であり、最上位の 1 のオフセットは 12 なので、D0=$0000000C になる。
BFFFO D0{0:32},D1
LSL.L D1,D0
D0 の内容を左詰めにする。
BFINS(Insert Bit Field)
BFINS は、データをビットフィールドに書き込む。
・文法
BFINS Dn,<ea>{offset:width}
・機能
Dn の下位から
width で示されたビット数だけ取り出してビットフィールドに上書きする。
ビットフィールドの内容をテストしてフラグを設定する。
・アドレッシングモード
BFINS 命令で使用できるアドレッシングモードは以下の通り。
データレジスタ直接
アドレスレジスタ間接(ポストインクリメント、プレデクリメントを除く)
BFINS (An){offset:width}
BFINS (d16,An){offset:width}
BFINS (d8,An,Xi){offset:width}
BFINS (bd,An,Xi){offset:width}
BFINS ([bd,An,Xi]){offset:width}
BFINS ([bd,An,Xi],od.W){offset:width}
BFINS ([bd,An,Xi],od.L){offset:width}
BFINS ([bd,An],Xi){offset:width}
BFINS ([bd,An],Xi,od.W){offset:width}
BFINS ([bd,An],Xi,od.L){offset:width}
BFINS (bd,An){offset:width}
BFINS ([bd,An]){offset:width}
BFINS ([bd,An],od.W){offset:width}
BFINS ([bd,An],od.L){offset:width}
絶対アドレス
BFINS (xxx).W{offset:width}
BFINS (xxx).L{offset:width}
・フラグの変化
操作後のビットフィールドの内容に応じてフラグが変化する。詳細は後述。
・例
MOVE.L #$12345678,D0
BFINS D0,(A0){4:16}
(A0) から 3 バイトが $?5,$67,$8? になる(? のところは変化しない)
BFSET(Test Bit Field and Set)
BFSET は、
BSET のビットフィールド版。ビットフィールド全体をセットする。
・文法
BFSET <ea>{offset:width}
・機能
ビットフィールドの内容をテストしてフラグを設定する。
ビットフィールドの中のすべてのビットをセット(0→1、1→1)する。
・アドレッシングモード
BFSET 命令で使用できるアドレッシングモードは以下の通り。
データレジスタ直接
アドレスレジスタ間接(ポストインクリメント、プレデクリメントを除く)
BFSET (An){offset:width}
BFSET (d16,An){offset:width}
BFSET (d8,An,Xi){offset:width}
BFSET (bd,An,Xi){offset:width}
BFSET ([bd,An,Xi]){offset:width}
BFSET ([bd,An,Xi],od.W){offset:width}
BFSET ([bd,An,Xi],od.L){offset:width}
BFSET ([bd,An],Xi){offset:width}
BFSET ([bd,An],Xi,od.W){offset:width}
BFSET ([bd,An],Xi,od.L){offset:width}
BFSET (bd,An){offset:width}
BFSET ([bd,An]){offset:width}
BFSET ([bd,An],od.W){offset:width}
BFSET ([bd,An],od.L){offset:width}
絶対アドレス
BFSET (xxx).W{offset:width}
BFSET (xxx).L{offset:width}
・フラグの変化
操作前のビットフィールドの内容に応じてフラグが変化する。詳細は後述。
・例
MOVEQ.L #4,D0
BFSET (A0){D0:16}
(A0) から 3 バイトが $?F,$FF,$F? になる(? のところは変化しない)
BFTST(Test Bit Field)
BFTST は、
BTST のビットフィールド版。ビットフィールド全体をテストする。
・文法
BFTST <ea>{offset:width}
・機能
ビットフィールドの内容をテストしてフラグを設定する。
・アドレッシングモード
BFTST 命令で使用できるアドレッシングモードは以下の通り。
データレジスタ直接
アドレスレジスタ間接(ポストインクリメント、プレデクリメントを除く)
BFTST (An){offset:width}
BFTST (d16,An){offset:width}
BFTST (d8,An,Xi){offset:width}
BFTST (bd,An,Xi){offset:width}
BFTST ([bd,An,Xi]){offset:width}
BFTST ([bd,An,Xi],od.W){offset:width}
BFTST ([bd,An,Xi],od.L){offset:width}
BFTST ([bd,An],Xi){offset:width}
BFTST ([bd,An],Xi,od.W){offset:width}
BFTST ([bd,An],Xi,od.L){offset:width}
BFTST (bd,An){offset:width}
BFTST ([bd,An]){offset:width}
BFTST ([bd,An],od.W){offset:width}
BFTST ([bd,An],od.L){offset:width}
絶対アドレス
BFTST (xxx).W{offset:width}
BFTST (xxx).L{offset:width}
プログラムカウンタ間接
BFTST (d16,PC){offset:width}
BFTST (d8,PC,Xi){offset:width}
BFTST (bd,PC,Xi){offset:width}
BFTST ([bd,PC,Xi]){offset:width}
BFTST ([bd,PC,Xi],od.W){offset:width}
BFTST ([bd,PC,Xi],od.L){offset:width}
BFTST ([bd,PC],Xi){offset:width}
BFTST ([bd,PC],Xi,od.W){offset:width}
BFTST ([bd,PC],Xi,od.L){offset:width}
BFTST (bd,PC){offset:width}
BFTST ([bd,PC]){offset:width}
BFTST ([bd,PC],od.W){offset:width}
BFTST ([bd,PC],od.L){offset:width}
・フラグの変化
ビットフィールドの内容に応じてフラグが変化する。詳細は後述。
・例
MOVE.L #$12345678,D0
BFTST D0{28:16}
#$8123 をテストする
ビットフィールド命令のフラグ変化
ビット操作命令と同様に、ビットフィールド命令はビットフィールドに対する操作を行う前(
BFINS は操作を行った後)にビットフィールドをテストし、その結果をフラグ(
CCR;コンディション・コード・レジスタの下位 5 ビット)に反映する。ビット操作命令は操作の対象が 1 ビットだけだったので
Z フラグだけが変化することになっていたが、ビットフィールド命令では、
N フラグと
Z フラグがテストの結果を反映し、
V フラグと
C フラグは常にクリアされる。
X フラグは変化しない。
・ビットフィールド命令のフラグ変化のまとめ
| X | 変化しない |
|
| N | 操作前(BFINS は操作後)のビットフィールドの最上位ビットの内容がコピーされる |
|
| Z | 操作前(BFINS は操作後)のビットフィールドの全てのビットが 0 ならばセット、それ以外はクリア |
|
| V | 常にクリア |
|
| C | 常にクリア |