実行順序の変更


無条件ジャンプ

これまでのプログラムは、指定アドレスから順番に実行するだけでした
ここでは、プログラムの流れを変える方法を覚えましょう

CPUはどのようにプログラムを実行しているかというとIPレジスタを用いています
プログラムは常に現在IPレジスタが指すオフセットアドレスを実行します
//セグメントはCSレジスタなので CS : IP が実行アドレスとなる

逆に考えれば、このIPレジスタを制御することがプログラムの制御につながるのです
しかし、IPレジスタのコントロールはMOV命令を使うことはできません
IPレジスタを書きかえるには、専用の命令を使わなくてはならないのです

ジャンプ命令には「条件ジャンプ」と「無条件ジャンプ」が存在します
高級言語などでは、無条件のジャンプはいわゆる「GoToレス」の概念から
Java言語のように最初から実装していない言語もありますが
アセンブリのような低水準言語では、オフセットアドレスを指定してジャンプすることができます

無条件ジャンプを行うにはJMP命令を用います
ディスティネーションオペランドには、オフセットアドレスを指定するか
16ビットのレジスタまたはメモリ空間を指定します
JMP命令が実行されると、無条件に指定したアドレスへジャンプします
-A 100
15F2:0100 MOV AX , 100
15F2:0103 MOV BX , 200
15F2:0106 JMP BX
15F2:0108
-A 200
15F2:0200 MUL BX
15F2:0202
-G =100 202

AX=0000  BX=0200  CX=0000  DX=0002  SP=FFEE  BP=0000  SI=0000  DI=0000
DS=15F2  ES=15F2  SS=15F2  CS=15F2  IP=0202   OV UP EI PL NZ AC PO CY
オフセットアドレス 0106 が実行されると、IPレジスタは 200 にセットされます
終了時にIPレジスタが202になっていることが確認できますね
疑わしければ、トレースして確認しても良いでしょう

プログラムはJMP命令でアドレス200へジャンプしてMULを実行しています
16進数100×200は20000なので、DXレジスタとAXレジスタを見ればわかりますね

このように、同じCS内部のジャンプをセグメント内ジャンプ
またはnearジャンプと呼びます
さらにJMP命令は、即値でのアドレス指定も可能です
-A 100
15F2:0100 JMP 110
15F2:0102
-A 110
15F2:0110 MOV AX , 100
15F2:0113 ADD AX , FF
15F2:0116
-G =100 116

AX=01FF  BX=0200  CX=0000  DX=0002  SP=FFEE  BP=0000  SI=0000  DI=0000
DS=15F2  ES=15F2  SS=15F2  CS=15F2  IP=0116   NV UP EI PL NZ NA PE NC
これらの動作では決してCSレジスタは変更されません
また、このようにIPアドレスから-128〜127以内でのnearジャンプのことを
特別にshortジャンプと呼びます //機械語レベルで分別されています

JMP SHORT オフセットアドレス

と指定することで、ショートジャンプであることを明示します
この方がプログラムのサイズは小さくなりますが、ジャンプ範囲が小さいことに注意してください


絶対アドレス指定と相対アドレス指定

アセンブリ言語では、ジャンプ命令のアドレス指定は絶対アドレスです
つまり、直接ジャンプ先のアドレスを指定します

これに対し、機械語は相対アドレスで指定しなければなりません
レジスタやメモリからジャンプアドレスをロードする場合は絶対アドレスですが
即値による指定を行う場合、現在のIPレジスタの次の命令からの距離を相対的に指定します
-A 100
15F2:0100 JMP 102
15F2:0102 JMP 106
15F2:0104
-U 100 103
15F2:0100 EB00          JMP     0102
15F2:0102 EB02          JMP     0106
shortジャンプ命令は EB です
その後に1バイトの相対アドレスを指定します
EB00は、現在のアドレスから0距離進んだ場所(つまり単純に次の命令)
EB02は、現在のアドレスから2アドレス進んだ場所ということになります



前のページへ戻る次のページへ