ARMアセンブリ言語の勉強を始めたばかりですが、MOVを使用してイミディエート番号をレジスタに転送する方法がわかりません。
ARMリファレンスマニュアルと私の教科書の両方から、MOV命令の直後の数の範囲は0から255であると言われています。しかし、ADS 1.2 IDEで自分のPCでテストすると、指示
MOV R2, #0xFFFFFFFF
うまく機能します。番号0xFFFFFFFFは仕様の範囲外ではありませんか?
ARMアセンブリ言語の勉強を始めたばかりですが、MOVを使用してイミディエート番号をレジスタに転送する方法がわかりません。
ARMリファレンスマニュアルと私の教科書の両方から、MOV命令の直後の数の範囲は0から255であると言われています。しかし、ADS 1.2 IDEで自分のPCでテストすると、指示
MOV R2, #0xFFFFFFFF
うまく機能します。番号0xFFFFFFFFは仕様の範囲外ではありませんか?
ARM は、ARM のオペコードに組み込まれているバレル シフターの一部として、即値に対して特定の一連の操作を実行できることに注意してください。
この小さな記事には、ARM アセンブラが ARM 命令の使用可能な小さなスペースに大きな即値を適合させるために使用できるいくつかのトリックの最も明確な説明の 1 つがあります。
この記事では、MVN オペコードを生成して即値のビットごとの補数をロードする特定の例で使用される可能性が高いトリックについて説明します。
これらの種類の操作は、すべての即値で実行できるわけではありませんが、ARM アセンブラーはそれについてかなり賢いと思われます (そして、C コンパイラーは確かにそうです)。シフト/補数のトリックを実行できない場合、値は通常、PC 相対の場所からロードされるか、複数の命令から値を「構築」することによってロードされます。
1 つの ARM 命令は、2 の偶数乗でシフトされた 8 ビットの即値として表すことができる即値定数のみをエンコードできます。
ただし、似ているがすべてのビットを反転するMVN
命令もあります。MOV
したがって、命令MOV R2, #0xFFFFFFFF
としてエンコードすることはできませんが、としてエンコードすることはできます。アセンブラがこの変換を実行する場合があります。MOV
MVN R2, #0
MOV 命令は、imm16 値または Operator2 値のいずれかを受け入れることができます (メモリ アラインメントとは対照的な命令長のため)。これは、次の規則のいずれかに準拠する必要があります (CortexM 命令セット マニュアルからコピー、X および Y は任意の 16 進数値)。
これが、0xFFFFFFFF が受け入れられる理由です (第 4 規則に準拠)。
独自の 32 ビット定数をアセンブルしたい場合は、命令MOVTを使用できます。これは、レジスタの上半分に書き込みます。
指定された定数が有効な範囲内にあるかどうかを判断するのはやや困難です。
マシューがすでに述べたように、アセンブラは、与えられた命令を、mov/mvn、cmp/cmn、tst/tne などのような類似の否定命令に置き換えることで、あなたの手を貸してくれます。
元の値の符号拡張によるアーティファクトが表示される場合があります。逆アセンブリを表示するために使用しているツールが 0..255 を符号付きバイトとして処理する場合、それをより大きな int 型 (またはレジスタ) にロードすると、すべての上位ビットが元の符号ビットで埋められます。価値。別の言い方をすれば、0xFF が符号付きバイトの場合、その 10 進値は -1 です。それを 32 ビット レジスタに入れると、16 進数は 0xFFFFFFFF のようになり、10 進数値は -1 のままです。
0x7F など、上位ビットが設定されていない値を使用してみてください。符号ビットが設定されていないため、より大きな int 型のレジスタまたはフィールドにロードすると、上位ビットがゼロで埋められると思います。
コンパイラ/アセンブラが、指定した値を切り捨てる可能性もあります。ソースコードのエラーだと思いますが、アセンブラはおかしな獣です。0x7FF を指定すると、0x7FF (切り捨てられず、0..255 より大きい) または 0xFFFFFFFF (0..255 に切り捨てられ、符号付きバイト) にコンパイルされますか?
1 つの可能性は、ARM アセンブラが数値の有効ビットを破棄し、最下位の FF のみを使用することです。
MOV 命令は、多くの CPU 命令セットの定番であり、通常、アセンブラは、ターゲット レジスタのサイズと提供される即値を解決します。
たとえば、x86 セットの次の MOV 命令は次のとおりです。
MOV BL, 80h, ; 8bit
MOV BX, ACACh ;16bit
MOV EBX, 12123434h ; 32bit