x86なCPUについて

アセンブラはCPUに非常に近い言語であるので、アセンブラの解説を始める前にCPUを理解しておくのが賢明だろう。
x86なCPUとは8086互換のCPUのことである。例えばPentiumAthlonなどはx86なCPUだ。

レジスタ

CPUは主にデータの計算を行う回路だ(他にもする仕事はあるけどね)。データを二つ受け取りそのデータを加工する(足したり、引いたり、いろいろ)。その入力データと出力データを保存するためにメモリが必要になる。
8086では効率化のためにCPU内部に下記に示す計算専用の特殊なメモリを用意してある。これをレジスタとよぶ。

汎用レジスタAXAH
AL
BXBH
BL
CXCH
CL
DXDH
DL
インデックスレジスタSI
DI
特殊レジスタBP
SP
IP
セグメントレジスタCS
DS
ES
SS
フラグレジスタ
それぞれ16bitの大きさをもった入れ物でAX~DXはそれそれ8bitに分割して使用できる。
さらに32bitCPUではそれぞれのレジスタが32bitに拡張されている。例えばEAXは下記の用になっている
EAXAXAH
AL
.
.

レジスタの使い方

レジスタはどれもほとんど同じように扱えるが、一応それぞれ利用目的が決まっている。
汎用レジスタは汎用に使えて計算などに用いる。インデックスはよく分からないがとくに意識する必要はない(と思うw)。特殊レジスタはスタックで使用される、初期設定以外でこのレジスタを直接いじる事はあまり無い。セグメントレジスタはメモリアドレスに関係していて下で詳しく述べる。フラグレジスタは1か0を表すレジスタで例えば、引き算の結果が0になったら0フラグが立つ。これを利用して、分岐などを行うことができる。
レジスタC言語に置ける変数の様に簡単に扱える。
たとえばアセンブラ

mov ax, 1
mov bx, 2
add ax, bx

C言語の下記に相当する

ax = 1;
bx = 2;
ax += bx;

メモリアドレスについて

8086ではメモリアドレスの指定に二つのレジスタを使用する。一つのレジスタでは16bitの範囲(0x0000〜0xFFFF)しか指定できないので。それにセグメントレジスタの値を16倍して加算することで1MBの範囲を指定できるようになっている(32bitCPUでは4GBまでの範囲が扱える)。
例えばメモリアドレス0x1FFFFのデータをBXへ代入したい場合、セグメントレジスタDXに0x1000を代入し下記のように書く

mov ax, 0xFFFF
mov dx, 0x1000
mov bx, [dx:ax] ; 0x1000×16+0xFFFF=0x1FFFF

dxは自動的にに加算されるのでここでdx:は省略可能である

mov bx, [ax]

つまりdxの値は慎重に設定すべきである