従来の C/C コンパイラーは、スタック ポインターを増やすことによってローカル変数を作成します(ESP)1回。ただし、プッシュ/ポップ命令を使用すると、コードがよりコンパクトになり、潜在的に高速になる可能性があります。この記事では、この最適化を提供するコンパイラについて説明します。
調査によると、4 つの主要な x86 コンパイラ (GCC、Clang、ICC、MSVC) は現在、push/ を使用していません。ローカル変数を作成するためのポップ命令。代わりに、sub rsp, c を使用してスタック ポインタを減らす、古い方法のバリエーションが好まれています。
ローカル変数にプッシュ/ポップを使用すると、いくつかの利点があります。
プッシュ/ポップ中有益な場合もありますが、すべての場合にお勧めできるわけではありません。たとえば、[rsp x] アドレッシング モードと混合すると、余分なスタック同期 UOP が発生する可能性があります。
次の関数を考えてみましょう:
int extfunc(int *,int *); void foo() { int a=1, b=2; extfunc(&a, &b); }
を使用してコンパイルを改善しましたPush/pop:
# compiled for the x86-64 System V calling convention: # integer args in rdi, rsi (,rdx, rcx, r8, r9) push 2 # only 2 bytes lea rdi, [rsp + 4] mov dword ptr [rdi], 1 mov rsi, rsp # special case for lea rsi, [rsp + 0] call extfunc(int*, int*) pop rax # alternative to add rsp,8 ret
注: この例では、push 命令の最後の 4 バイトを lea 命令の最初の 4 バイトとオーバーラップさせることで、コンパクトさと速度を最適化します。 .
プッシュ/ポップ命令は、コードサイズとパフォーマンス上の利点を提供します。ローカル変数は、現在主流の C/C コンパイラでは使用されていません。これは、余分なスタック同期 UOP が発生する可能性と、スタック オフセットの管理が複雑であることが原因であると考えられます。ただし、ハードウェアとコンパイラの最適化が進むにつれて、ローカル変数のプッシュ/ポップが将来的により広く採用される可能性があります。
以上がC/C コンパイラはローカル変数の作成にプッシュ/ポップ命令を利用しますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。