
■ 計算を行う ■
前回はアセンブラ言語の「MOV」命令と「ADD」命令について簡
単に説明を行ないました。
「MOV」命令は移動(move)を表す命令、「ADD」命令は足し算
(addition)を表す命令でした。
そして、簡単な足し算を行なっている例を示しました。
簡単な足し算を行なっている例をもう1度見てみましょう。
MOV EAX, 5 ;EAXに5を格納
MOV EBX, 3 ;EBXに3を格納
ADD EAX, EBX ;EAX+EBXをEAXに格納
右側の日本語はコメントです。
アセンブラ言語では「;」より右側は全てコメントとして扱わ
れます。
これだけの命令で5+3が求められるのです。
簡単ですね。
では、同じようにして今度は引き算を行なってみましょう。
●引き算を行なう時
MOV EAX, 5 ;EAXに5を格納
MOV EBX, 3 ;EBXに3を格納
SUB EAX, EBX ;EAX−EBXをEAXに格納
~~~
「ADD」となっていたところが「SUB」となっただけです。
たったこれだけで引き算が出来ます。
これと似たような事を行い、掛け算、割り算も行なう事が出来
ます。
●掛け算を行なう時
MOV EAX, 5 ;EAXに5を格納
MOV EBX, 3 ;EBXに3を格納
MUL EBX ;EAX×EBXをEAXに格納
~~~
足し算、引き算を行なう時と比べて、微妙に異なる部分があり
ます。
まず、実際に計算を行なう時の命令が「MUL」(Multiple)にな
っています。
これは「掛け算を行ないなさい」という命令なのですが、足し
算、引き算を行なう時と書き方が微妙に異なっています。
●引き算を行なう時
SUB EAX, EBX ;EAX−EBXをEAXに格納
●掛け算を行なう時
MUL EBX ;EAX×EBXをEAXに格納
 ̄ ̄
↑
この部分が無い。
EAXの指定がありませんよね。
何故EAXレジスタの指定が無いのかというと、掛け算ではEAXレ
ジスタが使用されるという、「暗黙の了解」があるからです。
これはインテルプロセッサの仕様です。
MUL命令を使用してレジスタ同士の掛け算を行なう時は必ずEAX
レジスタが使用されるのです。
では、次に割り算を行なってみましょう。
●割り算を行なう時
MOV EDX, 0 ;EDXに0を格納
MOV EAX, 5 ;EAXに5を格納
MOV EBX, 3 ;EBXに3を格納
DIV EBX ;EAX÷EBXをEAXに格納
~~~
今度は「DIV」(Division)になっています。
たったこれだけで割り算が出来ます。
割り算の場合も、足し算、引き算を行なう時と書き方が微妙に
異なっています。
●引き算を行なう時
SUB EAX, EBX ;EAX−EBXをEAXに格納
●割り算を行なう時
DIV EBX ;EAX÷EBXをEAXに格納
 ̄ ̄
↑
この部分が無い。
EAXの指定がありませんよね。
何故EAXレジスタの指定が無いのかというと、割り算ではEAXレ
ジスタが使用されるという、「暗黙の了解」があるからです。
これはインテルプロセッサの仕様です。
DIV命令を使ってレジスタ同士の割り算を行なう時は必ずEAXレ
ジスタが使用されるのです。
ところでもう1箇所異なる部分があります。
MOV EDX, 0 ;EDXに0を格納
という部分です。
これは何をしているのでしょうか?
EDXというレジスタに0を格納しているのですが、では何故EDX
レジスタに0を格納する必要があるのでしょうか?
皆さんご存知のように、割り算をすると余りが出る時がありま
す。
この余りを格納する為にEDXというレジスタが使用されます。
余りを正しく格納する為には、いったんこのEDXレジスタを0
クリアしておかなければならない、という約束事があるのです。
これもインテルプロセッサの仕様です。
「EDX」というレジスタは「DIV」という命令を使用する事によ
り自動的に書き換わってしまうのです。
今まで「レジスタの事をバッファの様な物だと思ってください」
と書いてきましたが、この様に見ていくと、レジスタとバッフ
ァの挙動が異なる物である事が少しずつですがお分かりいただ
けるのではないでしょうか?
バッファ(メモリ)の中身が自動的に書き換わってしまう事は
ありませんよね?
さあ、あなたはこれで一通りアセンブラ言語を使用して計算が
行なえるようになりました。
以下にアセンブラ言語での計算命令をまとめます。
●足し算(addition)を行なう時
MOV EAX, 5 ;EAXに5を格納
MOV EBX, 3 ;EBXに3を格納
ADD EAX, EBX ;EAX+EBXをEAXに格納
●引き算(sub)を行なう時
MOV EAX, 5 ;EAXに5を格納
MOV EBX, 3 ;EBXに3を格納
SUB EAX, EBX ;EAX−EBXをEAXに格納
●掛け算(multiple)を行なう時
MOV EAX, 5 ;EAXに5を格納
MOV EBX, 3 ;EAXに3を格納
MUL EBX ;EAX×EBXをEAXに格納
●割り算(division)を行なう時
MOV EDX, 0 ;EDXに0を格納
MOV EAX, 5 ;EAXに5を格納
MOV EBX, 3 ;EBXに3を格納
DIV EBX ;EAX÷EBXをEAXに格納
;余りをEDXに格納
思っていたより簡単だというイメージを持って頂けるとありが
たいのですが・・・。
ところで、計算命令を見ていっただけでも、「インテルプロセ
ッサの仕様」という言葉が度々出てきました。
C言語やJAVA言語で書かれたプログラムはインテルプロセ
ッサだけでなく、他のメーカーのプロセッサ上でも同じプログ
ラムを動作させる事が出来ます。
ところが、アセンブラ言語に関してはプロセッサが異なると全
く異なるものとなってしまいます。
何故異なってしまうのかというと、各メーカーのプロセッサ毎
に、さまざまな仕様の違いがあるからです。
前回説明したように、アセンブラ言語とプロセッサが直切理解
する機械語という物は1対1で対応するものです。
という事は、プロセッサの仕様が異なると、それにつられる形
でアセンブラ言語も異なる物となってしまいます。
一番単純な例を示すと、例えばインテルプロセッサのレジスタ
の1つに「EAX」という物があります。
この「EAX」というレジスタはインテルプロセッサ独自の物で
す。
他のメーカーのプロセッサには存在しません。
先ほどの計算を行なう命令をインテル以外のプロセッサで動作
させようとしても、「EAX」というレジスタがプロセッサに存
在しない以上、動作のしようがないのです。
ちなみにインテルIA32以外のプロセッサで同じように5+3の
計算を行なっている例を以下に示します。
●POWER-PC(IBM製)
このプロセッサはAPPLE社のPOWER MACというパソコンで使用
されているプロセッサです。
この講座をご覧になっている方でMACユーザーの方も極少数
ですがいらっしゃるようです。
その方は今、自分のコンピュータ上ではこんな命令が動作し
ているんだな、と思ってください。
li r1, 3
li r2, 5
add r1,r2,r1
●ARM(ARM製)
ARMというプロセッサ名を聞いた事がある方は少ないと思い
ますが、殆どの方が持っているはずです。そして実際に使っ
た事があるはずです。
このプロセッサは携帯電話に使われています。
小さくて省電力のわりに高速なのです。
mov r0 , #5
mov r1 , #3
add r0 , r0 , r1
●Itanium(INTEL製)
現在ではまだ殆ど使われる事はありませんが、インテルの次
世代プロセッサの基本となるプロセッサです。
このプロセッサの特徴は小さなプログラムをいくつか並行動
作させてしまうという非常に強力なパワーを持っています。
Pentium4までのプロセッサは命令単位で並行動作させていま
したが、このプロセッサ以降はプログラム単位、機能単位で
並行動作させてしまいます。
このプロセッサ1個で、あたかも複数のプロセッサが並行動
作しているかのようにふるまうと言えば良いでしょうか。
mov r16, 5
mov r17, 3
add r1 = r16, r17
Itaniumプロセッサに関しては同じインテル製なのにアセン
ブラ言語が違っても大丈夫なの?と疑問に思われた方もいる
かもしれません。
Itaniumプロセッサ以降はIA-64(Intel Architecture 64Bit)
というモードで動作するようになるので命令が異なるのです。
命令が違うからと言ってPentium4までのプログラムがこのプ
ロセッサ上で動作しなくなるという事はありません。
何故かというと、今までのプログラムはIA32モードという特
別なモードにより互換性が保たれるようになっているからで
す。
次回はアセンブラ言語を使用して実際にプログラムを作成して
みる予定です。
アセンブラ言語を本当に知りたい方は、恐らくこの講座の内容
は非常に退屈なものに感じているのではないでしょうか?
その気持ち凄く良く分かります。
本当に知りたい事はここに書かれてある様な事ではないはずで
す。
しかし、まずは基本から覚えていきましょう。