3

私はcでプログラムを作成し、それをarmアセンブリに変換しましたが、アセンブリコードで生成されたいくつかの命令を理解するのに問題があります。Cプログラムの一部は次のとおりです。

#define MAX_DIGIT 1024
int main()
{
    int fd[MAX_DIGIT];
    int xLen = 0;
    int sd[MAX_DIGIT];
    int yLen = 0;

    int result[6*MAX_DIGIT];

    // Take input for two numbers
    takeInput(fd, &xLen);
    takeInput(sd, &yLen);   
        ...
        ...
        ...
}
...
...
...

void takeInput(int digit[], int *length)
{
    char c;
    if((c=getchar()) != '\n' && *length <= MAX_DIGIT){
        takeInput(digit, length);
        digit[*length] = c - '0';
        (*length)++;
    }else return;
}

このcコードをgnuarmツールチェーンを使用してarmアセンブリコードに変換しました。そして、生成されたアセンブリコードの一部は次のとおりです。

main:
    @ args = 0, pretend = 0, frame = 32788
    @ frame_needed = 1, uses_anonymous_args = 0
    mov ip, sp
    stmfd   sp!, {fp, ip, lr, pc}
    sub fp, ip, #4
    sub sp, sp, #32768
    sub sp, sp, #20       @Why subtracted 20? 

    mvn r3, #4096
    sub r3, r3, #3
          @What r3 storing and Why took NOT of r3 and again subtract 3 from it?
    mov r2, #0
    sub r0, fp, #12
    str r2, [r0, r3]
    mvn r3, #8192
    sub r3, r3, #7
    mov r2, #0
    sub r1, fp, #12
    str r2, [r1, r3]
    sub r2, fp, #4096
    sub r2, r2, #12
    sub r3, fp, #4096
    sub r3, r3, #12
    sub r3, r3, #4
    mov r0, r2
    mov r1, r3
    bl  takeInput
    sub r2, fp, #8192
    sub r2, r2, #12
    sub r2, r2, #4
    sub r3, fp, #8192
    sub r3, r3, #12
    sub r3, r3, #8
    mov r0, r2
    mov r1, r3
    bl  takeInput
    mvn r3, #32768
    sub r3, r3, #11
    mov r2, #1
    sub ip, fp, #12
    str r2, [ip, r3]

コメントのアセンブリコード自体に自分の考えを記しました。ありがとう。

4

1 に答える 1

6

即値 (命令の一部にエンコードされた定数) は、それらをエンコードするフィールドに数ビットしかないため、特定の値しか持つことができません。コンパイラは、即値でエンコードできない値をレジスタにロードする必要がある場合、値の一部をロードし、演算を使用してそれを終了します。

さまざまな ARM 命令で即値のさまざまなエンコーディングがありますが、ARM アーキテクチャ リファレンス マニュアル、ARMv7-A および ARMv7-R 版からの例として 1 つを示します。「ARM 命令の変更された即値定数」は 12 ビットとしてエンコードされます。4 ビットは回転を指定し、8 ビットは値のリテラル ビットです。4 ビットは 2 進数を形成し、回転量はその数値の 2 倍 (右方向) です。たとえば、4 ビットが 3 の 0011 の場合、回転量は 6 ビットになります。

したがって、4 つのローテーション ビットが 0011 で、8 つのリテラル ビットが 10011101 の場合、値は 10011101 の 6 ビットを 32 ビット フィールド内で右にローテーションすることによって形成されます。したがって、0000 0000 0000 0000 0000 0000 1001 1101 は右に 6 ビット回転され、0110 0100 0000 0000 0000 0000 0000 0010、または 0x64000002 が生成されます。

明らかに、12 ビットは可能なすべての 32 ビット値をエンコードすることはできません。あなたの例でコンパイラが必要とする値の 1 つは 32748、つまり 0x7fec です。任意の位置 (より具体的には、偶数インデックス位置) の 8 ビットから 0x7fec を形成することはできません。

于 2012-08-24T10:55:05.480 に答える