読者です 読者をやめる 読者になる 読者になる

はじめて読む8086

GW中に「はじめて読む8086」という本を読んだ。

8086というのはインテルが開発、発売していたCPU「Intel 8086」のことで、今まで連綿と続くx86アーキテクチャを採用した最初のCPU。 ただし、8086で採用されたx86は16ビット版のx86

8086(x86-16)のアセンプラについてアセンプラを理解するのに必要なCPUやメモリ、I/Oの仕組みと合わせてわかりやすく解説されている。 開発環境はMS-DOSを想定しているが、そこら辺は気にする必要はない。

以下、メモ。

8086のレジスタ一覧

汎用レジスタ

インデックスレジスタ

  • SI(ソースインデックス)
  • DI(デスティネーションインデックス)

特殊レジスタ

  • BP(ベースポインタ)
  • SP(スタックポインタ)
  • IP(インストラクションポインタ)

セグメントレジスタ

  • CS(コードセグメント)
  • DS(データセグメント)
  • ES(エクストラセグメント)
  • SS(スタックセグメント)

あと、フラグレジスタという演算結果の状態を記録するレジスタがある。

どのレジスタもサイズは16ビット。
汎用レジスタは上位バイトと下位バイトを分けることにより8ビットのレジスタとしても使うことができる。

メモリやI/Oとのやり取り

8086ではアドレスバスが20本ある。 つまり、8086で扱えるメモリは1MiB(=2**20バイト)。

8086は20本あるアドレスバスの下位16本を利用してI/Oアクセスを行う。 つまり、8086で扱えるI/Oポートは65536(=2**16)個。

メモリへのアクセスなのか、I/Oへのアクセスなのかはアドレスバスとは別に信号を送って区別する。 CPUによってはアクセスするアドレスによってメモリへのアクセスなのかI/Oへのアクセスなのかを区別する(メモリマップドI/O)。

セグメント方式

8086ではメモリ管理にセグメント方式という方法をとっている。

メモリ全体はいくつかのセグメント(領域)に分けて管理される。
セグメントの始まり(セグメントベース)の物理アドレスはどこでもいいわけではなくて16の倍数でなくてはならない。 つまり物理アドレスを16進数20ビットで表したときに一番下の桁が0になっていないといけない。
またセグメントは連続していなければならない。 これは、例えば、一つのセグメントが0x00000から0x00010までと0x00040から0x00100まで、みたいに分かれていてはいけないということを意味する。

セグメントベースの物理アドレスから下位4ビット(セグメントの制約からこれはどれも0)を除いた16ビットの数値をセグメントアドレスという。

アドレスの指定はセグメントベースとセグメントベースを起点としたオフセットによって行う。 オフセットはオフセットアドレスという16ビットの数値で表される。 これはつまり、オフセットの最大値は0xffffで1つのセグメントの最大の大きさも0xffffであることを意味する。

まとめると、セグメント方式では、セグメントアドレスが0xffe1のセグメントのオフセットアドレスが0x0024のメモリへのアクセスは 物理アドレス0xffe34(= 0xffe10 + 0x0024)へのアクセスに変換される。

この変換はCPUによって行われ、アセンブラでの通常のアドレス指定はオフセットアドレスで行う。 セグメントアドレスは用途によってセグメントアドレス郡に格納されているどれかの値をセグメントアドレスとして使う。

はじめて読む8086―16ビット・コンピュータをやさしく語る (アスキーブックス)

はじめて読む8086―16ビット・コンピュータをやさしく語る (アスキーブックス)