第10回
制御構造と変数(6)~if、for、whileをアセンブリ言語で

制御構造をアセンブリ言語で

ifやforなどの制御構造は、プログラムの流れを決める重要な機能です。その働きを理解するため、これらの命令がCPUに対してどのように伝えられているのかを考えてみましょう。

データ構造と制御構造

C言語にはポインタや構造体といった、いわゆる学習する上での『壁』と呼ばれる重要な機能・概念があります。これらだけに絞って図解で解説した、書籍や技術雑誌の特集記事にお目にかかることもあります。

ポインタと構造体は確かにとても重要で、このコラムでも追って取り上げます。が、その前に処理の流れを変える制御構造をしっかり押さえておいて欲しいと思います。

ポインタや構造体は『データ構造』と呼ばれる機能に分類されます。言語を問わず、データ構造と制御構造とがプログラミングにおける二本柱です。

データをどのように扱うか(データ構造)ということと、そのデータをどのように処理し加工していくか(制御構造)ということによって、プログラムの基本であるアルゴリズム(計算手順・処理手順)が生成されます。

アルゴリズムについても、このコラムで追って取り上げます。まず、プログラミングにおける制御構造がどのようなもので、どのような働きを持っているのかをもう少し詳しく理解しておきましょう。

機械語とアセンブリ言語

コンピュータの頭脳であるCPUは、2進数で表現された──要するに0と1だけで構成された命令とデータだけを解釈します。どのようなプログラミング言語で書かれたプログラムも、最終的には2進数の機械語(マシン語)に変換されます。

CPUは実に単純な機構で、解釈できる命令の種類と数はごくわずかです。そして、CPUの理解できる機械語の命令と1対1で対応する言語がアセンブリ言語です。アセンブリ言語には、変数の宣言も、ifやforなど気の利いた命令も、関数の呼び出しもありません。2進数のパターンを、英単語をベースにした2~4文字程度の単純な『語』に置き換えただけのものです。

なお、ここではインテル製のx86系CPUで用いられる16ビットのアセンブリ言語を用いることにします。

ニモニックとオペランド

先述した、2進数の命令を単純な語に置き換えたものをニモニック(mnemonic)と言います。ニモニックは操作の対象となるデータを採り、これをオペランド(operand)と言います。例えば、MOVというニモニックは英語のmoveを略したもので、2つのオペランドを採り「第1オペランドに第2オペランドの値を保存(転送)する」という動作をします。

書式は以下のようになります。
MOV <op1>, <op2>
他にもいろいろなニモニックがありますが、アセンブリ言語の解説がテーマではないので省略します。今回、制御構造を理解するために必要なニモニックを表1に掲げておきます。

表1:x86系CPUで用いられる基本的なニモニック
ニモニック 書式 機能
ADD ADD <op1>, <op2> <op1>の値に<op2>の値を加算し、結果を<op1>に保存
SUB SUB <op1>, <op2> <op1>の値から<op2>の値を減算し、結果を<op1>に保存
MOV MOV <op1>, <op2> <op1>に<op2>の値を転送(コピー)
INC INC <op> <op>の値を1増加(インクリメント)
DEC DEC <op> <op>の値を1減算(デクリメント)
AND AND <op1>, <op2> <op1>と<op2>の論理和を取り、結果を<op1>に保存
OR OR <op1>, <op2> <op1>と<op2>の論理積を取り、結果を<op1>に保存
XOR XOR <op1>, <op2> <op1>と<op2>の排他的論理和を取り、結果を<op1>に保存
XCHG XCHG <op1>, <op2> <op1>と<op2>の値を入れ替える
CMP CMP <op1>, <op2> <op1>と<op2>の値を比較し、結果をフラグにセット
表2に示すジャンプ系ニモニックがフラグを調べて次の処理先へ移動