場合は32ビットプロセッサは、RAMの約4ジブ(すなわち扱うことができる)バイトであるならば、なぜ私のArduinoメガ2560は、SRAMの8 KiBのを持っていない8ビットプロセッサは、それだけで256を処理することができますバイト()?または、次のページを間違って読んでいますか?
場合は32ビットプロセッサは、RAMの約4ジブ(すなわち扱うことができる)バイトであるならば、なぜ私のArduinoメガ2560は、SRAMの8 KiBのを持っていない8ビットプロセッサは、それだけで256を処理することができますバイト()?または、次のページを間違って読んでいますか?
回答:
ほとんどの8ビットCPUには16ビットのアドレスバスがあり、64バイトをアドレス指定できます。これは、256バイトでは実際には十分ではないためです。アドレスを読み込む必要があるたびに、1バイトではなく2バイトを読み込む必要があることを意味します。少し遅いですが、サイズを考慮すると許容範囲です。
(もちろん、多くの例外があり、ほとんどは64kが小さくなりすぎたときに開発されましたが、ここでは基本的な考え方について説明しています)。
アドレスバスとデータバスは、彼らが異なるサイズを有することができるので、分離されています。特定のアドレスバスサイズには、レジスタのビット幅よりも多くのメモリをアドレス指定する多くの手法があります。
最も一般的な方法は、アドレスバス幅を何らかの方法で増やすことです。
アドレスに複数のレジスタを使用する
X
、Y
かつZ
データがRAMの最大64キロバイトを可能にするためのレジスタをアドレス指定します。今度のものはとペアにすることができRAMPX
、RAMPY
、RAMPZ
さらに大きなバージョンでは、より高いRAMのアドレスにアクセスします。また、256バイトを超えるRAMを備えたバリアントSPH
に加えて、スタックポインターの上位バイトにも対応していSPL
ます1H
&L
、B
&C
、D
&E
16ビットのアドレスレジスタとして一緒に使用することができますアドレス指定に自然なサイズよりも大きい単一の大きな特殊レジスターを使用する
アドレスの高い部分に特別なレジスタを使用します。一部のメモリをアドレス指定する場合、デフォルトではアドレスの下位8ビットは8ビットマイクロコントローラの8ビット即値レジスタまたは8ビットレジスタから取得されますが、上位ビットは他のアドレスレジスタの値に置き換えられます。
call
またはgoto
命令を使用する場合、アドレスの下位8ビットまたは9ビットが即値で示され、残りは現在のプログラムカウンタから取得されます。そのため、現在のセグメントからそれほど遠くない場所にアクセスする場合は、1つの命令のみを使用しますが、それ以上のアドレスには2つの命令が必要です(上位ビットを設定するため)。PC
を無条件でジャンプしながら結合します。これを実現する別の方法は、メモリバンキングです。これは、現在でも一部のアーキテクチャで使用されている便利な方法です。このモデルでは、メモリは複数のバンクに分割されます。毎回、特定の銀行のみに対応できます。多くの場合、いつでも常に表示されるグローバルバンクまたはアドレス範囲がありますが、他の部分については、必要に応じてバンクを切り替える必要があります。
あまり一般的ではないテクニックもありますが、Intel 8051にあります。8ビットのデータアドレスを持つマイクロコントローラーとして、最大256個のアドレスを持つことができます。スペースの半分(上位部分)は特殊機能レジスター(SFR)に使用され、アドレス可能な実RAMを128バイトのみに制限します。しかし、現代の8051シリーズのメーカーは、メモリアクセスを分離することでこれを克服する賢い方法を見つけました。ダイレクトアドレッシングアクセスするSFRをしながら、間接アドレッシングレジスタは、RAMの高い部分にアクセスしますけれども、今、あなたが256 + 128 = 384個のアドレス指定バイトを持っている手段。
1 https://en.wikipedia.org/wiki/Atmel_AVR_instruction_set#Memory_addressing_instructions
最小のコアには、256バイト以下のデータアドレス空間(I / Oポートおよびその他の予約済みアドレスが削除された後の128バイト以下のRAM)および8192バイト(8 KiB)以下のプログラムROMがあります。これらは8ビットスタックポインター(SPL内)のみを持ち、12ビットの相対ジャンプ/呼び出し命令RJMP / RCALLのみをサポートします。(AVRプログラムカウンターはバイトではなく16ビットワードをカウントするため、213バイトのROMをアドレスするには12ビットオフセットで十分です。)
利用可能なリソースにアクセスするために必要な追加のメモリアドレス指定機能があります。
- 256バイトを超えるデータアドレススペース(256バイト以上のRAM)を備えたモデルには、SPHレジスタに上位半分の16ビットスタックポインターがあります。
- ROMが8 KiBを超えるモデルには、2ワード(22ビット)のJUMPおよびCALL命令が追加されます。(一部の初期モデルでは、スキップ命令の後に2ワードの命令が続く場合、エラッタが発生します。)
- ROMが64 KiBを超えるモデルには、ELPM命令と対応するRAMPZレジスタが追加されます。LPM命令は、ZのROMアドレスをゼロ拡張します。ELPM命令は、RAMPZレジスタの上位ビットに追加します。これは、より一般的なLPM命令とは異なります。ELPMのゼロオペランド形式(ATmega103およびat43usb320)のみを持つ「クラシック」モデルが存在します。自動インクリメントが使用可能な場合(ほとんどのモデル)、RAMPZを含む24ビットアドレス全体が更新されます。
- (まれな)128 KiB以上のROMを搭載したモデルには、3バイトのプログラムカウンターがあります。サブルーチンの呼び出しと戻りは、追加のスタックスペースバイトを使用します。個々のジャンプと呼び出しに追加の高ビットを提供する新しいEINDレジスタがあり、宛先アドレスとしてEIND:Zを使用する新しい拡張命令EIJMPとEICALLがあります。(以前のIJMPおよびICALL命令はゼロ拡張Zを使用します。)
- (まれな)RAMアドレス空間が64 KiBを超えるモデルは、RAMPX、RAMPY、RAMPZ、RAMPDレジスタを使用して16ビットRAMアドレス制限を拡張します。これらは、それぞれX、Y、Zレジスタペア、または直接アドレス指定命令LDS / STSを使用するアドレス指定モードに追加の上位ビットを提供します。ROMアクセスとは異なり、明確な「拡張」命令はありません。代わりに、RAMPレジスタが無条件に使用されます。
ほぼすべての8ビットプロセッサには、下位部分と上位部分から16ビットアドレスを形成する機能があります。元の8080を含む一部のプロセッサには、アドレスの上部と下部を保持する専用のレジスタがあります(ただし、プログラマの観点からは、8080のスタックポインタのように、個別にアドレス指定する命令を提供しないレジスタもあります)。他の一部のプロセッサでは、アドレスの上半分または下半分専用のレジスタはありませんが、アドレスは「オンザフライ」でアセンブルされます。たとえば、6502では、命令「LDA $ 1234、X」は、8ビットのXレジスタに$ 1234を追加することで形成されたアドレスをアキュムレータにロードします($ F0が含まれていると仮定)。その命令の実行は、4つまたは5つの手順で進みます。
アキュムレータへの読み取りバイトの転送は、次の命令のフェッチとオーバーラップします。さらに、多くの操作で、ステップ3でキャリーが生成されなかった場合、ステップ4で正しいアドレスが読み取られ、ステップ5をバイパスして、ステップ4から次の命令に直接スキップできます。
操作のシーケンスを調べると、リトルエンディアンアーキテクチャがビッグエンディアンアーキテクチャに比べて明確な利点を持っていることに気付くでしょう。ほとんどの場合(示されているものではありませんが)さらに、通常、フェッチされた上位バイトはターゲットオペランドの上位バイトになるため、ALUの結果を待たずに計算されたアドレスからバイトを読み取ることができます。8ビットALUを備えたビッグエンディアンのマシンでは、インデックス付きロードには少なくとも5サイクルかかります(アドレスの下半分はステップ3まで読み込まれないため、ステップ4で計算されるため)。
データバスライン(ピン)とアドレスライン(ピン)は完全に分離されています。簡単に言えば、データバスラインは一度に1つずつ転送(およびメモリに保存)できる最大ビット数を決定し、アドレスラインは選択可能なメモリ「セル」の最大数を決定します。
32ビットx86 CPUが4GBを超えるRAMに対処できないことは、ほとんどマーケティングの問題でした。Pentium 4 CPUにはA33-34ピンがあったことをどこかで覚えています。
アドレス可能なメモリサイズと内部レジスタサイズの間に何らかの関係があることはよくありますが、関係はさまざまな理由で異なります。256バイトのアドレス空間は、マイクロプロセッサのごく初期の段階でも小さすぎると考えられていたため、ほとんどの8ビットプロセッサは、64キロバイトをアドレス指定する16ビット(2バイト)アドレスを生成しました。ただし、バンクスイッチングでは(本質的に特定のI / Oラインを使用してさらに多くのアドレスラインを生成します)、さらに多くのアドレスラインを作成することができました。
最初の16ビットおよび32ビットプロセッサでは、内部アドレスレジスタがアドレス指定できるすべてのスペースに到達するための十分なピンがデバイスに常に存在していませんでした。たとえば、Motorola 68000では、16メガバイトのRAMをアドレス指定するのに十分なアドレスピン(24)しかありませんでしたが、内部アドレスレジスタは32ビット幅でした。
あなたが言及したAVRコントローラーに特にこの質問に答えます。基本原理は、他の多くの8ビットアーキテクチャにも当てはまります。
AVRは8ビットコアです。つまり、8ビットのレジスタがあります。ただし、8ビットでは使用可能なメモリ量にアクセスするには不十分です。したがって、AVRコアは、16ビットポインターレジスタとして組み合わされた特定のレジスタセットを使用できます。レジスタr30およびr31(別名ZLおよびZH)は、この例です。これらが一緒になってZポインターを形成します。
アセンブリでアドレス0x1234のバイトを読み取ると、次のようになります。
ldi ZL, 0x34 ; Load r30 (ZL) with low byte of address
ldi ZH, 0x12 ; Load r31 (ZH) with high byte of address
ld r16, Z ; Load byte to r16
AVRファミリには、これに使用できる3つのレジスタペアがあります。このような操作を可能にするために、ハードウェアで特別に設計されています。
Cのような高レベル言語でプログラミングする場合、コンパイラはこのようなことを処理します。
注:一部のAVRは64kよりも大きなメモリサイズをサポートします。これらのコントローラには、アクセスの前にアドレスの追加ビットが書き込まれる特別な機能レジスタがあります。したがって、アドレスは次のビット(MSBからLSB)で構成されます。
特殊機能レジスタ(通常は1バイト)、ZH(8ビット)、ZL(8ビット)。
Atmelの8ビットAVRは実際には16ビットのデータアドレスを使用します。他にも多数の16ビットレジスタと16ビットタイマーがあります。8ビットプロセッサしかないため、通常は2クロックサイクルを使用して16ビットレジスタをロードします。
プロセッサの「ビット幅」がプロセッサが対応できるRAMの最大量を確立するという概念は、コンピューティングで最も普及している神話の1つです。実際、業界の歴史には、この関係が成り立たないCPUが散らばっています。
HP 21MX、HP 1000:16ビットCPU、メモリー16 MB
PDP-11:16ビットCPU、メモリ4 MB
VAX-11 / 780:32ビットCPU、512MBまでのメモリー
などなど