サブルーチン


コールとリターン

プログラムが大きくなってくると、同じようなコードを何度も繰り返します
似たようなプログラムを何度も使いまわす時、何度も書きなおすのは不合理です

C言語プログラマであれば、この場合は関数での処理を思い出すでしょう
まさにそれが正解ですが、機械語では関数というものは存在しません
機械語ではこれをサブルーチンと呼び、呼び出し場所に戻る機能をサポートしています
因みに、エントリポイントからのプログラムをサブルーチンに対しメインルーチンと呼びます

サブルーチンの概念はBasicプログラマーさんならばよくご存知でしょう
機械語では、指定オフセットアドレスにジャンプし処理を終了すると呼び出し元に戻ります
呼び出した場所に戻ることができるJMP命令のようなものです

サブルーチンの先頭となるオフセットアドレスに移動するにはCALL命令を使います
第一オペランドに、オフセットアドレスまたはそれを表すレジスタ、メモリアドレスを指定します

CALLした場合は、必ず呼び出し元へ戻る必要があります
そうでなければ、永遠とサブルーチンを走っていることになります
サブルーチンから呼び出し元へ戻るには、サブルーチンでRETを指示します
-A 200
15F2:0200 MOV WORD PTR [BX] , AX
15F2:0202 ADD BX , 2
15F2:0205 RET
15F2:0206
-A 100
15F2:0100 MOV AX , 4241
15F2:0103 MOV BX , 300
15F2:0106 CALL 200
15F2:0109 MOV AX , 4443
15F2:010C CALL 200
15F2:010F

-G =100 10F

AX=4443  BX=0304  CX=0000  DX=0000  SP=FFEE  BP=0000  SI=0000  DI=0000
DS=15F2  ES=15F2  SS=15F2  CS=15F2  IP=010F   NV UP EI PL NZ NA PO NC

-D 300 303
15F2:0300  41 42 43 44                                       ABCD
オフセットアドレス0200〜0205がサブルーチンとなっています
0106でCALLしてサブルーチンへとジャンプしますが、0205のRETで復帰し
その次の0109からプログラムを実行します

サブルーチンはその後、010Cでも呼び出しています
このように、メインルーチンから何度もサブルーチンを呼び出すことができます
このサブルーチンは、AXレジスタをBXレジスタの指すアドレスへストアします
そして、最後にBXレジスタの内容に2を加算して戻ります

さらに、サブルーチンのサブルーチンというものも可能です
サブルーチンからコールされたサブルーチンもちゃんと呼び出し元に復帰します
-A 300
15F2:0300 MOV DL , FF
15F2:0302 RET
15F2:0303
-A 200
15F2:0200 MOV DH , EE
15F2:0202 CALL 300
15F2:0205 RET
15F2:0206
-A 100
15F2:0100 CALL 200
15F2:0103 MOV AX , DX
15F2:0105

-G =100 105

AX=EEFF  BX=0000  CX=0000  DX=EEFF  SP=FFEE  BP=0000  SI=0000  DI=0000
DS=15F2  ES=15F2  SS=15F2  CS=15F2  IP=0105   NV UP EI PL NZ NA PO NC
サブルーチンである0202でCALLしています
するとサブルーチンのサブルーチンが実行され、RETでサブルーチンに復帰します
このように、サブルーチンはネスティング(入れ子構造)が可能です



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