通常、有効な値の範囲を調べます。
- 値が範囲内にあることを確認します。
- レジスタから最小値を引きます。
- 配列インデックスとして変更された値を使用します。配列は値キーを持つか、単にyes/noにすることができます。
ステップ2,3は、範囲内の一部の値が有効ではなく、配列がかなり密にパックされている必要がある場合にのみ必要です。これは2桁の16進数の場合です。
# Range check (step 1)
cmp r2, #hi_val
bhi out_of_range
cmp r2, #low_val ; optimized version is subs r2, r2, #low_val
blo out_of_range
# Adjust value (step 2)
sub r2, r2, #low_val ; removed in optimized version.
# Get check from array (step 3)
adr r0, key_array
ldrb r0, [r0, r2] ; base of array + adjusted value.
bx lr ; return w. result in r0.
# Handle not in range.
out_of_range:
mov r0, #-1
bx lr ; use 0xffffffff for out of range.
# This is a constant array included with the code.
key_array:
.byte 1, 1, 0, 1, 1, 1, 0, 0, 1, 1 # etc.
もちろん、あなたkey_array
はあなたのユースケースで有効になるように変更する必要があります。条件付きコードは、符号付きおよび符号なしの値に対してわずかに変更されます。
key_array
がすべてバイナリケースの場合は、ステップ2と3はちょうどreturn 1;
です。 low_val
がゼロの場合、減算する必要はありません(または低範囲チェックを行う)。 key_array
のサイズはhi_val - low_val + 1
である必要があります。また、範囲チェックロジックが変更される可能性があります。
このメカニズムは、ispunct
などの多くの 'ctype'関数で使用されますが、バイトに最大8個の値を格納し、ビットマスクを使用して興味のあるものを取得することもできます。 'C'を実行し、コンパイラを使用します。レジスタは1つしか使用できません(R0はEABI互換機能です)が、エラー処理も混在しています。
配列で比較したい値を持っていて、それをループします –
比較のバイナリ検索のようなツリーができます。 – EOF
それはアセンブリ言語の性質のようなものですが、RISC、おそらくCISCではなく、多くのことを一度に命令と比較することはありませんが、例外を表示する可能性があります。あなたは多分比較の数を減らすことができますが、親は1対多数の命令を比較しません。 –