8086マイクロプロセッサでは、20ビットアドレスが16ビット+ 4ビットアドレスに分割され、4ビットバイナリがセグメントアドレスになります.4ビットバイナリを16進数に変換すると、1ビット16進数になります。私の質問は、物理的な計算の問題が発生したときです。論理からのアドレス、4ビットの16進セグメントアドレスが与えられます。なぜそうなのですか?また、物理アドレスの計算では、lsbに0を追加してセグメントのベースアドレスを見つけ、それにオフセットを追加します。0を追加する背後にあるロジックは何ですか?
2 に答える
1つのセグメントは1つの段落に相当します。1つの段落は、10進数の16バイトまたは16進数の10バイトに相当します。したがって、89AB
オフセットがゼロのセグメント値は、89AB x 10
またはに等しくなります89AB0
(注:このコンテキストでは、すべてのアドレスは16進数です)。
セグメントオフセットから20ビットの絶対アドレスへの変換の例では、これは次のように最もよく表されます。
89AB:F012 -> 89AB -> 89AB0 (paragraph to byte -> 89AB x 10 = 89AB0)
F012 -> 0F012 (offset is already in byte unit)
----- +
98AC2 (the absolute address)
絶対アドレスからセグメントオフセットへの変換の場合:
98AC2 -> 9 8AC2 -> 9 -> 9000 -> 9000:8AC2
(split) 8AC2 8AC2
また...
98AC2 -> 98AC 2 -> 98AC -> 98AC -> 98AC:0002
(split) 2 0002
または途中で分割することができます...
98AC2 -> 98 AC2 -> 98 -> 9800 -> 9800:0AC2
(split) AC2 0AC2
(元のアドレス値)を含む上記の3つのセグメントオフセットアドレスはすべて89AB:F012
、同じ絶対アドレス(同じ物理位置)を指しています。
セグメントレジスタと見なされるレジスタの値に16を掛けて(または16進バイトを左にシフトします。16進数の末尾に0を追加します)、オフセットレジスタの値を加算します。したがって、セグメントとオフセットのペアの任意の組み合わせの絶対アドレスは、次の式を使用して求められます。絶対
メモリ
位置
=(セグメント値* 16)+オフセット値
いくつかの例を実行すると、これをより明確に理解できるようになります。セグメント:オフセットペアの絶対アドレスまたは線形アドレス、F000:FFFDは、セグメント値の最後にゼロを挿入するだけで、頭の中で非常に簡単に計算できます(これは、16を掛けてからオフセット値を加算するのと同じです:F0000 + FFFD ------ FFFFDまたは1,048,573(10進数)
別の例を次に示します。923F:E2FF->
923F0
+ E2FF
------
A06EF or 657,135(decimal)
次に、Segment:Offsetリファレンスを使用して表現できる最大値の絶対メモリ位置を計算しましょう:FFFF0 + FFFF
------- 10FFEFまたは1,114,095(10進数)実際には、8086からかなり時間が経ってから、このような大きな値が実際のメモリ位置に対応するようになりました。PCが1MiBを超えるメモリを持つことが一般的になると、プログラマーはそれを有利に使用する方法を開発し、この最後のバイトは現在HMA(高メモリ領域)と呼ばれるものの一部になりました。しかし、それまでは、プログラムが20ビットの絶対アドレス(1MiB)を超えるSegment:Offsetペアを使用しようとすると、CPUは最上位ビットを切り捨てて(8086/8088 CPUには20のアドレスラインしかありません)、効果的にマッピングします。最初のセグメント内のアドレスに対するFFFFFh(1,048,575)を超える値。したがって、10FFEFhはFFEFhにマップされました。
Segment:Offsetペアを使用することの欠点の1つ(そしておそらくほとんどの人を混乱させるもの)は、これらのペアの多くが同じ正確なメモリ位置を参照しているという事実です。たとえば、以下のすべてのセグメント:オフセットペアは、メモリ内のまったく同じ場所を参照しています。