汎用レジスタ
レジスタの役割
レジスタとは、CPUが演算などをおこなうためにメモリから値を読みこむ
命令実行への最終的な記録装置であることはご存知でしょう
レジスタは、あらゆる記憶装置よりも高速でビットあたりの価値も高価です
高級言語になれている人は、レジスタを操作するということに実感がないでしょう
しかし、機械語プログラムの多くはレジスタを操作することが中心といっても良いくらいです
メモリからレジスタへ値を読みこんだり、フロー制御をおこなうのにもレジスタを用います
メモリはアドレスで位置を指定しますが、レジスタにアドレスはありません
メモリとは異なりレジスタは名前で指定するものなのです
レジスタの数は物理的なレジスタの実装で決定され、メモリの変数のように可変ではありません
そして、それぞれのレジスタには専用の役割があります
各種レジスタの中で、データの格納に用いるのが汎用レジスタと呼ばれるものです
レジスタの種類は、汎用レジスタ、インデックスレジスタ
セグメントレジスタ、特殊レジスタ、フラグレジスタに分かれます
汎用レジスタ
|
---|
AX | アキュムレータ
|
BX | ベースレジスタ
|
CX | カウントレジスタ
|
DX | データレジスタ
|
インデックスレジスタ
|
---|
SI | ソースインデックス
|
DI | ディスティネーションインデックス
|
特殊レジスタ
|
---|
BP | ベースポインタ
|
SP | スタックポインタ
|
IP | インストラクションポインタ
|
セグメントレジスタ
|
---|
CS | コードセグメント
|
DS | データセグメント
|
ES | エクストラセグメント
|
SS | スタックセグメント
|
フラグレジスタ
|
---|
--
|
インデックスレジスタや特殊レジスタは、メモリのアドレス指定などに関係するものです
このレジスタについては、このレジスタにかかわる命令と一緒に後ほど紹介します
セグメントレジスタは、8086の特殊なメモリ管理方式に関係するレジスタです
これも、セグメントという特殊な概念について説明する時に一緒に解説します
フラグレジスタは、レジスタの中でも特殊な存在で
値の格納ではなく、CPUの状態を0か1で表します
これも、フロー制御などの判断材料などに用いることができます
これらのレジスタは全て16ビットで構成されています
これが16ビットCPUといわれる由縁ですね
今回は、アセンブリの基本的な命令を使うのに必要な汎用レジスタの知識を得ましょう
汎用レジスタの構成
汎用レジスタには、4つのレジスタが存在します
AX(アキュムレータ) , BX(ベース) , CX(カウンタ) , DX(データ)です
偶然にも頭から A B C D と、アルファベット順になっているので覚えやすいですね
汎用レジスタの目的は、主にプログラマが使い変数としてのメモリです
基本的には、データの格納など、何に用いてもかまわない領域です
しかし、一般的に BX はメモリのアドレスを指すための領域に用い
CX はループなどのカウンタとして用いるためのレジスタであるとされます
そのため、普段はAXにデータを入れ、足りない場合にDXを用いるという方法を使います
レジスタやメモリに、データの転送を行うにはMOVを使います
この命令は、高級言語でたとえると代入をおこなうためのものです
MOV destination, source
この時、第一オペランドをデスティネーション・オペランドと呼び
第二オペランドをソース・オペランドと呼びます
destination は、値を受け取る記憶領域を指定します
この場所には、レジスタかメモリアドレスしか指定することができません
メモリアドレスの指定については、アドレスを説明してから解説します
source には、deastinationに代入するレジスタ、メモリアドレス、または数値を指定します
アセンブリでは、機械語に記述されている数値リテラルを即値とも呼びます
ただし、即値オペランドは必ず1バイトまたは2バイトで表現されます
MOVは、move(移動)から来ている命令ですが、これは非破壊読み取りです
元のデータが破壊されることはなく、実際にはコピーされています
このような命令の一文を、高水準言語ではステートメントと呼んでいましたが
アセンブリは、このような機械語に対応する記号をニーモニックと読んでいます
destination には、数値を直接指定することもできます
MS-DOSのDEBUGを使う場合は、全てが16進数と解釈されます
それ以外の環境でアセンブルする場合、なにもしていしなければ10進数と解釈されます
16進数であることを明示するためには、MOV AX, 50H というように、後ろにHを付加します(8進数なら O)
詳しくは、アセンブラ付属のマニュアルを参照してください
-A 100
15F2:0100 MOV AX , FFFF
15F2:0103 MOV DX , AX
15F2:0105 MOV FFFF , AX
^ エラー
15F2:0105
MOV AX , FFFF というのは、AXレジスタに16進数FFFFを送り
MOV DX , AX は、レジスタAXが格納している値を DX に送っています
DEBUGのAコマンドは、行ごとにエラーチェックを行い機械語に翻訳しています
3行目は、受け取り側がレジスタやメモリではなく、値のためエラーになっています
これを、Gコマンド(またはTコマンド)で実行してください
最後に、各種レジスタの値が表示されるのでそこで確認することができます
-G =100 105
AX=FFFF BX=0000 CX=0000 DX=FFFF SP=FFEE BP=0000 SI=0000 DI=0000
DS=15F2 ES=15F2 SS=15F2 CS=15F2 IP=0105 NV UP EI PL NZ NA PO NC
今は、汎用レジスタ以外の値は気にしないでください
最初の、AX , BX , CX , DX の汎用レジスタの値に注目してください
今回使ったのは AX と DX レジスタです
値が見事、FFFFになっていますね
これは、まぎれもなく私たちが書いたアセンブリ言語を実行した結果なのです
8ビットレジスタとしての使用
各種汎用レジスタは、少し複雑な構造になっています
16ビットで構成される汎用レジスタは二つの8ビットで構成されています
たとえば、AXレジスタは8ビットのAHとALレジスタに分解して考えられます
AH(High)は上位8ビット、AL(Low)は下位8ビットを表すレジスタ名です
この考えは、C言語の共用体を思い出してもらえるとわかりやすいと思います
AXに対するAHとALは、名前とサイズは異なりますが領域を共用しています
つまり、AHの値を変更するとAXの値の上位8ビットが変更されることになります
16ビット : AX
|
---|
8ビット : AH
|
8ビット : AL
|
---|
同様の考え方で、BX , CX , DX のレジスタも BH と BL、CH と CL、DH と DL を持ちます
このように分解されてレジスタも、演算命令などでよく用いるので覚えてください
名前はすぐ覚えられると思うので、問題は概念ですね
-A 100
15F2:0100 MOV AH,42
15F2:0102 MOV AL,41
15F2:0104
-G =100 104
AX=4241 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=15F2 ES=15F2 SS=15F2 CS=15F2 IP=0104 NV UP EI PL NZ NA PO NC
プログラムでは、AHに42hを、ALに41hを代入しています
結果として、実行後のAXレジスタは上位8ビットが42、下位8ビットが41になっていますね
レジスタの操作
最後にDEBUGコマンドから直接レジスタを操作する方法を教えます
プログラムによるレジスタの変化を実験する時に、使うことができます
レジスタの操作には R (Register) コマンドを使用します
このコマンドは、レジスタの内容表示したり変更することができます
R [レジスタ名]
レジスタ名を省略すると、TコマンドやGコマンドが終了した時に出る
レジスタの一覧と次に実行される命令が表示されます
レジスタ名を指定すると、そのレジスタの現在の値が表示され
その後に、そのレジスタに格納する16進数を指定できます
-R
AX=0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=15F2 ES=15F2 SS=15F2 CS=15F2 IP=0104 NV UP EI PL NZ NA PO NC
15F2:0104 2106E8B1 AND [B1E8],AX DS:B1E8=0000
-R AX
AX 0000
:1234
-R
AX=1234 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=15F2 ES=15F2 SS=15F2 CS=15F2 IP=0104 NV UP EI PL NZ NA PO NC
15F2:0104 2106E8B1 AND [B1E8],AX DS:B1E8=0000
最初のRコマンドは、レジスタの一覧を表示しています
二回目は AX レジスタを指定してその値を直接変更して
最後にもう一度レジスタの一覧を表示して、変更されたかを確認しています