[小西ホームページ]   [目次・索引]   [前の授業]   [次の授業]

コンピュータIIL(情報科学入門)第4回

目次
4.1 機械語(1)
4.1.1 スタック
4.1.2 機械語とは
4.1.3 命令の形式
4.1.4 Java仮想マシン
4.1.5 プログラムの例
4.2 演習4
4.3 レポート課題
4.4 参考文献
索引
Java仮想マシン   後入れ先出し   オペコード   オペランド   オペレーション・コード   機械語   機械語プログラム   スタック   プッシュ   変数   ポップ   命令セット  

4.1 機械語(1)

4.1.1 スタック

コンピュータの中で、データが格納できる場所を、抽象的に 変数variable ) と呼ぶことがあります。 格納したデータを、変数の値と呼びます。 変数にはデータが一つ格納でき、その値は読み取ったり変更したりできます。

変数にはデータが一つしか格納できません。 たくさんのデータを格納するには、他の抽象データ構造を利用します。 そのようなものの一つがスタックです。

スタックstack ) は、複数のデータが格納できる抽象データ構造です。 スタックには次々とデータが格納できますが、取り出せるのは最後に格納したデータのみです。

An image of a stack
図 4.1  スタックのイメージ

紙袋の中に雑誌を積み上げる様子を考えてください。 例えば、4月号の上に5月号をのせ、その上に6月号をのせます。 直接取り出せるのは6月号のみです。 6月号を取り除けば、5月号が取り出せます。 5月号も取り除き、7月号をのせ、その上に8月号をのせます。 すると、8月号、7月号、4月号の順に取り出せます。 以上がスタックのイメージです。

スタックにデータを格納することを、 プッシュpush ) と言います。 スタックからデータを取り出すことを、 ポップpop ) と言います。 スタックでは、最後に格納したデータが最初に取り出されます。 この仕組みを、 後入れ先出しlast-in first-out ) と呼びます。

4.1.2 機械語とは

ここで、プログラムについて復習します。

コンピュータが動くことは、コンピュータがプログラムを実行することです。 プログラムは、命令の系列で構成されます。 コンピュータがプログラムを実行することは、CPUがプログラムの命令を次々と解釈して実行することです。

プログラムは、CPUが直接理解できる表現という意味で、一種の言語と考えられます。 この言語を、 機械語machine language ) と呼びます。 プログラムが機械語であることを強調するときは、 機械語プログラムmachine language program ) という言葉を使います。

CPUが解釈できる命令の全体を、 命令セットinstruction set ) と呼びます。 一般的に、CPUの種類が異なりますと、命令セットも異なります。 したがって、CPU Aで動くプログラムをCPU Bに与えても、基本的には実行できません。

4.1.3 命令の形式

一般的に、命令は前半部分と後半部分に分かれます。 前半は、命令の種類を表す部分で、 オペレーション・コードoperation code ) または オペコードopcode ) と呼ばれます。 後半は、命令の付加データを表す部分で、 オペランドoperand ) と呼ばれます。 命令によっては、オペランドのないものもあります。

現在のコンピュータでは、命令はバイトの列で表されます。 プログラムは命令の系列ですので、結局、プログラムはバイトの列となります。

4.1.4 Java仮想マシン

この授業では、Java仮想マシンをCPUと見なして演習を行います。 Java仮想マシンJava virtual machine )は、Javaプログラムを実行するために設計された、仮想的なCPUです。 適切なシステムを与えると、現実のCPUは、この仮想的なCPUのシミュレーション(まね)を行うことができます。 実際、javaコマンドは、Java仮想マシンをシミュレーションして、プログラムを実行します。

Java仮想マシンは、基本的には現実のCPUと同じように設計されています。 ただし、いくつかの重要な違いがあります。 今日の話に関係するところでは、Java仮想マシンにはレジスタがないことがあげられます。 Java仮想マシンは、レジスタの代わりに変数とスタックを使います。

4.1.5 プログラムの例

それでは、実際にプログラムを作成して実行します。 今日扱う命令は次の通りです。

表 4.1  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 0003 は、どちらも整数0をスタックにプッシュするものです。 0をスタックにプッシュすることはよく行われますので、特に1バイトの命令が用意されているというわけです。

今日の演習は次のJavaプログラムから始めます。

/*  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%

4.2 演習4

次のプログラムを実行すると何が出力されるかを答えてください。 出力だけではなく、プログラムの動作についても説明してください。 バイナリ・ファイルEx4.classのプログラムの部分を置き換え、javaコマンドを実行すると、答えが確認できます。

  1. 1009 3c00 0000 0000
  2. 1000 3602 1502 3601
  3. 033d 043c 1b3d 1c3c

4.3 レポート課題

今日の演習4の答案をメールで提出してください。 メールの差出人は学内のアドレス(b04a001@twcu.ac.jpなど)とし、メールの宛先はkonishi@twcu.ac.jpとします。 メールの本文には、学生番号、氏名、科目名、授業日(10月21日)を明記してください。


4.4 参考文献


[小西ホームページ]   [目次・索引]   [前の授業]   [次の授業]

2005年10月21日更新
小西 善二郎 <konishi@twcu.ac.jp>
Copyright (C) 2005 Zenjiro Konishi. All rights reserved.