ぐだぐだ低レベルプログラミング(72) ARM64(AArch64)、ビットフィールドMOV

Joseph Halfmoon

前回、MOV命令の込み入った事情を図にしただけで「実習はまた今度」などと書きました。しかし今回も「また今度」の回であります。MOV命令の親戚?ビットフィールドMOV命令群がこれまた込み入っているためであります。ビットフィールド転送命令と聞くと地味な?感じがしますが、これがどうして非常に多数の命令に化けるのであります。

※「ぐだぐだ低レベルプログラミング」投稿順indexはこちら

ビットフィールド転送命令とそのエイリアス

前回のMOV(転送)命令は、調べていくとaliasで実際は他の命令だった、というオチが多かったです。MOVは蜃気楼のようなもので実体がない、と。今回はその逆です。ビットフィールドMOV命令は、ちょいとオペランドの「お化粧直し」をして多数の命令の実体を担っていたのであります。その様子を表にしてみました。BFM_alias

BFM、SBFM、UBFMという3列が、今回とりあげるビットフィールド転送命令です。

    1. BFM Bitfield MOVE
    2. SBFM Signed Bitfield MOVE
    3. UBFM Unsigned Bitfield MOVE

上記の3命令はレジスタの全幅でなく、その一部であるビットフィールドをとりだして他のレジスタに転送する命令群です。そう説明すると何に使うんだか分からないマイナーな命令群にも聞こえますが、実はこやつらは他の多くの命令に化けて各所で活躍しています。上の表の左端の列、alias に書かれている命令の全てもしくは一部の実体はビットフィールド転送命令です。alias先?の命令群は以下の3つに分類できます。

    • BFCなどのビットフィールド操作命令
    • ASRなどのシフト命令
    • SXTBなどの符号拡張、ゼロ拡張命令

大活躍じゃないですかい。aliasとする場合、オペランドの指定を工夫することでお化粧しています。こんな感じ。

    1. ソースレジスタをゼロレジスタにする。
    2. 2つある即値(イミディエイト)に特定の値を指定する
    3. エイリアス命令の2つまたは1つの即値を加工して実際のビットフィールド転送命令のオペランドに変換する。

なかなかテクが入っているので、それぞれのalias命令をエクササイズするときに個別に見て行きたいと思います。しかし、元のビットフィールド転送命令自体の動作も結構複雑です。まずはその動作を確認しておきたいと思います。

ビットフィールド転送命令BFMの動作

以下にビットフィールド転送命令 BFM の動作を図にしてみました。ビットフィールド転送命令には二つの即値、imms と immr があり、その値が動作のキモになります。

左右に2つ動作が書かれていますが、immsとimmrの大小関係で、どちらになるかが決まります。図を見ていただいた方が分かり易いかと思います。

どちらもソースレジスタの一部のビットフィールドを取り出して、デスティネーションレジスタに書き込みます。ビットフィールドを上書きした部分以外のデスティネーションレジスタの他ビットの値は以前のものが保持されます。

BFM

符号付きビットフィールド転送命令SBFMの動作

上のBFM命令の動作が分かってしまえば、SBFM命令の動作は簡単です。BFMでは「キープ」であったデスティネーションの他ビット部分の取扱いが違うだけです。ビットフィールドよりもMSB側の部分には、ビットフィールドの最上位ビットを符号ビットとみなしてそれをコピーします。下図の赤の部分です。それに対してビットフィールドよりもLSB側の部分はゼロです。下図の青の部分です。

SBFM

符号無ビットフィールド転送命令UBFMの動作

上のSBFM命令で「符号ビット」がコピーされていた部分をゼロクリアするとUBFM命令となります。こんな感じ。

UBFM

個別にビットフィールド転送命令見ていくと、これがそんなに応用の広い命令には見えないのですが、実は変幻自在に活躍するのだ、と。ううむ、次回こそ実機上でその動作を確かめないと。ちゃんと実習しろよ、自分。

ぐだぐだ低レベルプログラミング(71) ARM64(AArch64)、MOVの込み入った事情 へ戻る

ぐだぐだ低レベルプログラミング(73) ARM64(AArch64)、MOV命令の実習 へ進む