2

ARMアセンブラ初心者の質問です。私は最初のアーム アセンブラ プログラムを書いており、この C フラグメントをコーディングしようとしています。

int x = somevalue1 << 12; // s19.12 

int y = somevalue2 << 12; // s19.12

int a = somevalue3 << 12; // s19.12 

int b = somevalue4 << 12; // s19.12

int c = somevalue4 << 12; // s19.12

long long acc = (long long) a * b;

acc += (long long) x * y;

int res = (acc >> 24);

acc += (long long) c * a;

最初の部分をコーディングし、r10、r11 レジスターの合計を計算しました。

@ r6 =a, r4 = b, r0 = x,r2 =y, r3=c

smull r10, r11, r6, r4  @acc = a * b

smlal r10, r11, r0, r2  @acc += x * y

次に、「long long」を 24 ビット右シフトして、r10 および r11 レジスタから「res」の値を抽出する必要があります。それ、どうやったら出来るの ?

-ありがとう、

4

1 に答える 1

3

r10 には下位 32 ビットが含まれ、r11 には上位 32 ビットが含まれます。

r10           r11
0  1  2  3    4  5  6  7

必要な結果は次のようになります。

r12
3  4  5  6

つまり、最終結果には、r11 の下位 24 ビットと r10 の上位 8 ビットが含まれます。符号なし演算を使用する場合、ビットの抽出は非常に簡単です。符号付き演算を使用しているため、符号を保持する必要があります。また、必要に応じて、long long を整数に変換して上位 8 ビットも破棄していることにも注意してください。

まず、r11 の下位 24 ビットを最終的な位置に移動しましょう。算術左シフトにより、符号が保持されます。

mov r12, r11 asl #8

これらのビットを r12 の適切な場所に挿入します。上位ビットの符号が正しいことはすでに確認したので、ここでは論理シフトのみを使用します。

orr r12, r10 lsr #24

上記は、次の C と同等です。

r12 = ((signed)r11 << 8);
r12 |= ((unsigned)r10 >> 24);

もちろん、コンパイラにこのようなコードを生成させることもできます。コンパイラーが C で long long を正しくシフトするには、以下を使用する必要があります。

int res = (acc >> 24LL);
于 2010-06-24T09:54:35.500 に答える