ARM逆アセンブルの「tst r0,r2,LSL r1」とは?LSLやbeq命令を具体例付きでわかりやすく解説

工学

ARMの逆アセンブルを読んでいると、「tst r0,r2,LSL r1」のような命令が出てきて混乱する人は多いです。

特に「r2 を r1 ビット左シフト(LSL)」という表現は、初心者にはかなり分かりづらく感じます。

この記事では、ARM命令の基本から、「tst」「LSL」「beq」の意味を、実際のレジスタ値を使ってわかりやすく解説します。

まず命令全体を分解してみる

今回のコードは次の2行です。

tst r0,r2,LSL r1
beq 0xAAAAAA

これは大きく分けると、次のような流れです。

  1. r2をr1ビット左にずらす
  2. その値とr0をAND演算する
  3. 結果が0ならbeqで分岐する

つまり、「特定ビットが立っているかチェックする命令」に近い使い方です。

LSLとは何か

LSLは「Logical Shift Left」の略で、日本語では「論理左シフト」と呼ばれます。

簡単に言うと、ビット列を左へずらす処理です。

例えば、次のようになります。

元の値 LSL 1後
0001 0010
0010 0100
0100 1000

左に1ビットずらすと、値は基本的に2倍になります。

つまり、LSLは「ビットを左へ移動する命令」です。

「r2,LSL r1」の意味

「r2,LSL r1」は、「r2の値を、r1で指定されたビット数だけ左シフトする」という意味です。

例えば、次の値を考えます。

r2 = 0b00000001
r1 = 3

この場合、r2を3ビット左へ移動します。

00000001 → 00001000

つまり結果は8になります。

r1の値が「何ビット動かすか」を決めています。

tst命令とは

tst命令は、「AND演算だけして結果を保存しない命令」です。

実際にはフラグだけ更新します。

つまり次のような処理です。

r0 AND (r2をLSLした値)

結果そのものは保存されません。

代わりに、結果が0かどうかをCPU内部フラグに記録します。

具体例で動きを見る

例えば次の値を設定します。

r0 = 0b00001000
r2 = 0b00000001
r1 = 3

まず、r2を3ビット左へ移動します。

00000001 → 00001000

次にtstがAND演算します。

00001000
AND 00001000
----------------
00001000

結果は0ではありません。

そのため、Zeroフラグは立たず、beqはジャンプしません。

beq命令の意味

beqは「Branch if Equal」の略です。

ARMでは、「演算結果が0だったら分岐する」という意味でよく使われます。

つまり今回のコードでは、次の条件になります。

もしAND結果が0なら
0xAAAAAAへジャンプ

逆に、0でなければそのまま次の命令へ進みます。

ジャンプするケースも見てみる

今度は別の値を使います。

r0 = 0b00000100
r2 = 0b00000001
r1 = 3

まずLSL。

00000001 → 00001000

AND演算。

00000100
AND 00001000
----------------
00000000

結果が0になりました。

この場合、Zeroフラグが立つため、beqが実行されて0xAAAAAAへ分岐します。

実際には「ビットチェック」に使われる

このようなコードは、実際には特定ビットのON/OFF確認によく使われます。

例えば、フラグ管理やハードウェアレジスタ確認などです。

「指定位置のビットが立っているか?」を高速に判定できます。

ARMでは、このようなビット演算が非常に多く使われます。

まとめ

「tst r0,r2,LSL r1」は、まずr2をr1ビット左へシフトし、その値とr0をAND演算する命令です。

tstは結果を保存せず、「0だったかどうか」だけをCPUフラグへ記録します。

その後のbeqは、「結果が0だった場合だけジャンプする」という意味になります。

最初は難しく見えますが、「LSLでビット移動 → ANDで比較 → 0なら分岐」という順番で考えると理解しやすくなります。

コメント

タイトルとURLをコピーしました