しようとするcmp r0, #350
と、350 は Operand2 形式で表現できないと表示されます。350 は 8 ビットよりも大きいため、私はそれを想定しています。350 と比較するにはどうすればよいですか??
2 に答える
事前に定数をレジスタにロードしてから、レジスタを比較する必要があります。
次のようなものを試してください
ldr r1, =350
cmp r0, r1
これを分解すると、次のようになります
0: e51f1000 ldr r1, [pc, #-0] ; 8 <.text+0x8>
4: e1500001 cmp r0, r1
8: 0000015e .word 0x0000015e
シンボルの末尾に定数を格納し、PC 相対アクセスを使用してレジスタにロードします。
350 を Operand2 形式で表現できない理由を理解するには、ARM が即値オペランド フィールド、つまり最後の 12 ビットをどのように使用するかを理解する必要があります。
- 明らかな方法の 1 つは、これらの 12 ビットを使用して数値をそのまま表すことです。たとえば、最後の 12 ビットが次の場合:
000001011010
含まれる対応する数値は、上記の 2 進数を 10 進数に変換するだけで取得できます。この場合は 90 です。このようにすると、0 から 4095 または -2048 から 2047 のように、2^12 (= 4096) の数字を持つ連続した数字 (整数) のシーケンスしか取得できません。
ARM アーキテクトが思いついたもう 1 つの方法は、「右回転」という概念です。これにより、12 ビットの数値という制限をはるかに超えて数値を格納できるようになりました。これでは、即値用に予約されている 12 ビットのうち、回転 (上位 4 ビット) と値 (下位 8 ビットに格納される) と呼ばれる 2 つのフィールドに分割されます。この値は、256 の可能な組み合わせを表す 8 ビットの数値です。位置は、値が 32 ビット ワードのどこにあるかを決定する 4 ビット フィールドです。12 ビットの代わりに、32 ビットの数値を格納できることに注意してください。以下は、位置の 16 個の値が値の移動先を決定する方法を示す図です。値の部分のビットは、0、1、2 などで示されます。 上の図では、緑の領域は 0 または 1 を表し、白は 0 のみを表します。左側には、基本的に回転値を表す 0 から 15 までの 16 進数が表示されます (12 ビット即値の最初の 4 ビット)。
- あなたの質問に来て、アセンブリ言語で、ARMメカニズムのこの方法で表現できない数値(即時)を指定すると、エラーが発生します。あなたの番号は 350 で、2 進数では 101011110 です。9 ビット (ビット数が奇数) であり、4 回転ビットが 8 ビット値を (4 回転ビットの値の 2 倍) だけ右にシフトするため、奇数の数値は得られないことに注意してください。 12 ビット即値の任意の値のビット数。あなたが書くとき:
cmp r0,#350
Arm は 350 に適切な 12 ビット フィールドを生成しようとします。ただし、350 (9 ビット値が必要) など、生成できない値を指定すると、エラーが生成されます。