2016-08-15 20 views
1

x86-32アセンブリでは、パラメータはスタックに格納されますが、レジスタに格納されるパラメータはx86-64です。これの理由は何ですか?パラメータがレジスタに格納され、x86-64アセンブリのスタックに格納されないのはなぜですか?

+2

IA64は、歴史的な理由からx64ではありません。 – harold

+1

x86パラメータの下では常にスタック上に存在し、決してレジスタ内には存在しないことを一般化することは悪いことです。それはすべて、呼び出し規約、渡されるデータのタイプ、およびパラメータの数に依存します。 –

+0

1)できること2)もっと多くのレジスタ3)速度 –

答えて

8

RAMにアクセスするよりもCPUレジスタにアクセスする方が高速です(多くの場合)。

64ビットCPUには汎用レジスタがたくさんあります(64ビットとはまったく関係がありませんが、それは新しい/より大きなものだからです)。

+0

も参照:https://en.wikipedia.org/wiki/Calling_convention –

+0

誰かがx64をそのウィキペディアの記事に追加する必要があります... – Thilo

+0

リンクされた記事:https://en.wikipedia.org/wiki/X86_calling_conventions –

5

往復のストア/リロードは、ストア転送のレイテンシが6サイクルに及ぶため、現代の呼び出し規約はより効率的な設計を使用します。呼び出し側はレジスタ内でargを生成し、それをプッシュしないので、命令によっても保存されることがあります。 (そして、復帰後にスタックをポップする必要はありません)。

x86-64は新しいモードなので、後方互換性の要件はありません。したがって、従来の手荷物のない新しいABIを設計することができました。 x86-64 SysV呼び出し規約の設計方法とWindows x86-64呼び出し規約よりも効率的な理由については、this answerを参照してください。 (赤いゾーン、より多くのargを渡すレジスタ)。これは、Windowsの規約よりも複雑です。特に、varargs関数の方がより複雑です。レジスタ内の最初のカップルの引数を渡す


も、32ビットのコードでは、より効率的であるが、新しい呼び出し規則を導入したライブラリとの下位compatの壊れます。

でも、MSは__fastcall/__vectorcallでそれを行いました。これは、32ビットモードでもargを渡すために2つのコールクローバ型レジスタ(ecxとedx)を使用しています。これらの呼び出し規約の64ビット版では、x86-64にはより多くのGPレジスタがあるため、より多くのarg-passingレジスタが使用されます。

Unix/Linuxは、32ビットの新しい呼び出し規約を導入しようとはしていませんが、基本的には古くなったレガシーコードとして遅くなってしまいます。 (32ビットのSysV ABIは、スタック上ではなく、16B SSEと32B AVXベクトルをベクトルregsに渡したり返すための規則で拡張されましたが。

呼び出し規約のドキュメントへのリンクはのタグwikiを参照し、ストア転送の待ち時間の詳細については、パフォーマンスリンクを参照してください。

関連する問題