私はいくつかのコードを読んでいて、この行が何をするのかわかりませんでした:
movq (%rsp), %rsp
movq
(x86について話していると仮定して)クワッドワード(64ビット値)の移動です。この特定の指示:
movq (%rsp), %rsp
スタックフレームをウォークアップするコードに非常によく似ています。この特定の命令は、現在のスタックポインターが指すクワッドワードを取得し、それをスタックポインターにロードして、上書きします。
例として、このコードシーケンス(実際のコードに基づいており、AT&T形式ではなくIntelで)は、スタックポインタをその内容から16バイト先の値が0になるまで継続的にロードします。
576 cmpq [rsp+0x10],0x0
582 jz 594
588 movq rsp,[rsp]
592 jmp 576
594 ...
スタックフレームウォーキングコードではない可能性がありますが、通常は使用されないもののスタックポインタをサブオーニングするため、異常です。
スタックフレームを上に移動するには、通常、スタックポインターとベースポインターが必要ですが、これは通常、1レベル上に移動する場合(つまり、関数からの戻り)であるという点で珍しいことです。
複数のレベルを上に移動したい上記の種類のコードの場合、必要な場所に到達するまでスタックポインターを使用し、次にベースポインターをポップする方がおそらく高速です(呼び出し規約は現在のベースをプッシュすることがよくあります)変更する前にポインタを指定して、単純なポップで古い値を復元できるようにします)。
64ビット値のmovです。クワッドであるmovqの「q」のためにその64ビットであり、クワッドは64ビットです。
lが32ビットであるmovlなどの他の例があります。
ただし、movq(%rsp)の場合、%rspはATT構文を使用します。
movq(%rsp)、%rsp-> movqはオペコードと呼ばれ、(%rsp)はソースまたはsrcと呼ばれ、%rspは宛先またはdstと呼ばれます。
レジスタ%rspで検索し、その値を取得して、その値のメモリ[角かっこ "()"はメモリ値に入ることを意味します]に移動し、それを%rspに割り当てます。
両方とも同じレジスタですが、違いは%rspの値が変わることです。
EG:%rspの値が22であるとしましょう。しかし、%rspのメモリは30です。
この命令を使用してmovq(%rsp)、%rsp
%rspの新しい値は30です。これも(%rsp)が22と想定される%rspの値を取得し、(%rsp)がメモリ値30に移動し、それを宛先の%rspに割り当てるためです。 %rsp自体。