スタックと割り込み ―― プログラムが動く仕組みを知ろう
CPUは機械語の命令を一つずつメモリから読み出して実行します.さて,このときメモリ上のどの位置(どのアドレス)にある命令を読み出せばよいのかをどうやって知るのでしょうか? ここで出てくるのが,「プログラム・カウンタ」という特別なレジスタ注1です.
注1;レジスタとは,CPUにとって特に重要な情報を格納するための記憶領域であり,CPU内部に存在する.
プログラム・カウンタは,命令が格納されている領域(一般に「コード領域」と呼ばれる)内の,一つのアドレスを指しています.CPUはプログラム・カウンタが指定するアドレスのメモリから命令を読み出し,次の命令を読み出すためにプログラム・カウンタの値を増やします(図1).
図1 プログラム・カウンタとメモリの関係
プログラム・カウンタの値が0x1000のとき,CPUはメモリ上に確保されたコード領域内のアドレス0x1000から命令を読み出す.命令を読み出したら,次の命令を読み出すためにプログラム・カウンタの値を増やす.
命令を読み出すたびにプログラム・カウンタの値を増やすことで,CPUは命令の順次実行を実現します.分岐の場合は,分岐命令の実行結果によってプログラム・カウンタを更新する値が変わります.
図2に,C言語プログラム(リスト2)とアセンブリ言語プログラム(リスト4)の対応関係を示します.このアセンブリ言語はあるCPU用の命令を表現するものですが,詳細は割愛し,ここではif文を構成する(1)~(2)の命令列について概要を説明します.
図2 C言語ソース・プログラム(リスト2)とアセンブリ言語プログラム(リスト4)の対応関係
比較命令cmpで65('A')とr10(chの中身)を比較し,分岐命令jneで前行の比較結果がイコールでない場合に.L12に分岐している.
(1)は,メモリから引き数chの読み出しを行うロード命令ld.b,文字定数A注2との比較を行う比較命令cmp,比較結果によって分岐する分岐命令jneで構成されています.分岐命令jneの実行後,プログラム・カウンタの値は,条件が真なら(2)のmov命令,条件が偽なら(3)のmov命令を指す値に更新されます.(2)のデータ転送命令movではレジスタに1をセットし,続いてメモリへの書き込みを行うストア命令st.wで変数resultにレジスタの値(この場合は1)を書き込んでいます.同じように,(3)のデータ転送命令movではレジスタに2をセットし,続いてストア命令st.wで変数resultにレジスタの値(この場合は2)を書き込んでいます.
注2;ASCIIコードで'A'には65という値が割り当てられている.