インライン アセンブリ コードを含む単純なプログラムを作成しました。私のコードは、変数 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 に再利用することを決定した理由です。