今日、VS2008 で提供されるツールの間に逆アセンブラー IL を見つけました。プログラムを逆アセンブルして結果を見てみました。オペコードを理解するのはそれほど難しくありませんでしたが、1 つ驚いたことがあります。.NET はスタック ベースなのですか?! 「優れたコードを書く、第 2 巻」を読んでも、スタック ベースのマシンは非常に遅いため、よく理解できませんでした。実装も簡単ですが、コードを実際のマシンコードに変換する必要があるため、問題を移動するだけなので、MS 開発者がその単純さのためにこのアプローチを選択したとは思いません。
この奇妙な選択を説明できる人はいますか?
PS:
このトピックについて読んだことをここに投稿します:
13.1.1 スタックベースのマシン スタックベースのマシンは、ほとんどの計算にメモリを使用し、メモリ内のスタックを使用してすべてのオペランドと結果を保持します。スタック アーキテクチャを採用するコンピュータ システムには、他のアーキテクチャに比べていくつかの重要な利点があります。
残念ながら、スタック マシンには深刻な欠点もあります。
- 命令は通常、オペランドを指定する必要がないため、他のアーキテクチャに見られる命令よりも小さい (それぞれの消費バイト数が少ない) ことがよくあります。
- 算術式を一連のスタック操作に変換するのは非常に簡単であるため、スタック アーキテクチャ用のコンパイラを作成する方が、他のマシン用のコンパイラよりも一般的に簡単です。
- スタック自体がその目的を果たすため、スタック アーキテクチャで一時変数が必要になることはめったにありません。
スタックは、スタックのいくつかの制限された要素 (多くの場合、スタックのトップおよびスタックの次と呼ばれる) でのみ操作を許可するデータ構造です。スタックでは、通常、新しいデータをスタックにプッシュする、スタックからデータをポップする、現在スタックの一番上にあるデータ (およびそのすぐ下のデータ) を操作する、の 3 つのいずれかを行います。
- ほとんどすべての命令がメモリを参照します (最新のマシンでは遅い)。キャッシュはこの問題を軽減するのに役立ちますが、メモリ パフォーマンスは依然としてスタック マシンの主要な問題です。
- HLL からスタック マシンへの変換は非常に簡単ですが、他のアーキテクチャよりも最適化の機会が少なくなります。
- スタック マシンは常に同じデータ要素 (つまり、スタックの一番上にあるデータ) にアクセスしているため、パイプライン処理と命令の並列処理を実現するのは困難です (パイプライン処理と命令の並列処理の詳細については、「優れたコードを書く」第 1 巻を参照してください)。
と
13.1.1.5 実際のスタックマシン
スタック アーキテクチャの大きな利点は、そのようなマシン用のコンパイラを簡単に作成できることです。スタックベースのマシン用のエミュレーターを作成するのも非常に簡単です。これらの理由から、スタック アーキテクチャは、Java 仮想マシンや Microsoft Visual Basic p-code インタープリターなどの仮想マシン (VM) で人気があります。Java VM のハードウェア実装など、実際のスタックベースの CPU はいくつか存在します。ただし、メモリ アクセスのパフォーマンスが制限されるため、あまり一般的ではありません。それにもかかわらず、スタック アーキテクチャの基本を理解することは重要です。多くのコンパイラは、実際のマシン コードに変換する前に HLL ソース コードをスタック ベースの形式に変換するためです。実際、最悪の場合 (まれではありますが)、
編集: @EricLippert のブログで、質問に回答し、@Aaron の回答を確認する記事を見つけました。