関数呼び出しスタックのアライメント
提供されたアセンブリ コードで、最初の操作として RAX がスタックにプッシュされているのを見ると困惑するかもしれません。関数内 f.このアクションの背後にある理由を理解するには、64 ビット ABI を調べる必要があります。
64 ビット ABI では、呼び出し命令の前にスタックが 16 バイトにアライメントされることが義務付けられています。ただし、call 命令は 8 バイトの戻りアドレスをスタックにプッシュし、このアラインメントを中断します。したがって、コンパイラは、次の呼び出しに進む前にスタックを 16 の倍数に再調整する措置を実装する義務があります。
このコンテキストでは、RAX などのドントケア値をプッシュすると、効率的な目的。これは、追加の sub rsp, 8 命令を実行するオーバーヘッドを発生させずにスタックを調整する手段を提供しますが、スタック エンジンを搭載した CPU では効率が低下する可能性があります。
std を使用しないテールコールとの比較: :function ラッパーはこの原理を示しています。自明な関数 g では、コンパイラは事前のスタック アライメント アクションなしで jmp 命令を単純に実行できます。ただし、f の場合、16 バイトのアラインメントを維持し、ABI 要件との互換性を確保するには、RAX の追加プッシュが必要です。
以上が関数「f」が他の操作の前に RAX をスタックにプッシュするのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。