即値がARM命令の有効な即値であるかどうかを判断する方法

http://blog.sina.com.cn/s/blog_7ea827fe0100torx.html

ARMプロセッサのアセンブリ言語では、命令構文形式で<shifter_operand>の定数式が規定されています。「定数は8ビットのビットマップに対応している必要があります。つまり、定数は周期的にシフトされた偶数です。 8ビット定数ビットによる。 "<?xml:namespaceprefix = o ns =" urn:schemas-microsoft-com:office:office "/>

ARM命令システムの文法形式から始めましょう。

ARM命令の構文形式は、次の部分に分かれています。

<opcode> {<cond>} {S} <Rd>、<Rn> {、<shifter_operand>}

その中で、<>の項目は必須、{}の項目はオプションです。たとえば、<opcode>は必須の命令ニーモニック、{<cond>}はオプションの命令実行条件です。記述されていない場合、デフォルトの条件AL(無条件実行)が使用されます。

  LDR、STRなどのオペコード 命令ニーモニック 

Condの       ようにEQ、NE、など実行条件、 など

                 CPSRレジスタの値に影響しますか?書き込み時にはCPSRに影響 しますが、そうでない場合は影響しません。

       Rd          ターゲットレジスタ

Rn         の第1オペランドのレジスタ 

shifter_operand      第2オペランド

 

命令のエンコード形式は次のとおりです。

 

31-28

27-25

24-21

20  

19-16

15〜12

11-0 (12位)

cond

001

オペコード

S

Rn

Rd

shifter_operand

 

第2オペランドの形式が#immed_8r定数式の場合、「定数は8ビットビットマップに対応している必要があります。つまり、定数は8ビット定数を偶数に周期的にシフトすることによって取得されます。」

それはこれを意味します:

#Immed_8rは、チップの処理時に32ビットの数値を表しますが、8ビットの数値(たとえば、01011010、つまり0x5A)から、偶数桁(10000000 0000 0000 0000 0000 0001 0110、つまり、0x5Aは、2桁(偶数桁)のサイクルで右にシフトされます。

ただし、1010 0000 0000 0000 0000 0000 00010110はこの要件を満たしていないため、コンパイル中にエラーを発生させる必要があります。10110101を右に周期的にシフトすることで取得できる場合がありますが、偶数ビットを周期的にシフトすることでは取得できないためです。1011 0000 0000 0000 0000 0000 00010110もこの要件を満たしていません。明らかに、1 01101011は9桁です。

なぜそのような要件があるのですか?

命令のエンコード形式から説明するために(これが最初に命令のエンコード形式について説明した理由です)、表のshifter_operandが占めるビット数(12ビット)を注意深く見てください。12ビットコードを使用して32ビット数を表すことは絶対に不可能です(12ビット数には2 ^ 12の可能性があり、32ビット数には2 ^ 32タイプがあります)。

しかし、12ビットコードを使用して32ビットの数値を表す場合はどうすればよいですか?

表現の数には制限があります。コーディングを通じて、32ビットの数値を表す12ビットコーディングの使用を実現します。

12ビットのshifter_operandでは、8ビットがデータを格納し、4ビットがシフト数を格納します。

8ビットストレージデータ:「定数は8ビットビットマップに対応する必要がある」と説明されています。

4ビットストレージのシフト数:偶数桁のみをシフトできる理由を説明します。4ビットに対して可能な値は16のみであり、32ビットは32回周期的にシフトできるため(32の可能性)、制限する必要があります:偶数桁のみをシフトできます(2桁は16のように2つシフトされます)桁がシフトしています、16種類のシフトが可能です)。このようにして、表現できる状況が実際の状況の半分であるという矛盾が解決されます。

したがって、#immed_8r定数式の制限は、命令エンコーディングの2番目のオペランドの数が32ビットのオペランドを表すのに十分ではないという問題を解決するのに無力ですが、私の意見では、これは次のように言えます。スマートなアプローチ。12桁を直接使用して32ビットのオペランドを表す場合、0から(2 ^ 12-1)までしか表すことができないためです。(2 ^ 12-1)より大きい数値は表現できません。そして、「8ビットはデータを格納し、4ビットはシフト数を格納する」と慎重に考えると、それが最良の組み合わせになるはずです(すべての組み合わせについては考えていませんが、いくつか試してみました)。


ARM命令の第2オペランド#immed_8r詳細な説明

ほとんどのARM一般データ処理命令には、柔軟な第2オペランド(柔軟な第2オペランド)があります。ここでは、形式の1つである#immed_8r定数式について説明します。定数は8ビットパターンに対応している必要があります。ビットマップは、32ビットワード内の偶数ビット(0,2,4、... 28,30)だけ周期的にシフトされます。法的定数0xff、0xff000、0xf000000f。不正な定数:0x101,0xff04

ARMの32ビットモードでは、命令の長さは32ビットです。上記のデータ処理命令では、オペランド2は12ビットです。したがって、0x7f02のような数値を完了するには、2つの命令が必要です。

MOV     R3、#0x7F00    ; E3 A0 3C 7Fこの命令は、0x7fシフト​​を単独で完了します。

ORR     R1、R3、#2

だから私は0x7f02を見つけることができません

サイクリックシフトに関しては、実際、アームにはサイクリック右シフト(ROR)しかありません。0x7fから0x7f00は、右に24回循環シフトすることで実現されます。ここでは、各シフトは2ビットであるため、12倍(0xc)です。

ARMデータ処理命令では、演算に関係する第2オペランドが即値の場合、8ビット定数を使用して偶数桁を右に回転させることにより、各即値を間接的に取得します。右に回転するのは1つです。4ビットバイナリの二重表現。有効な即値は次のように表すことができます。<immediate> :=immed_8; 循环右移(2×rotate_imm)その中で:<immediate>即値をimmed_8表し、8ビット定数を 表します。いわゆる「8ビットイメージ」。rotate_immは4ビットのサイクリック右シフト値を表します。このように表示されます。問題があります。表現範囲は広くなりましたが、12ビットで表現できる数は確かです。したがって、ARMでは32個すべてではないことを規定しています。 -ビット定数は、上記の構成によってのみ有効な即値です。メソッドは有効な即値を取得し、コンパイル時にエラーを報告しません。

例を挙げると、
0x3FC(0000 0000 0000 0000 0000 00 11 1111 11 00)は、0xffを2ビット回転させることによって得られます
。200(0000 0000 0000 0000 0000 00 00 1100 10 00)は、0xc8を2ビット回転させることによって得られます。それらはすべて合法である。
そして、(0000 0000 0001 1111 1110 0000 0000 0000)0x1FEと
511(0000 0000 0000 0000 0001 1111 1111 0000)とみなすことができない8ビット定数により得られる回転偶数の桁を右にあるので、それはあります違法。

命令オペランドがイミディエートの場合、各イミディエートは、偶数桁を8ビット定数だけ右にシフトすることによって取得されます。

<immediate> = immed_8サイクリック右シフト(2 * rotate_imm)

例:
1。イミディエート値0xF200は、間接的に0xCF2で表されます。つまり、
immed_8 == 8ビット0xF2を24だけ右にサイクリックシフトすることによって取得されます( 2 * 12)0xF2;   rotate_imm == 0xC

2.イミディエート0x3F0は間接的に0xE3Fで表されます。つまり、
immed_8 == 0x3F;  rotate_imm == 0xE
または
イミディエート0x3F0は8ビット0x3Fを右に回転する ことによって取得されます。 28(2 * 14)これは間接的に0xFFCで表されます。つまり、
immed_8 == 0xFC;  rotate_imm == 0xFは、8ビット0xFCを右に30(2 * 15)回転せて得られます。 

いくつかの

PSメソッドがあります。実際、1つずつ数える必要はありません
。LDR疑似命令を使用するだけです。たとえば、次のようになります。ldrr1、= 12345678
コンパイラが自然に作業を行います。実際のプログラミングでも同じです。

 

比較すると、次のように要約できます。

  1. 数値が8ビットビットマップの原則に準拠しているかどうかを判断するには、最初に、数値の2進表現の1の数が8を超えないかどうかを確認します。8を超えない場合は、これらのn 1(n < = 8)同時に8つの2進数に入れることができます。入れることができる場合は、これらの8つの2進数を偶数桁右に回転して、使用する数値を取得できるかどうかを確認します。可能な場合は、この数値は8ビットビットマップの原則に準拠しており、有効です。即時値。それ以外の場合は、満たされません。
  2. 表現できない32ビット数は、論理演算や算術演算などの他の手段でのみ取得できます。たとえば、0x000000ffのビット単位の反転で取得できる0xffffff00です。
したがって、今後のプログラミングでは、使用する第2オペランドが8ビットビットマップに準拠しているかどうかを常に確認してください。12ビットの operand2 「84オープン」の理由については 、この質問を参照してください。牛

おすすめ

転載: blog.csdn.net/lgdlchshg/article/details/78605140