私はCPUとそれらがどのように実装されているかについて読んでおり、いくつかの大きな複雑なアーキテクチャ(x86を見て)には、1クロックサイクル中にメモリからロードする命令があります。 1つのアドレスが1バイトを指しているので、どのように書けばよいですか。
mov eax, DWORD PTR ds:[esi]
ここで、メモリからダブルワード(4バイト!)をロードし、それをeax
にチャッキングしています。これは1クロックサイクルでどのように機能しますか? 4つのアドレスにアクセスする必要はありませんか? DWORDはds:[esi]
から始まり、[ds:[esi] - 3]
で終わります。つまり、4つの実効アドレスを計算する必要がありますが、1サイクルで実行されます。
どうやって?
ありがとう
バイトレベルでアドレスを指定できるからといって、8ビットのデータバスが必要になるわけではありません。ほとんど(おそらくすべて)の最新のx86プロセッサは64ビットのデータバスを使用し、メモリから読み取るたびに毎回64ビットを読み取ります。 8ビットのみを要求した場合、超過分は単に破棄されます。
64ビットを超えるリクエストを行う場合(たとえば、128ビットSSEレジスタ)をロードする場合)、複数のメモリアクセスが発生します。
また、多くのプロセッサにはアラインメントの概念があります。これは基本的に、すべてのメモリアクセスがデータバス幅で割り切れるアドレス上にあることを意味します。ほとんどは未調整のメモリをフェッチできますが、それが調整境界を越える場合(たとえば、64ビット調整システムのアドレス0xFCで32ビットを要求する場合)、データバスに収まる場合でも、複数のメモリアクセスを取得します。 。
質問のいくつかの側面に関するその他の注意事項は次のとおりです。
動作を説明する例として、まず古き良き68020のようなクラシックな32ビットプロセッサについて話しましょう。
さまざまな理由(互換性、ASCII文字など)の使いやすさ)のため、32ビットおよび64ビットのCPUでも個々のバイトに名前(「アドレス」と呼ばれます)があります。CPUにより大きなメモリチャンク、たとえば4バイトに名前を付けるには、最初のバイトに名前を使用し、暗黙的に後続のバイトは、直後に続くアドレス番号を持つバイトです。
一方、CPUには32本のデータラインD0 ... D32があるため、バスは32ビットを同時に転送できます。したがって、アドレスの32ビットのうち、下位2ビットはデータラインのグループを選択します(ビット00はD0 ... D7を選択し、01はD8 ... D15を選択し、10はD16 ... D23を選択し、11はD24を選択します... D31)。上位30アドレスビットのみが実アドレスラインA2 ... A32として存在します。下位2ビットの代わりに、CPUには4つの異なるバイト選択信号があり、さまざまな組み合わせで個別に使用できます。
これで、CPUがアドレス0x1000から32ビットを読み取る場合、32本のデータラインすべてを並行して使用できます。上位30ビットをアドレスバスに配置し、4つのバイト選択信号をすべて設定して、4バイトを転送します。
概要を見てみましょう:
現在のCPUでは原理は同じですが、内部キャッシュメモリでは、外部からのCPUコアの個々のバイト転送を監視できなくなりました。それらは、CPUコアとキャッシュ(両方ともオンチップ)の間で発生します。現在、メモリはキャッシュとのみ通信し、その転送は常にバイトより大きなチャンクで行われます。