2

インライン アセンブリ コードを含む単純なプログラムを作成しました。私のコードは、変数 a と b を単純に追加し、結果を b に返します。

私を混乱させているのは、以下のコードがこの命令 movl 28(%esp), %ecx を生成する理由です。

修飾子 + と = が入力リストと出力リストで果たす役割を完全には理解していません。ですから、これについて少しでも光を当てることができれば幸いです。

#include <cstdio>

int main( int argc , char ** argv )
{
    int a = 2, b = 7;

    __asm__
    (
     "addl %1,%0;"      
    :"+r"(b)           
    :"r"(a), "r"(b)     
    );

    printf("b = %d\n",b);

    return 0;
}
    movl    $2, 24(%esp)
    movl    $7, 28(%esp)

    movl    24(%esp), %edx
    movl    28(%esp), %ecx
    movl    28(%esp), %eax

    addl %edx,%eax

    movl    %eax, 28(%esp)

次に示すのは間違っています。しかし、これは GCC で何が起こっているのかをよりよく理解するためのものです。

さて、+r から =r に変更しました。これが GCC が生成するアセンブリ コードです。

#include <cstdio>

int main( int argc , char ** argv )
{
    int a = 2, b = 7;

    __asm__
    (
     "addl %1,%0;"      
    :"=r"(b)           
    :"r"(a), "r"(b)     
    );

    printf("b = %d\n",b);

    return 0;
}
    movl    $2, 24(%esp)
    movl    $7, 28(%esp)
    movl    24(%esp), %eax
    movl    28(%esp), %edx

    addl %eax,%eax;

    movl    %eax, 28(%esp)

出力は 4 になりましたが、これは間違っています。私の質問は、この命令 addl %eax,%eax; に示されているように、GCC が "=r" でレジスタ eax を b に再利用することを決定した理由です。

4

4 に答える 4

4

その非常に単純な --+入力と出力を=意味し、出力のみを意味します。だからあなたが言うとき:

asm("addl %1,%0;" : "+r"(b) : "r"(a), "r"(b));

3 つのオペランドがあります。1 つの入力/出力レジスタ ( %0) が で初期化され、bその出力が に出力されb、2 つの入力レジスタ (%1および%2) がそれぞれaおよび で初期化されbます。を使用することはありません%2が、とにかくあります。生成されたコードで確認できます。

movl    24(%esp), %edx
movl    28(%esp), %ecx
movl    28(%esp), %eax

addl %edx,%eax

movl    %eax, 28(%esp)

したがって、コンパイラは%eaxfor %0%edxfor %1、および%ecxforを使用してい%2ます。3 つすべてがインライン コードの前にロードされ、%0後で書き戻されます。

あなたがするとき:

asm("addl %1,%0;" : "=r"(b) : "r"(a), "r"(b));

現在%0は出力のみです (入力ではありません)。したがって、コンパイラは以下を生成できます。

movl    24(%esp), %eax
movl    28(%esp), %edx

addl %eax,%eax;

movl    %eax, 28(%esp)

%eaxfor%0およびfor%1を使用します。%edx%2

必要なものを取得する別の方法は次のとおりです。

asm("addl %1,%0;" : "=r"(b) : "r"(a), "0"(b));

0制約を使用%2すると、コンパイラはそれを同じ場所に配置する必要があるため、最終 的には次のように%0 生成されます。

movl    24(%esp), %edx
movl    28(%esp), %eax

addl %edx,%eax

movl    %eax, 28(%esp)

%eaxfor%0および%2、および%edxfor の使用%1

于 2013-05-23T02:24:07.443 に答える
1

-use (出力引数番号)"r"の繰り返しには使用しbない でください。"0"現在、コンパイラは使用されていないものをロードb%ecxています。

于 2013-05-22T15:14:12.403 に答える
-2

「インライン アセンブリ コードを含む簡単なプログラムを作成しました。」

「私のコードは単に変数 a と b を追加し、結果を b に返します。何とか何とか何とか」

どこ?

mov ax,2
mov bx,3 

add bx,ax

もしよろしければ、私をアインシュタインと呼んでください...

「なりすまし」インタビューを思い出させる

読んで泣く

http://www-users.cs.york.ac.uk/susan/joke/cpp.htm

于 2013-05-22T23:55:42.803 に答える