I/Oポート


入出力命令

コンピュータは様々な周辺機器から成り立っているのは知ってのとおりです
見た目では、ディスプレイ、キーボード、プリンタ、マウスなどが代表的ですが
このほかにも各種のシステムコントローラーなどやタイマーなども入出力装置です

これまで私たちが作ってきたアセンブリプログラムはどこか物足りませんでした
理由は明らかで、データを入力することも、画面に1文字たりとも表示することがなかったからです

しかし、アセンブリ言語がサポートするのはCPUの命令だけです
メモリとのやりとりや計算などが多くの命令となっています
「画面に文字を表示しろ」という命令は、アセンブリ言語にはありません

では、どうすればよいのでしょうか?
実はアセンブリ言語では、周辺機器への入出力はメモリと同じ概念で行います
周辺機器は 入出力ポート(I/O port) によって管理されます

8086CPU では、入出力にはメモリと同じアドレスバスとデータバスを用います
メモリと区別するための信号がともに出力されることで、メモリとI/Oを切り替えます

入出力ポートは、アドレスバス20本のうち16本を使用します
すなわち16進数、0000 〜 FFFF まで、10進数 65536 個までのポートを持つことができます
入出力を行うには、ポートアドレスと入出力の対象データを指定します

入出力は信号を用いることでハードウェア的にメモリと切り替えます
そのため、技術的に同じバスを使用していてもI/Oポートを指定するには専用の命令を使います
入力の場合は IN、出力の場合はOUT を用います

IN は、第一オペランドにAL、またはAXレジスタを指定します
ポートから入力されたデータは、このレジスタに格納されます
第二オペランドには、8ビットの即値か DX レジスタを用いてポートアドレスを指定します

OUT は IN と逆の指定方法で、第一オペランドに出力するポートの即値、または DX レジスタを
第二オペランドに、出力するデータを格納している AL または AX レジスタを指定します
バイト即値の場合は 0〜255までの範囲 でしかアクセスできません


さて、長いこと入出力ポートについて語ってきましたが
ディスクにファイルを書き出したり、ディスプレイに文字を表示というわけにはいきません
これらは全て OS の管理下であり、直アクセスをしてはいけないというのが原則です
//もちろん、あなたが作った自作のハードウェアなら別かもしれないが…

すくなくとも、マイコンプログラムやデバイスドライバなどを作らない限り
Intel プロセッサにおける IN や OUT 等を使うことはないといって良いでしょう
しかし、ここでは 8086 の入出力を理解するために簡単なI/O制御を行いましょう

いつの時代も(?)、最も簡単な入出力制御はシステムスピーカです
今回のプログラムは DOS/V コンピュータの Windows 9x で実行可能です

システム情報などで入出力ポートを確認してください
ポートアドレス 0061 番がシステムスピーカになっていることが確認できます

システムスピーカは、下位2ビットが 1 であればブザーを鳴らします
これを利用して、システムスピーカの値の 3 の論理和を出力します
-A 100
15F2:0100 MOV DX , 61
15F2:0103 IN AL , DX
15F2:0104 OR AL , 03
15F2:0106 OUT DX , AL
15F2:0107
-G =100 107

AX=0033  BX=0000  CX=000C  DX=0061  SP=FFEE  BP=0000  SI=0000  DI=0205
DS=15F2  ES=15F2  SS=15F2  CS=15F2  IP=0107   NV UP EI PL NZ NA PE NC
けっこう音がうるさかったりするので、夜中の実験は避けるべきでしょう

上のプログラムを実行すると、けたたましいブザーが鳴り響きます
これを止めるには、システムスピーカの下位2ビットを 0 にすれば良いのです
-A 120
15F2:0120 MOV DX , 61
15F2:0123 IN AL , DX
15F2:0124 AND AL , FC
15F2:0126 OUT DX , AL
15F2:0127
-G =120 127

AX=0000  BX=0000  CX=000C  DX=0061  SP=FFEE  BP=0000  SI=0000  DI=0205
DS=15F2  ES=15F2  SS=15F2  CS=15F2  IP=0127   NV UP EI PL ZR NA PE NC
システムスピーカがなっている状態でこのプログラムを実行してください
先ほどのプログラムでスピーカを鳴らしたあとに実行すると良いでしょう

これを実行すれば、システムスピーカの音を止めることができます
優秀な(良いお年頃の?)Cプログラマさんであれば、インラインアセンブラで
これに類似したプログラムをご存知の方も多いことでしょう



前のページへ戻る次のページへ