ARMアセンブリの逆アセンブルを扱う際、整数命令(MOV r0,#0など)と浮動小数点命令(VMOV.F32など)ではエンコード方式が大きく異なります。本記事ではVMOV.F32 s1,#1.5がどのように機械語になるのか、その考え方を体系的に整理します。
ARM命令の基本と即値エンコードの違い
ARMでは即値(Immediate)の表現方法が命令ごとに異なります。
整数レジスタ操作のMOVはビット回転付き即値エンコードですが、VFP(浮動小数点)命令は別の専用フォーマットを持ちます。
そのためMOV r0,#0(例:E3A00000)とVMOV.F32は構造的に互換性がありません。
VMOV.F32の命令形式とは
VMOV.F32はVFP命令セットに属し、32bit浮動小数点値をレジスタに転送します。
この命令は「レジスタ⇔即値」「レジスタ⇔レジスタ」の形式があり、即値版は特殊なエンコードルールを持ちます。
内部的にはIEEE754形式の値をそのまま埋め込むのではなく、符号・指数・仮数を圧縮した形式になります。
#1.5の内部表現(IEEE754)
まず1.5のIEEE754単精度表現は以下です。
1.5 = 0x3FC00000(32bit float)
ARMのVMOV.F32ではこの値をそのまま即値フィールドに入れるのではなく、分解して再構成可能な形にエンコードします。
VMOV.F32 s1,#immのエンコード構造
ARMのVFP即値は以下のような圧縮形式です。
sign + exponent + mantissaの一部をビットパターンとして保持し、特定の定数のみ表現可能です。
そのためVMOV.F32 s1,#1.5は「単純な16進固定値」にはならず、命令フォーマット内で専用ビット列として表現されます。
実際の機械語表現について
VMOV.F32 s1,#1.5はARMの単純なMOV命令のように一意の短いHEXで表せるものではありません。
一般的なARMモードでは以下のようなVFP命令としてエンコードされます。
例:EEF00A4B(環境やアセンブラにより差異あり)
これは「VLDR擬似命令」やリロケーションを伴う場合もあるため、必ずしも即値埋め込みとは限りません。
注意点:逆アセンブルでの誤解
VMOV.F32の即値表現は限定的で、すべてのfloat値を直接エンコードできるわけではありません。
そのため逆アセンブル結果では「リテラルプール経由」や「別命令に展開」されるケースがあります。
特にコンパイラ(GCC/Clang/ARMCC)によって出力が異なるため注意が必要です。
まとめ
VMOV.F32 s1,#1.5はMOV r0,#0のような単純な即値命令とは異なり、VFP専用の圧縮即値フォーマットで表現されます。
内部的にはIEEE754(0x3FC00000)を元にしつつも、ARMのVFP即値規則に従ってエンコードされます。
そのため固定の1ワードHEXとして覚えるのではなく、「VFP即値のエンコード規則」を理解することが重要です。


コメント