[Atelier Blue アトリエブルー]Homeプログラミング IL(CIL,MSIL)>分岐1(Branch)

分岐1(Branch)

もしもプログラムが順次実行だけだったら、すごくつまらないです。というわけで今回は分岐を扱いたいと思います。

無条件分岐

いつでも分岐する分岐を「無条件分岐」といいます。ジャンプとも呼びますが、とりあえずはこれを使ってみましょう。命令は、CSファイルを逆アセンブルして調べても良いですが、私たちは命令表を手に入れたのでそちらを見ながら考えましょう。

命令をさがす

無条件分岐はジャンプです。ということなので「jump」「jmp」という命令をさがしてみます。しかし、なんかmethodとかとついていたりで目的のものではなさそうです。予想が外れました。というわけで「分岐」を英語に直したものである「branch」でさがしてみます。

見つけられたでしょうか?正解は「br.<length> br. – unconditional branch」です。「br」とずいぶん短くなっていますが、説明は「unconditional」つまり「無条件の」という意味になっているのでこれが正解です。

ラベル(Label)

前にも説明しましたが、「~:」と書くとラベルになります。分岐先に指定します。

ソースコード

.assembly extern mscorlib{}
.assembly branchtest{}

.method public static void main() cil managed
{
    .entrypoint
    .maxstack 1
    
    ldc.i4 200
    call void [mscorlib]System.Console::
                    WriteLine(int32)
    br end
    
    //下が実行されない
    ldc.i4 100
    call void [mscorlib]System.Console::
                    WriteLine(int32)
end:
    ret
}

実行すると、「100」を出力して終わります。また、brはオフセットを指定するため、数字で指定することも出来ます。

.assembly extern mscorlib{}
.assembly branchtest{}

.method public static void main() cil managed
{
    .entrypoint
    .maxstack 1
    
    ldc.i4 200
    call void [mscorlib]System.Console::
                    WriteLine(int32)
    br 10 //10バイト後に飛ぶ
    
    //下が実行されない
    ldc.i4 100
    call void [mscorlib]System.Console::
                    WriteLine(int32)
    
    ret
}

大抵は使わないと思います。それと、今までと同じ系統で、「br.s」というものもあります。1バイトのオフセットが指定できるので、「-128~127」の範囲のジャンプで在ればこちらを使った方が少ないバイト数になります。

.assembly extern mscorlib{}
.assembly branchtest{}

.method public static void main() cil managed
{
    .entrypoint
    .maxstack 1
    
    ldc.i4 200
    call void [mscorlib]System.Console::
                    WriteLine(int32)
    br.s end 
    
    //下が実行されない
    ldc.i4 100
    call void [mscorlib]System.Console::
                    WriteLine(int32)
    
end:
    
    ret
}

3バイト分の節約になります。


ページの一番上へ
前のページへ一覧に戻る 次のページへ
初版2006-4-6
[Atelier Blue アトリエブルー]Homeプログラミング IL(CIL,MSIL)>分岐1(Branch)