2012-06-17 8 views
15

私はただそれを取得しません。マニュアルはあまりにも技術的です。平坦でセグメント化されたメモリとは何ですか?メモリをアドレス指定する方法、メモリ内のバイトを整理する方法どちらが32ビットコンピュータに最適ですか?誰もそれを説明できますか?リアルモードと保護モードは、フラットまたはセグメント化されたメモリと何が関係していますか?ありがとう!セグメンテーションメモリとフラットメモリ

+3

など、あなたが好きか、より良いコンパイラを作る場合は、これらの問題を持っていけないと調整でき正気のプラットフォームで動作するセグメント化されたメモリは、メモリ要件は、サイズを超えた時点からオーバー(32ビットおよび64ビットの土地で)ホールドありますアドレスバスのアドレス。そのような考察は長い過去であり、誰もフラットモデルを使用しています。モトローラ(286までずっと優雅な命令セットとはるかに優れたプロセッサ()とそれの前身)68Kの設計者はこのことを知っていたし、対処するセグメント化して気にしませんでした。しかし、歴史は美学を気にせず、インテルが勝利し、今、私たちはすべての詳細な回答のために386 –

答えて

18

既存の32/64ビットオペレーティングシステムで実行されているアプリケーションだけに興味がある場合は、セグメント化されたメモリを忘れることができます。 32ビットOSでは、4 GBの "フラット"メモリ空間があると仮定できます。フラットとは、32ビットの値とレジスタを使用してアドレスを操作できることを意味します。

16ビットプロセッサでは、アドレスは20ビット幅で、レジスタに格納できないので、1つのレジスタにベースを格納して、実際のアドレスを指定する必要がありました。そのベースにオフセットを追加します。 (私が正しく覚えていれば、基数は16倍になり、実際のアドレスを得るためにオフセットが追加されました。)これは、一度に64KBのアドレスしか指定できないことを意味します。 64KBブロックでメモリを「セグメント化」する必要がありました。

正直言って、初心者の方でも、古い16ビットのチュートリアルや書籍がたくさんあるので、それはまだ聞こえます。アセンブリレベルでプログラムがどのように動作するかを理解する必要はありません。あなたがOS開発を学びたいなら、それは別の話です。 PCは16ビットモードで起動するので、少なくともフラット32ビットモードを有効にするには十分な知識が必要です。

リアルモードとプロテクトモードについても尋ねました。リアルモードはMS DOSが使用したモードです。どんなプログラムでもハードウェア機能にアクセスできました。たとえば、グラフィックカードのコントローラに直接何かを印刷するのが一般的でした。それはマルチタスクOSではなかったので問題は生じなかった。

最近のOSでは、通常のプログラムはハードウェアに直接アクセスすることはなく、メモリに直接アクセスすることさえありません。 OSはハードウェアを管理し、プロセッサ上で実行されるプロセスを決定します。また、すべてのプロセスの仮想アドレス空間も管理します。この種の機能はPCの最初の32ビットプロセッサである386に付属している保護モードで利用できます。

+0

+1の子孫を使用します! –

+0

そこで、アドレッシングセグメントメモリは16ビットレジスタに適合し、レジスタ容量よりも大きいメモリからアドレスを定義式のようです。 PCが16ビットアドレッシングモードで起動すると、BIOSは32ビットアドレスを読み取ることができません。ありがとう! – ali

+0

@ali:私は、BIOSのが実装されているのか分かりません。技術的には、何らかの理由でBIOSが32ビットに切り替えてから16ビットに戻ってくるのを防ぐことは何もないと思います。 –

8

アドレス(メモリ、I/O、メモリマップI/Oなど)を使用して何かにアクセスする命令は、(プロセッサ実行のそのレイヤの観点から)完全なアドレスを提供することがあります。例えば、プログラムカウンタがベースアドレスであり、命令がそのベースにオフセットを与え、2つを足し合わせると、(そのレベルで)アドレスを取得します。

16ビットレジスタと64KByteの最大アドレス空間の制限を持つ16ビットシステムを採用してください。そのメモリを拡張する簡単な方法は、セグメント化することです。アドレス全体を含むレジスタの代わりに、命令のレジスタには、PC相対命令と同様に、ベースに対するオフセットが含まれています。この場合を除いて、ベースアドレスとして使用されるさらに別のレジスタが存在する。これは、コアを変更してもあまりにも多くのことをすることなく、簡単にアドレス範囲を拡張したいと考えていた多くのアーキテクチャでは、これを見ることができます。 (コアに変更を加えることなくメモリコントローラで行うことができます)x86の場合、いくつかのレジスタがありました。 1つは、実行の範囲を広げるために使用されました。もう1つは、データへのアクセス、ロード、ストアの範囲を拡大することです。非PC相対分岐のアドレスは、左に4ビットシフトされたコードセグメントを使用して計算され、命令で指定されたレジスタに加算されました。 pc相対でないロードおよびストアの場合、データセグメントレジスタが使用され、左にシフトすると、命令で指定されたレジスタが追加されます。したがって、0x123456789をアドレス指定する場合は、セグメントレジスタに0x12340000が含まれ、アドレッシングに使用されるレジスタに0x56789が含まれているか、セグメント0x12345678とgprに0x9が含まれている可能性があります。 Pc相対アドレス指定はもちろんセグメント+ pc +オフセットです。

これは、さまざまなメモリモデルの採用につながります。小さい、小さい、中型、大きい、巨大な。最小のモデルでは、すべてのものが64Kのメモリ空間内にあり、コンパイラとコードがセグメントレジスタを心配する必要がないということを、x86の場合に仮定したり仮定したりすることができます。大きなモデルの場合や遠くにあるfarポインタを使用する場合は、データセグメントを設定してデータオフセットを設定し、ロードまたはストアを実行します。コードの場合、コードセグメントレジスタを変更するとすぐに、命令をフェッチしている全体のアドレスに影響を与えるので、少し難しいでしょう。ハードウェアソリューションでは、ブランチがセグメントとオフセットの両方を変更できるようにすることもできますし、コードで実行することもできます(ハードウェアが許可されている場合)。私は今のところそれをあなたと混同しないでください。

unsigned char abc[123]; 

基本的には同じです:あなたは、コードで配列を持っているときはいつでも

。ベースアドレス、メモリ内で配列が始まるアドレスはセグメントに似ており、インデックスはオフセットです。上記のabcがアドレス0x1004にあった場合、abc [5]はアドレス0x1004 + 5 = 0x1009にあります。 x86セグメントのようにシフトされません:オフセットアドレス指定ですが、ベースとオフセットを追加するのと同じ概念です。いくつかのセグメント化されたアーキテクチャでは、追加がありません。いくつかのレジスタのいくつかのビットは、どこかの上位ビットです。これらのシステムの1つでアドレス0x12345を取り、0x1はセグメントに、16ビットgprでは0x2345でなければなりません。それをシフトと考えることもできますし、必要に応じて追加することもできますが、x86セグメントとは異なり、オフセットはシフトとも呼ばれます。

フラットなメモリ空間は、x86システムでは幻想的なものです。 x86コンピュータ、32ビット、さらには64ビットでも、プラグインカードのフラットメモリ容量は1Gigに制限されています.32ギガビットのシステムでは4ギガバイトのアドレス空間があり、なぜこれらのいくつかがあなたに3ギガの限界を与えるか、または4ギグの錯覚を与えますが、プラグインカードのためにその一部を切り刻んだ理由です。 (あなたのマザーボード上のアイテムの多くは、実際のプラグインカードと同様にこのスペースにあります)。ビデオカードや解像度などによっては、フレームバッファ全体がその周辺空間のサブセットに収まらないことがあるので、アクセスを分割する必要があります。 BIOSはあなたにx86アドレス空間の基底としてアドレス0x80000000を与えているかもしれません、そして、あなたはビデオカードのアドレス空間内のアドレスを指定するビデオカードの他のレジスタにいます。デモンストレーションの目的で、x86アドレス0x80000000で16MByteのウィンドウが与えられたとします。 16Mバイトは0x01000000です。ビデオメモリ内のアドレス0x04321888にアクセスしたい場合は、ビデオカード内のセグメントレジスタを0x04に設定し、次にx86アドレス空間(pci(e)アドレス空間)にアドレス0x80321888を使用する必要があると考えられます。

ここの一番下の行は、ここからいくつかのビットを取り出し、そこからいくつかのビットを取り、それらをまとめてターゲットにします。ビデオカードまたはオンボードI/Oコントローラ、またはpciまたはpcieコントローラである周辺機器を扱うときは、ターゲットアドレス空間に関して考えることを学ばなければなりません。プロセッサには、プログラムの観点からのアドレス空間があります。 mmuはそれを物理アドレス空間にスクランブルすることができますし、あなたはあなたのpcieアドレス空間を持っています、そして、pcieを通してアクセスされた周辺機器はそれぞれ独自のアドレス空間を持っています。インテルとインテルベースのPCの世界は、プロセッサの物理アドレス空間とpcieアドレス空間を同じにしています。 mmuの仮想対物理スクランブリングはまだそこにあり、周辺のアドレス空間へのウィンドウはまだそこにありますが、あなたはまだそこからいくつかのアドレスを取ってそこから少しずつ最終的なアドレスを得る必要があります。

リアルで保護されたアクセス権は、アクセスに関連しています。例えば、ポインタを作成したり、ポインタを変更したり、任意のアドレスを作成したりすることができます。これは、別のアプリケーションメモリやカーネルのメモリを突き抜けてしまうことを意味しますか?理想的には、仮想マシンのビットにあるアプリケーションの命令を実行しているときに、各アプリケーションごとにそのようにする必要はありません。必要な場合は、コードや命令がフィルタを通過するたびにメモリにアクセスします。そのフィルタは、そのアクセスがプログラムの許可された空間内にあるかどうかをチェックし、その領域外に出ると、その例外がカーネル(これらの制限を持たないか、または異なる制限を持つ) 、または何かへのアクセスを仮想化したり、ユーザーに警告を出したりすることができます(一般保護違反)。仮想化されたプログラムが実際にプロセッサ上で命令を実行できるようにする仮想化されたプログラムが、ビデオカードのアドレスと考えられるものにアクセスすると、保護違反が発生し、VMWareドライバ/アプリケーションカーネルレベルと考える)は、そのアドレスを取得し、ビデオカードの応答を偽り、アプリケーションに制御を返します。メタル上で命令を実行させることにより、すべてのプロセッサ命令をシミュレートする代替手段へのより迅速な仮想化が可能になります。それは極端なケースです。あなたがこれを読んでいるWebブラウザでさえ、0x000や0x8000のような基本アドレスに基づいたメモリ空間を持っていると思うように仮想化されています。特定のOSの各プログラムを同じものにコンパイルしますフラットな仮想メモリ空​​間であり、オペレーティングシステムは仮想アドレスから物理アドレスへのアドレスの変更を処理します。あなたのウェブブラウザのアドレス0x8000へのアクセスは物理0x12345678であり、mp3プレーヤープログラム0x8000のアクセスは物理的な0x2345678かもしれませんが、両方のアプリケーションに対して命令は0x8000を計算しています。

最高のものを言うことは、常に相対的な用語です。一人の人は、他の人が最悪です。あなたは自分のために最悪から最高のものを定義しなければなりません。モーメンタムと世論は、x86をフラットなメモリ空間に、または少なくともプログラマの観点から見たフラットなメモリ空間の錯覚に追い込んだので、フローに苦労することは少なくなりました。

8086/8088プログラマとハードウェアのリファレンスマニュアルのコピーを入手することをお勧めします。これは、数ドルでも可能です。

http://www.amazon.com/Manual-Programmers-Hardware-Reference-240487-001/dp/1555120814/ref=sr_1_1?ie=UTF8&qid=1340000636&sr=8-1&keywords=8088+programmers+reference

あなたのように計算されたセグメントとオフセットを持っていたときなど、バックpcemuのようなシミュレータを取る(私は、この目的のhttp://github.com/dwelch67/pcemu_samplesためのクローンを持っている)しても、仮想化の前に、命令セット、古い学校と遊ぶ、保護セグメントを4つ左にシフトし、オフセットを追加します(これはすべてこのマニュアルで説明しています)。以来、あらゆる世代は、逆互換にしようとしながら、改善しようとする何かを行ってきました。もちろん利益を助けてくれたが、プロセッサを厄介な獣に変えた。あなたは、x86の詳細について忘れて、より洗練されたシステムを学ぶほうがいいです。なぜなら、x86の進化のせいで、コンパイルされたコードの上に何かを書き込もうとすると、最小限の利益しか得られないからです。異なるファミリのプロセッサは同じコードを異なる速度で実行するため、新しい世代では以前のコードよりもはるかに遅い速度でハンドチューニングされたコードを実行することがよくあります。コンパイラよりも高速ではないので、すべてのプラットフォーム上で高速になるようにチューニングすることはできません。したがって、コンパイラにx86 asmコードを残すだけです。

関連する問題