目次 | 索引 |
---|---|
今日は、コンピュータがどのような装置から構成されているかについて説明します。
コンピュータを構成する装置には、中央処理装置、記憶装置、入出力装置などがあります。
中央処理装置 ( central processing unit )は CPU とも呼ばれ、各種の制御や演算を行う装置です。 CPUはコンピュータの「頭脳」であると考えてください。
記憶装置 ( memory unit )は、データを記憶する装置です。 記憶装置は、主記憶と補助記憶に分類されます。 主記憶 ( main memory )は、容量が小さい代わりに高速に記憶できる装置です。 代表的な主記憶は、メモリです。 一方、 補助記憶 ( auxiliary memory )は、速度が遅い代わりに大容量の記憶ができる装置です。 代表的な補助記憶は、ハード・ディスク、フロッピー・ディスクなどです。
入出力装置 ( input/output unit )は、主に人間との間で入力や出力を行う装置です。 代表的な入出力装置は、キーボード、マウス、ディスプレー、プリンタなどです。
代表的な主記憶である メモリ ( memory )には、1バイト単位でデータが格納できます。 それぞれのバイトには、 アドレス ( address )と呼ばれる番号が割り当てられています。 CPUは、アドレスを指定して、メモリの中のデータを読み書きします。
CPUの内部には、制御を行う制御装置と演算を行う演算装置があります。 この他に、 レジスタ ( register )と呼ばれる、極小容量・超高速の記憶装置があります。 レジスタには、役割が決まっている専用レジスタと、自由に使える汎用レジスタがあります。 専用レジスタには、演算データが格納される アキュムレータ ( accumulator )や、命令アドレスを指定する プログラム・カウンタ ( program counter )などがあります。
さて、コンピュータが動くとはどういうことでしょうか。
コンピュータが動くことは、CPUが次々に命令を実行することです。 ここで、 命令 ( instruction )とは、CPUの動作を意図するデータです。 例えば、レジスタの値をメモリに書き込め、メモリを読み取りレジスタに格納せよ、アキュムレータの値とレジスタの値を足してアキュムレータに格納せよ、などの命令があります。
命令の系列を プログラム ( program )と呼びます。 プログラム内蔵方式 ( stored program )とは、プログラムをデータと同じように記憶装置に格納し、プログラムを実行するときは、プログラムを記憶装置から取り出し、その命令の系列を解釈して実行する方式を言います。 現在のコンピュータは、プログラム内蔵方式で動いています。
この授業では、Java仮想マシンをCPUと見なして演習を行います。 Java仮想マシン ( Java virtual machine )は、Javaプログラムを実行するために設計された、仮想的なCPUです。 適切なシステムを与えると、現実のCPUは、この仮想的なCPUのシミュレーション(まね)を行うことができます。 実際、javaコマンドは、Java仮想マシンをシミュレーションして、プログラムを実行します。
Java仮想マシンは、基本的には現実のCPUと同じように設計されています。 ただし、いくつかの重要な違いがあります。 今日の話に関係するところでは、Java仮想マシンにはレジスタがないことがあげられます。 Java仮想マシンは、レジスタの代わりにスタックを使います。 スタックとは、特別な役割を持つメモリ領域のことですが、今日は特別な変数であると思ってください。 ここで、変数とは、データを一つ記憶するために確保されたメモリ領域のことです。
それでは、実際にプログラムを作成して実行します。 今日扱う命令は次の通りです。
命令長 | 第1バイト | 第2バイト | 命令 |
---|---|---|---|
1バイト | 0x00 | 何もしない。 | |
1バイト | 0x03 | 整数0をスタックに格納する。 | |
1バイト | 0x04 | 整数1をスタックに格納する。 | |
2バイト | 0x10 | byte | 整数byteをスタックに格納する。 |
2バイト | 0x15 | index | 第index変数の値をスタックに格納する。 |
1バイト | 0x1b | 第1変数の値をスタックに格納する。 | |
1バイト | 0x1c | 第2変数の値をスタックに格納する。 | |
2バイト | 0x36 | index | スタックの値を第index変数に格納する。 |
1バイト | 0x3c | スタックの値を第1変数に格納する。 | |
1バイト | 0x3d | スタックの値を第2変数に格納する。 |
上記の命令には、1バイトのものと2バイトのものがあります。
これらの中には、同じ働きをするものがあります。
例えば、命令
10 00
と
03
は、どちらも整数0をスタックに格納するものです。
0をスタックに格納することはよく行われますので、特に1バイトの命令が用意されているというわけです。
今日の演習は次のプログラムから始めます。
/* 1*/ class Ex4 { /* 2*/ public static void main (String[] args) { /* 3*/ int x = 6; /* 4*/ int y = 7; /* 5*/ x = y; /* 6*/ System.out.println(x); /* 7*/ } /* 8*/ }
b04a001@AsiaA1:~/comp2l% javac Ex4.java b04a001@AsiaA1:~/comp2l% java Ex4 7 b04a001@AsiaA1:~/comp2l%
バイナリ・ファイルEx4.classを開きますと、下から4行目にプログラム
1006 3c10 073d 1c3c
が見えます。
このプログラムは、上記の3行目から5行目に対応します。
... 00000150: 0010 1006 3c10 073d 1c3c b200 021b b600 ....<..=.<...... ...
このプログラムを読んでみます。
まず、命令
10 06
で整数6がスタックに格納されます。
次に、命令
3c
でスタックの値が第1変数(
x
に対応)に格納されます。
この時点で、整数6が第1変数に格納されたことになります。
これは、「整数を第1変数に格納する」という命令がないので、整数をいったんスタックに格納し、続いてスタックの値を第1変数に格納しているのです。
続いて、命令
10 07
で整数7がスタックに格納され、命令
3d
でスタックの値が第2変数(
y
に対応)に格納されます。
この時点で、整数7が第2変数に格納されます。
そして、命令
1c
で第2変数の値がスタックに格納され、命令
3c
でスタックの値が第1変数に格納されます。
この時点で、第2変数の値7が第1変数に格納されます。
これも、「第2変数の値を第1変数に格納する」という命令がないので、スタックを仲介にしているのです。
最後に、第1変数の値7が出力されます。
例題1.
プログラム
1008 3d1c 3c00 0000
を実行すると何が出力されるかを答えてください。
出力だけではなく、プログラムの動作についても説明してください。
バイナリ・ファイルEx4.classのプログラムの部分を置き換え、javaコマンドを実行すると、答えが確認できます。
解答例1.
命令
10 08
で整数8がスタックに格納され、命令
3d
でスタックの値が第2変数に格納されるので、第2変数の値は8になる。
命令
1c
で第2変数の値がスタックに格納され、命令
3c
でスタックの値が第1変数に格納されるので、第1変数の値は8になる。
命令
00
が3回で何も変わらない。
したがって、第1変数の値8が出力される。
確認のため、バイナリ・ファイルEx4.classを次のように書き換え、javaコマンドを実行します。
... 00000150: 0010 1008 3d1c 3c00 0000 b200 021b b600 ....=.<......... ...
b04a001@AsiaA1:~/comp2l% java Ex4 8 b04a001@AsiaA1:~/comp2l%
次のプログラムを実行すると何が出力されるかを答えてください。 出力だけではなく、プログラムの動作についても説明してください。 バイナリ・ファイルEx4.classのプログラムの部分を置き換え、javaコマンドを実行すると、答えが確認できます。
1009 3c00 0000 0000
1000 3602 1502 3601
033d 043c 1b3d 1c3c
今日の演習4の答案をkonishi@twcu.ac.jpあてにメールで送ってください。 メールには、学生番号、氏名、科目名、授業日(10月15日)を明記してください。