これは月刊電脳倶楽部 138 号 (1999 年 11 月号) の読み物横町のコーナーに収録した『X680x0 アセンブラ講座 #$11《ビットフィールド命令》』を再編集したものです。


目次

  1. はじめに
  2. ビットフィールド
  3. ビットフィールド命令
  4. ビットフィールド・オペランド
  5. 実効アドレスがデータレジスタの場合
  6. 実効アドレスがメモリの場合
  7. ビットフィールド命令の種類
  8. BFCHG(Test Bit Field and Change)
    1. 文法
    2. 機能
    3. アドレッシングモード
    4. フラグの変化
  9. BFCLR(Test Bit Field and Clear)
    1. 文法
    2. 機能
    3. アドレッシングモード
    4. フラグの変化
  10. BFEXTS(Extract Bit Field Signed)
    1. 文法
    2. 機能
    3. アドレッシングモード
    4. フラグの変化
  11. BFEXTU(Extract Bit Field Unsigned)
    1. 文法
    2. 機能
    3. アドレッシングモード
    4. フラグの変化
  12. BFFFO(Find First One in Bit Field)
    1. 文法
    2. 機能
    3. アドレッシングモード
    4. フラグの変化
  13. BFINS(Insert Bit Field)
    1. 文法
    2. 機能
    3. アドレッシングモード
    4. フラグの変化
  14. BFSET(Test Bit Field and Set)
    1. 文法
    2. 機能
    3. アドレッシングモード
    4. フラグの変化
  15. BFTST(Test Bit Field)
    1. 文法
    2. 機能
    3. アドレッシングモード
    4. フラグの変化
  16. ビットフィールド命令のフラグ変化
    1. ビットフィールド命令のフラグ変化のまとめ

1. はじめに

「M68000 ファミリのビットフィールド命令がよくわからない」という声を耳にすることがあるので、今回はビットフィールド命令について解説する。

ビットフィールド命令は MC68020 で新設された命令だ。MC68020~MC68060 で使うことができるが、残念ながら MC68000 では使うことができない。そのためビットフィールド命令は MC68000 のユーザにはほとんど馴染みがないものだが、他の人が作ったプログラムを解析しているときに知らない命令が出てくると困ってしまうので、一応どんなものか知っておいて損はないと思う。

ビットフィールド命令の動作は Motorola などのマニュアルを見てもよくわからなかったという人もいると思う。ここではなるべくわかるように説明したい。

2. ビットフィールド

ビットフィールドとは、データレジスタまたはメモリ上の連続する 1~32 ビットの領域である。C を使いこなしている人なら、構造体のビットフィールドメンバ 1 個分の領域を想像すればよい。一般的に、メモリにデータを格納するときはバイト境界に合わせて格納したほうが効率がよくなるものだが、限られた領域により多くのデータを詰め込みたい場合にはバイト境界に構わず配置されたビットフィールドを利用することがある。

簡単なビットフィールドの例を示そう(図の中の点線はバイト境界、破線はビットフィールドの境界)。

D0 レジスタの下位側に幅が 10 ビットのデータを 3 個充填する
D0XYZビット3124231615870ビット302920191090
メモリ上に幅が 10 ビットのデータを 3 個充填する
メモリXYZアドレス+0+1+2+3ビット70707070ビット7654321

それぞれ、X、Y、Zの 3 個が幅が 10 ビットのビットフィールドであると言える。

3. ビットフィールド命令

ビットフィールド命令とは、その名の通り「ビットフィールドを扱う命令」である。MC68000~MC68060 で使うことができるビット操作命令(BCHG/BCLR/BSET/BTST)が 1 ビットの領域を扱うのに対して、MC68020~MC68060 で使うことができるビットフィールド命令は 1~32 ビットの任意の幅の領域(ビットフィールド)を扱うことができる。

ビットフィールドを扱うということは、レジスタやメモリ上で、バイト境界に関係なく任意の位置から始まる任意の幅の領域を読み出したり書き換えたりするということだ。ビット操作命令と同様に、ビットフィールドと同じバイトに含まれているビットであってもビットフィールドの外側ならばその内容はビットフィールド命令によって使用されることも変化することもない。ビットフィールド命令は、ビット単位で指定された範囲のビットフィールドだけを操作してくれる便利な命令なのだ。

個々のビットフィールド命令については後で詳しく説明することにして、先にビットフィールド命令に指定するビットフィールド・オペランドについて解説しよう。

4. ビットフィールド・オペランド

ビットフィールド命令では、ソースオペランドまたはデスティネーションオペランドのどちらかでビットフィールドを指定しなければならない。そのオペランドをここではビットフィールド・オペランドと呼ぶことにしよう。アセンブラでは、ビットフィールド・オペランドを次のようなフォーマットで記述する。

<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}

である。

5. 実効アドレスがデータレジスタの場合

最初に挙げたビットフィールドの例をもう一度見てみよう。

D0 レジスタの下位側に幅が 10 ビットのデータを 3 個充填する
D0XYZビット3124231615870ビット302920191090

これにビットフィールドのオフセットと幅を書き加えると次のようになる。

D0XYZオフセット0781516232431ビット3124231615870ビット302920191090オフセット12111221223110 ビット10 ビット10 ビット

X、Y、Zを示すビットフィールド・オペランドは、次のようになる。

ビットフィールドオフセットビットフィールド・オペランド
2 から10 ビットD0{2:10}
12 から10 ビットD0{12:10}
22 から10 ビットD0{22:10}

ところで、言うまでもないことだが、データレジスタは 32 ビットしかない。それでは、次のビットフィールド・オペランドは何を意味しているだろうか。

D0{16:32}

オフセットが 16 で幅が 32 ビット。これではビットフィールドが D0 レジスタの最下位からはみ出してしまう。こういうときは、D0 レジスタを横に 2 つ並べて考えればよい。

D0D0Wビット31242316158703124231615870ビットオフセット01516310151631オフセット

このように、ビットフィールドがデータレジスタの最下位からはみ出したら最上位に戻ってくればよいのだ。ビットフィールド・オペランド D0{16:32} は、D0 レジスタの上位ワードと下位ワードを入れ換えたものということになる。

6. 実効アドレスがメモリの場合

ここでも最初に挙げた例を見てみよう。

メモリ上に幅が 10 ビットのデータを 3 個充填する
メモリXYZアドレス+0+1+2+3ビット70707070ビット7654321

ここでは、+0 で示したアドレスが A0 で指されている場合を考えてみる。オフセットとビットフィールドの幅も書き加えよう。

メモリXYZアドレス(A0)1(A0)2(A0)3(A0)ビット70707070ビット7654321オフセット012345610 ビット10 ビット10 ビット

X、Y、Zを示すビットフィールド・オペランドは、次のようになる。

ビットフィールドアドレスオフセットビットフィールド・オペランド
(A0)0 から10 ビット(A0){0:10}
1(A0)2 から10 ビット1(A0){2:10}
2(A0)4 から10 ビット2(A0){4:10}

実は、これらのビットフィールド・オペランドは、次のように書くこともできる。

ビットフィールドアドレスオフセットビットフィールド・オペランド
(A0)0 から10 ビット(A0){0:10}
(A0)10 から10 ビット(A0){10:10}
(A0)20 から10 ビット(A0){20:10}

ビット操作命令ではメモリに関するビット番号の指定は 0~7 の範囲でしか指定できないので、MC68000 のアセンブラに慣れていると、ビットフィールド・オペランドのオフセット 10 や 20 という表記には少々違和感を感じるものだ。実効アドレスで指定されたアドレスの 1 バイトは操作の対象にすらなっていないのだ。

このように、ビットフィールド・オペランドの実効アドレスがメモリの場合は、メモリ上の任意のアドレスの任意のビットからビット番号降順、アドレス昇順で最大 32 ビットまでの領域(ビットフィールド)が操作の対象になる。データレジスタの場合と違い、ある領域の最下位からはみ出して同じ領域の最上位に戻ってくるということはない。

7. ビットフィールド命令の種類

ビットフィールド命令には次の 8 種類がある。

  1. BFCHG <ea>{offset:width}
  2. BFCLR <ea>{offset:width}
  3. BFEXTS <ea>{offset:width},Dn
  4. BFEXTU <ea>{offset:width},Dn
  5. BFFFO <ea>{offset:width},Dn
  6. BFINS Dn,<ea>{offset:width}
  7. BFSET <ea>{offset:width}
  8. BFTST <ea>{offset:width}

なお、ビット操作命令と違ってビットフィールド命令にはオペレーションサイズがない。ビットフィールド命令にオペレーションサイズを書くとエラーになるので注意。

続いて、個々のビットフィールド命令について解説する。

8. BFCHG(Test Bit Field and Change)

BFCHG は、BCHG のビットフィールド版。ビットフィールド全体をビットごとに反転する。

8.1. 文法

BFCHG   <ea>{offset:width}

8.2. 機能

  1. ビットフィールドの内容をテストしてフラグを設定する。
  2. ビットフィールドの中のすべてのビットを反転(0→1、1→0)する。

8.3. アドレッシングモード

BFCHG 命令で使用できるアドレッシングモードは以下の通り。

データレジスタ直接

BFCHG   Dn{offset:width}

アドレスレジスタ間接(ポストインクリメント、プレデクリメントを除く)

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}

8.4. フラグの変化

操作前のビットフィールドの内容に応じてフラグが変化する。詳細は後述。

8.5. 例

BFCHG   D0{0:16}

D0 の上位ワードがビット反転される

9. BFCLR(Test Bit Field and Clear)

BFCLR は、BCLR のビットフィールド版。ビットフィールド全体をクリアする。

9.1. 文法

BFCLR   <ea>{offset:width}

9.2. 機能

  1. ビットフィールドの内容をテストしてフラグを設定する。
  2. ビットフィールドの中のすべてのビットをクリア(0→0、1→0)する。

9.3. アドレッシングモード

BFCLR 命令で使用できるアドレッシングモードは以下の通り。

データレジスタ直接

BFCLR   Dn{offset:width}

アドレスレジスタ間接(ポストインクリメント、プレデクリメントを除く)

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}

9.4. フラグの変化

操作前のビットフィールドの内容に応じてフラグが変化する。詳細は後述。

9.5. 例

BFCLR   D0{0:16}

D0 の上位ワードがクリアされる

10. BFEXTS(Extract Bit Field Signed)

BFEXTS は、ビットフィールドの内容を符号つき整数と見なして取り出す。

10.1. 文法

BFEXTS  <ea>{offset:width},Dn

10.2. 機能

  1. ビットフィールドの内容をテストしてフラグを設定する。
  2. ビットフィールドの内容を符号つき整数と見なして取り出し、32 ビットに符号拡張して Dn に格納する。

10.3. アドレッシングモード

BFEXTS 命令で使用できるアドレッシングモードは以下の通り。

データレジスタ直接

BFEXTS  Dn{offset:width}

アドレスレジスタ間接(ポストインクリメント、プレデクリメントを除く)

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}

10.4. フラグの変化

操作前のビットフィールドの内容に応じてフラグが変化する。詳細は後述。

10.5. 例

BFEXTS  D0{16:8},D0

D0 の下位ワードの上位バイトを 32 ビットに符号拡張して D0 に格納し直す

11. BFEXTU(Extract Bit Field Unsigned)

BFEXTU は、ビットフィールドの内容を符号なし整数と見なして取り出す。

11.1. 文法

BFEXTU  <ea>{offset:width},Dn

11.2. 機能

  1. ビットフィールドの内容をテストしてフラグを設定する。
  2. ビットフィールドの内容を符号なし整数と見なして取り出し、32 ビットにゼロ拡張して Dn に格納する。

11.3. アドレッシングモード

BFEXTU 命令で使用できるアドレッシングモードは以下の通り。

データレジスタ直接

BFEXTU  Dn{offset:width}

アドレスレジスタ間接(ポストインクリメント、プレデクリメントを除く)

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}

11.4. フラグの変化

操作前のビットフィールドの内容に応じてフラグが変化する。詳細は後述。

11.5. 例

BFEXTU  D0{16:8},D0

D0 の下位ワードの上位バイトを 32 ビットにゼロ拡張して D0 に格納し直す

BFEXTU  D0{16:32},D0

D0 の上位ワードと下位ワードを入れ換える

12. BFFFO(Find First One in Bit Field)

BFFFO は、ビットフィールドの中で最初の 1 のビットを探す。

12.1. 文法

BFFFO   <ea>{offset:width},Dn

12.2. 機能

  1. ビットフィールドの内容をテストしてフラグを設定する。
  2. ビットフィールドの中で最も上位にある 1 のビットの位置のオフセット(offset と同様に実効アドレスの最上位ビットからのオフセット)を 32 ビットにゼロ拡張して Dn に格納する。ビットフィールドの中の最上位のビットが立っているときは、Dn には offset の値が入る。ビットフィールドの中のすべてのビットが 0 のときは、Dn には offset+width の値が入る。

12.3. アドレッシングモード

BFFFO 命令で使用できるアドレッシングモードは以下の通り。

データレジスタ直接

BFFFO   Dn{offset:width}

アドレスレジスタ間接(ポストインクリメント、プレデクリメントを除く)

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}

12.4. フラグの変化

操作前のビットフィールドの内容に応じてフラグが変化する。詳細は後述。

12.5. 例

MOVE.L  #$00084210,D0
BFFFO   D0{4:20},D0

ビットフィールドの内容は $00842 であり、最上位の 1 のオフセットは 12 なので、D0=$0000000C になる。

BFFFO   D0{0:32},D1
LSL.L   D1,D0

D0 の内容を左詰めにする。

13. BFINS(Insert Bit Field)

BFINS は、データをビットフィールドに書き込む。

13.1. 文法

BFINS   Dn,<ea>{offset:width}

13.2. 機能

  1. Dn の下位から width で示されたビット数だけ取り出してビットフィールドに上書きする。
  2. ビットフィールドの内容をテストしてフラグを設定する。

!!!注意!!!

他のビットフィールド命令は操作前のビットフィールドの内容をテストするが、BFINS は操作後のビットフィールドの内容をテストする。

13.3. アドレッシングモード

BFINS 命令で使用できるアドレッシングモードは以下の通り。

データレジスタ直接

BFINS   Dn,Dn{offset:width}

アドレスレジスタ間接(ポストインクリメント、プレデクリメントを除く)

BFINS   Dn,(An){offset:width}
BFINS   Dn,(d16,An){offset:width}
BFINS   Dn,(d8,An,Xi){offset:width}
BFINS   Dn,(bd,An,Xi){offset:width}
BFINS   Dn,([bd,An,Xi]){offset:width}
BFINS   Dn,([bd,An,Xi],od.W){offset:width}
BFINS   Dn,([bd,An,Xi],od.L){offset:width}
BFINS   Dn,([bd,An],Xi){offset:width}
BFINS   Dn,([bd,An],Xi,od.W){offset:width}
BFINS   Dn,([bd,An],Xi,od.L){offset:width}
BFINS   Dn,(bd,An){offset:width}
BFINS   Dn,([bd,An]){offset:width}
BFINS   Dn,([bd,An],od.W){offset:width}
BFINS   Dn,([bd,An],od.L){offset:width}

絶対アドレス

BFINS   Dn,(xxx).W{offset:width}
BFINS   Dn,(xxx).L{offset:width}

13.4. フラグの変化

操作後のビットフィールドの内容に応じてフラグが変化する。詳細は後述。

13.5. 例

MOVE.L  #$12345678,D0
BFINS   D0,(A0){4:16}

(A0) から 3 バイトが $?5,$67,$8? になる(? のところは変化しない)

14. BFSET(Test Bit Field and Set)

BFSET は、BSET のビットフィールド版。ビットフィールド全体をセットする。

14.1. 文法

BFSET   <ea>{offset:width}

14.2. 機能

  1. ビットフィールドの内容をテストしてフラグを設定する。
  2. ビットフィールドの中のすべてのビットをセット(0→1、1→1)する。

14.3. アドレッシングモード

BFSET 命令で使用できるアドレッシングモードは以下の通り。

データレジスタ直接

BFSET   Dn{offset:width}

アドレスレジスタ間接(ポストインクリメント、プレデクリメントを除く)

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}

14.4. フラグの変化

操作前のビットフィールドの内容に応じてフラグが変化する。詳細は後述。

14.5. 例

MOVEQ.L #4,D0
BFSET   (A0){D0:16}

(A0) から 3 バイトが $?F,$FF,$F? になる(? のところは変化しない)

15. BFTST(Test Bit Field)

BFTST は、BTST のビットフィールド版。ビットフィールド全体をテストする。

15.1. 文法

BFTST   <ea>{offset:width}

15.2. 機能

  1. ビットフィールドの内容をテストしてフラグを設定する。

15.3. アドレッシングモード

BFTST 命令で使用できるアドレッシングモードは以下の通り。

データレジスタ直接

BFTST   Dn{offset:width}

アドレスレジスタ間接(ポストインクリメント、プレデクリメントを除く)

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}

15.4. フラグの変化

ビットフィールドの内容に応じてフラグが変化する。詳細は後述。

15.5. 例

MOVE.L  #$12345678,D0
BFTST   D0{28:16}

#$8123 をテストする

16. ビットフィールド命令のフラグ変化

ビット操作命令と同様に、ビットフィールド命令はビットフィールドに対する操作を行う前(BFINS は操作を行った後)にビットフィールドをテストし、その結果をフラグ(CCR; コンディション・コード・レジスタの下位 5 ビット)に反映する。ビット操作命令は操作の対象が 1 ビットだけだったので Z フラグだけが変化することになっていたが、ビットフィールド命令では、N フラグと Z フラグがテストの結果を反映し、V フラグと C フラグは常にクリアされる。X フラグは変化しない。

16.1. ビットフィールド命令のフラグ変化のまとめ

フラグビットフィールド命令のフラグ変化
X変化しない
N操作前(BFINS は操作後)のビットフィールドの最上位ビットの内容がコピーされる
Z操作前(BFINS は操作後)のビットフィールドの全てのビットが 0 ならばセット、それ以外はクリア
V常にクリア
C常にクリア

更新履歴

2020 年 3 月 5 日

https://stdkmd.net/bitfield/ で再公開しました。図を SVG で描き直しました。

── 続きを読む ──── 続きを隠す ──

2016 年 9 月 21 日

http://stdkmd.com/bitfield/ に引っ越しました。

2012 年 12 月 26 日

BFINS のアドレッシングモードの説明で欠落していたソースオペランドを追加しました。

2000 年 10 月 10 日

HTML を更新しました。

2000 年 9 月 16 日

『M68000 ファミリのビットフィールド命令』と改題し、HTML 化して STUDIO KAMADA で公開しました。

1999 年 10 月 9 日

月刊電脳倶楽部 138 号(1999 年 11 月号)の読み物横町のコーナーに『X680x0 アセンブラ講座 #$11《ビットフィールド命令》』として収録しました。