13

メモリアドレッシングについて読んでいます。セグメント オフセットについて読み、次に記述子オフセットについて読みました。リアル モードで正確なアドレスを計算する方法を知っています。これはすべて問題ありませんが、正確にオフセットが何であるかを理解できませんか? 私が読んだところはどこでも:

リアル モードでは、レジスタは 16 ビットしかないため、最大 64k までしかアドレス指定できません。より多くのメモリのアドレス指定を可能にするために、アドレスは から計算され segment * 16 + offsetます。

ここで、最初の行を理解できます。16 ビットなので、最大 2^16 = 64k までアドレス指定できます。

しかし、この2行目は何ですか?セグメントは何を表していますか? なぜそれを16倍するのですか?オフセットを追加する理由。このオフセットが何であるか理解できませんか?誰か私に説明したり、これのリンクを教えてもらえますか?

4

6 に答える 6

20

Intel が 8086 を構築していたとき、1 台のマシンに 64KB を超えるメモリを搭載する正当なケースがありましたが、32 ビットのアドレス空間を使用する方法はありませんでした。当時は、1 メガバイトでさえ大量のメモリでした。(「640K は誰にとっても十分なはずだ」という悪名高い引用を覚えていますか? それは本質的に、当時 1MB は非常に巨大だったという事実の誤訳です。) 「ギガバイト」という言葉は、あと 15 ~ 20 年は一般的に使用されないでしょう、そしてその後5〜10年ほどRAMを参照することはありません。

そのため、完全に活用されることが「決して」ないほど巨大なアドレス空間を実装する代わりに、彼らが行ったことは、20 ビット アドレスを実装することでした。結局のところ、これは 16 ビット プロセッサであるため、アドレスにはまだ 16 ビット ワードが使用されていました。上の単語は「セグメント」で、下の単語は「オフセット」でした。ただし、2 つの部分はかなりオーバーラップしています。「セグメント」は から始まる 64KB のメモリのチャンクで(segment) * 16あり、「オフセット」はそのチャンク内の任意の場所を指すことができます。実際のアドレスを計算するには、アドレスのセグメント部分に 16 を掛けて (または左に 4 ビット シフトします... 同じことです)、オフセットを追加します。完了すると、20 ビットのアドレスが得られます。

 19           4  0
  +--+--+--+--+
  |  segment  |
  +--+--+--+--+--+
     |   offset  |
     +--+--+--+--+

たとえば、セグメントが 0x8000 で、オフセットが 0x0100 の場合、実際のアドレスは((0x8000 << 4) + 0x0100)==になり0x80100ます。

   8  0  0  0
      0  1  0  0
  ---------------
   8  0  1  0  0

ただし、数学はめったにきちんとしたものではなく、0x80100文字通り何千もの異なるセグメントとオフセットの組み合わせ (私の数学が正しければ 4096) で表すことができます。

于 2010-11-07T20:36:45.780 に答える
13

x86 リアルモード メモリでは、物理アドレスは 20 ビット長であるため、次のように計算されます。

PhysicalAddress = Segment * 16 + Offset

こちらもチェック:リアルモードメモリ管理

于 2010-11-07T20:35:08.747 に答える
1

私もこれを理解しようとしてインターネットを精査しているという理由だけで、ここに答えを追加したいと思います。他の回答は、回答の1つに示されているリンクから取得した重要な情報を省略していました。しかし、私はほとんど完全にそれを逃しました。リンク先のページを読んでも、これがどのように機能しているかはまだわかりませんでした。

私がおそらく抱えていた問題は、コモドール64(6502プロセッサ)がどのようにメモリをレイアウトしたかを本当に理解していることだけでした。同様の表記法を使用してメモリをアドレス指定します。合計64kのメモリがあり、PAGE:OFFSETの8ビット値を使用してメモリにアクセスします。各ページの長さは256バイト(8ビットの数値)で、オフセットはそのページの値の1つを指します。ページはメモリ内で連続して配置されます。したがって、ページ2は、ページ1が終了するところから始まります。私は同じスタイルを考えて386に入っていました。これはそうではありません。

リアルモードは、SEGMENT:OFFSETという表現が異なっていても、同様のスタイルを使用しています。セグメントのサイズは64kです。ただし、セグメント自体は、コモドールのように連続して配置されていません。それらは互いに16バイト離れています。オフセットは引き続き同じように動作し、ページ\セグメントの開始から何バイトかを示します。

この説明がこの質問を見つけた他の人の助けになることを願っています。それは私がそれを書くのに役立ったのです。

于 2012-12-17T18:56:49.753 に答える
1

質問と回答が数年前のものであることがわかりますが、リアル モード内に 16 ビット レジスタしか存在しないという誤った記述があります。

リアル モード内では、レジスタは 16 ビットだけではなく、8 ビット レジスタもあります。これらの 8 ビット レジスタはすべて 16 ビット レジスタの一部であり、16 ビット レジスタの下位部分と上位部分に分割されます。

そして、80386+ でリアル モードを開始すると、32 ビット レジスタになり、さらに 2 つの新しい命令プレフィックスが追加されます。コードセグメント。

これらの命令プレフィックスを組み合わせて使用​​すると、1 つの命令のオペランド サイズとアドレス サイズを逆にすることができます。リアル モードでは、デフォルトのオペランド サイズとアドレス サイズは 16 ビットです。これらの両方の命令プレフィックスを使用して、32 ビット オペランド/レジスタの例を使用して、1 つの 32 ビット レジスタで 32 ビット値を計算したり、32 ビット値をメモリ ロケーションとの間で移動したりできます。また、32 ビット レジスタすべてをアドレス レジスタとして (ベース + インデックス * スケール + ディスプレースメントと組み合わせて) 使用できますが、実効アドレスの合計が 64 kb セグメント サイズの制限を超える必要はありません。 .

(OSDEV-Wiki ページの「オペランド サイズとアドレス サイズ オーバーライド プレフィックス」の表で、「0x66 オペランド プレフィックス」と「0x67 アドレス プレフィックス」は N/A (実行不可) であることがわかります。実モードと仮想 8086 モードhttp://wiki.osdev.org/X86-64_Instruction_Encoding
しかし、これは完全に間違っています。なぜなら、Intel のマニュアルには次の記述があるからです。保護モードおよび仮想 8086 モードでも同様です。)

Pentium MMX から始めて、8 つの 64 ビット MMX レジスタになります。
Pentium 3 から始めて、8 つの 128 ビット XMM レジスターになりました。
..

私が間違っていなければ、x64 の 256 ビットの YMM-Register と 512 ビットの ZMM-Register と 64 ビットの汎用レジスタは、リアル モードでは使用できません。

ダーク

于 2014-02-06T12:56:26.057 に答える