分岐命令

分岐命令は命令ポインタ(RIP)を書き換えることでプログラムの実行位置を変更します。数値の比較と比較結果で動作が変わる条件分岐命令、条件転送命令等があります。

JMP

プリフィックス オペコード 命令 説明
- EB cb JMP rel8 jmp命令の次の命令のアドレス ±127 バイトの範囲で分岐する。
- E9 cd JMP rel32 jmp命令の次の命令のアドレス ±2G バイトの範囲で分岐する。
- FF /4 JMP r/m64 レジスタまたはメモリで指定された 64 ビットのオフセットへ分岐する。
プリフィックス オペコード 命令 説明
- FF /5 JMP m16:16 m16:16 で指定されるアドレスに絶対間接分岐する。
- FF /5 JMP m16:32 m16:32 で指定されるアドレスに絶対間接分岐する。
REX.W FF /5 JMP m16:64 64 ビットモードの場合、セレクタの指示先がゲートであれば、
RIP は64 ビットのディスプレースメントであり、ゲートから取得される。
指示先がゲートでなければ、RIP はゼロ拡張された32 ビットのオフセットであり、
命令で参照されるfar ポインタから取得される。
- EB cb JMP rel8 Jump short, RIP = RIP + 8-bit displacement sign extended to 64-bits
- E9 cd JMP rel32 Jump near, relative, RIP = RIP + 32-bit displacement sign extended to 64-bits
- FF /4 JMP r/m64 Jump near, absolute indirect, RIP = 64-Bit offset from register or memory
- FF /5 JMP m16:16 Jump far, absolute indirect, address given in m16:16
- FF /5 JMP m16:32 Jump far, absolute indirect, address given in m16:32.
REX.W FF /5 JMP m16:64 Jump far, absolute indirect, address given in m16:64.

JECXZ / JRCXZ

ECX または RCX の値が 0 の場合に、次の命令のアドレス ±127 バイトの範囲で分岐します。

プリフィックス オペコード 命令 説明
67 E3 cb JECXZ rel8 ECX が 0 なら分岐
- E3 cb JRCXZ rel8 RCX が 0 なら分岐

LOOP / LOOPZ / LOOPNZ

RCXをカウンタとして使い、RCXの値をデクリメント(1を減じる)し、カウント≠0 の場合に、次の命令のアドレス ±127 バイトの範囲で分岐します。繰り返し回数をRCXレジスタに設定し、繰り返す部分の最後にLOOP命令を置き、RCXが 0 でなければ先頭に戻る(分岐)ことで繰り返し回数の決まっているループを構成するために使います。LOOPZ、LOOPNZ命令はカウンタが 0 でない場合にゼロフラグがゼロ(LOOPZ)またはゼロでない(LOOPNZ)場合に分岐します。loop命令より dec/jnz の組み合わせのほうが速いためloop命令はあまり使われません。以下のコードはどちらも100回繰り返されます。

        mov     rcx, 100               mov     rcx, 100
    label01:                       label01:
                                              
        繰り返し部分                   繰り返し部分
                                       
        pushf                          loop    label01
        dec     rcx
        popf
        jrcxz   label01
プリフィックス オペコード 命令 説明
- E2 cb LOOP rel8 RCXをデクリメントし、カウント≠0 の場合に 8bitオフセットで分岐する。
REX.W E2 cb LOOP rel8 RCXをデクリメントし、カウント≠0 の場合に 8bitオフセットで分岐する。JMP Shortでは、RIP = RIP + 64 ビットに符号拡張された8 ビットのオフセット。
- E1 cb LOOPE rel8 RCXをデクリメントし、カウント≠0 でかつZF=1 の場合に 8bitオフセットで分岐する。
REX.W E1 cb LOOPE rel8 RCXをデクリメントし、カウント≠0 でかつZF=1 の場合に 8bitオフセットで分岐する。JMP Short では、RIP = RIP + 64ビットに符号拡張された8 ビットのオフセット。
- E0 cb LOOPNE rel8 RCXをデクリメントし、カウント≠0 でかつZF=0 の場合に 8bitオフセットで分岐する。
REX.W E0 cb LOOPNZ rel8 RCXをデクリメントし、カウント≠0 でかつZF=0 の場合に 8bitオフセットで分岐する。JMP Short では、RIP = RIP + 64ビットに符号拡張された8 ビットのオフセット。

条件フラグの名称と意味

条件分岐命令、条件転送命令のオペコードに含まれている、条件を表す名称は以下の表のように 30種類が割り当てられています。「大きくない」と「小さいか等しい」と同じ状態を表す名称が 重複して使用できるようになっています。また逆の意味をもつ条件を対応させると9種類の 正逆2種類となって、かなり覚えやすくなると思います。Jcc、CMOVcc、SETcc で90種類ある 命令を 3命令 x 9条件 x 正逆2つ として分解して理解すると楽になります。


名称 別名 意味 名称 別名 意味
Z
Zero
E
Equal
等しい/ゼロ
(ZF=1)
NZ
NotZero
NE
NotEqual
等しくない/ゼロでない
(ZF=0))
A
Above
NBE
NotBelow or Equal
符号なしで大きい
(CF=0 および ZF=0)
BE
Below or Equal
NA
NotAbove
符号なしで小さいか等しい
(CF=1 または ZF=1)
B
Below
NAE
NotAbove or Equal
符号なしで小さい
(CF=1)
AE
Above or Equal
NB
NotBelow
符号なしで大きいか等しい
(CF=0)
G
Greater
NLE
NotLess or Equal
大きい
(ZF=0 および SF=OF)
LE
Less or Equal
NG
NotGreater
小さいか等しい
(ZF=1 または SF<>OF)
L
Less
NGE
NotGreater or Equal
小さい
(SF<>OF)
GE
Greater or Equal
NL
NotLess
大きいか等しい
(SF=OF)
P
Parity
PE
ParityEven
パリティが偶数
(PF=1)
NP
NotParity
PO
ParityOdd
パリティが奇数
(PF=0)
C
Carry
キャリー
(CF=1)
NC
NotCarry
キャリークリア
(CF=0)
O
Overflow
オーバーフロー
(OF=1)
NO
NotOverflow
オーバーフローでない
(OF=0)
S
Sign
2の補数で負、
最上位ビットが1(SF=1)
NS
NotSign
2の補数で正、
最上位ビットが0(SF=0)

条件分岐命令(Jcc)

プリフィックス オペコード 命令 説明
- 74 cb JZ rel8 ゼロの場合に分岐する。
- 0F 84 cd JZ rel32
- 75 cb JNZ rel8 ゼロでない場合に分岐する。
- 0F 85 cd JNZ rel32
- 77 cb JA rel8 符号なしで大きい場合に分岐する。
- 0F 87 cd JA rel32
- 76 cb JBE rel8 符号なしで小さいか等しい場合に分岐する。
- 0F 86 cd JBE rel32
- 72 cb JB rel8 符号なしで小さい場合に分岐する。
- 0F 82 cd JB rel32
- 73 cb JAE rel8 符号なしで大きいか等しい場合に分岐する。
- 0F 83 cd JAE rel32
- 7F cb JG rel8 大きい場合に分岐する。
- 0F 8F cd JG rel32
- 7E cb JLE rel8 小さいか等しい場合に分岐する。
- 0F 8E cd JLE rel32
- 7C cb JL rel8 小さい場合に分岐する。
- 0F 8C cd JL rel32
- 7D cb JGE rel8 大きいか等しい場合に分岐する。
- 0F 8D cd JGE rel32
- 7A cb JP rel8 パリティが偶数の場合に分岐する。
- 0F 8A cd JP rel32
- 7B cb JNP rel8 パリティが奇数の場合に分岐する。
- 0F 8B cd JNP rel32
- 72 cb JC rel8 キャリーがある場合に分岐する。
- 0F 82 cd JC rel32
- 73 cb JNC rel8 キャリーがない場合に分岐する。
- 0F 83 cd JNC rel32
- 70 cb JO rel8 オーバーフローがある場合に分岐する。
- 0F 80 cd JO rel32
- 71 cb JNO rel8 オーバーフローがない場合に分岐する。
- 0F 81 cd JNO rel32
- 78 cb JS rel8 2の補数で負の場合に分岐する。
- 0F 88 cd JS rel32
- 79 cb JNS rel8 2の補数で正の場合に分岐する。
- 0F 89 cd JNS rel32

フラグの変化 : 変化しない。

フラグ OF SF ZF AF CF PF
実行後 - - - - - -

条件転送命令 (CMOVcc)

プリフィックス オペコード 命令 説明
66 0F 44 /r CMOVZ r16, r/m16 ゼロの場合にコピーする。
- 0F 44 /r CMOVZ r32, r/m32
REX.W 0F 44 /r CMOVZ r64, r/m64
66 0F 45 /r CMOVNZ r16, r/m16 ゼロでない場合にコピーする。
- 0F 45 /r CMOVNZ r32, r/m32
REX.W 0F 45 /r CMOVNZ r64, r/m64
66 0F 47 /r CMOVA r16, r/m16 符号なしで大きい場合にコピーする。
- 0F 47 /r CMOVA r32, r/m32
REX.W 0F 47 /r CMOVA r64, r/m64
66 0F 46 /r CMOVBE r16, r/m16 符号なしで小さいか等しい場合にコピーする。
- 0F 46 /r CMOVBE r32, r/m32
REX.W 0F 46 /r CMOVBE r64, r/m64
66 0F 42 /r CMOVB r16, r/m16 符号なしで小さい場合にコピーする。
- 0F 42 /r CMOVB r32, r/m32
REX.W 0F 42 /r CMOVB r64, r/m64
66 0F 43 /r CMOVAE r16, r/m16 符号なしで大きいか等しい場合にコピーする。
- 0F 43 /r CMOVAE r32, r/m32
REX.W 0F 43 /r CMOVAE r64, r/m64
66 0F 4F /r CMOVG r16, r/m16 大きい場合にコピーする。
- 0F 4F /r CMOVG r32, r/m32
REX.W 0F 4F /r CMOVG r64, r/m64
66 0F 4E /r CMOVLE r16, r/m16 小さいか等しい場合にコピーする。
- 0F 4E /r CMOVLE r32, r/m32
REX.W 0F 4E /r CMOVLE r64, r/m64
66 0F 4C /r CMOVL r16, r/m16 小さい場合にコピーする。
- 0F 4C /r CMOVL r32, r/m32
REX.W 0F 4C /r CMOVL r64, r/m64
66 0F 4D /r CMOVGE r16, r/m16 大きいか等しい場合にコピーする。
- 0F 4D /r CMOVGE r32, r/m32
REX.W 0F 4D /r CMOVGE r64, r/m64
66 0F 4A /r CMOVP r16, r/m16 パリティが偶数の場合にコピーする。
- 0F 4A /r CMOVP r32, r/m32
REX.W 0F 4A /r CMOVP r64, r/m64
66 0F 4B /r CMOVNP r16, r/m16 パリティが奇数の場合にコピーする。
- 0F 4B /r CMOVNP r32, r/m32
REX.W 0F 4B /r CMOVNP r64, r/m64
66 0F 42 /r CMOVC r16, r/m16 キャリーがある場合にコピーする。
- 0F 42 /r CMOVC r32, r/m32
REX.W 0F 42 /r CMOVC r64, r/m64
66 0F 43 /r CMOVNC r16, r/m16 キャリーがない場合にコピーする。
- 0F 43 /r CMOVNC r32, r/m32
REX.W 0F 43 /r CMOVNC r64, r/m64
66 0F 40 /r CMOVO r16, r/m16 オーバーフローがある場合にコピーする。
- 0F 40 /r CMOVO r32, r/m32
REX.W 0F 40 /r CMOVO r64, r/m64
66 0F 41 /r CMOVNO r16, r/m16 オーバーフローがない場合にコピーする。
- 0F 41 /r CMOVNO r32, r/m32
REX.W 0F 41 /r CMOVNO r64, r/m64
66 0F 48 /r CMOVS r16, r/m16 2の補数で負の場合にコピーする。
- 0F 48 /r CMOVS r32, r/m32
REX.W 0F 48 /r CMOVS r64, r/m64
66 0F 49 /r CMOVNS r16, r/m16 2の補数で正の場合にコピーする。
- 0F 49 /r CMOVNS r32, r/m32
REX.W 0F 49 /r CMOVNS r64, r/m64

フラグの変化 : 変化しない。

フラグ OF SF ZF AF CF PF
実行後 - - - - - -

条件セット命令 (SETcc)

条件フラグにしたがってレジスタ、またはメモリ(バイト) に 1 を設定する。

プリフィックス オペコード 命令 説明
- 0F 94 SETZ r/m8 ゼロの場合に 1 を格納する。
REX 0F 94 SETZ r/m8
- 0F 95 SETNZ r/m8 ゼロでない場合に 1 を格納する。
REX 0F 95 SETNZ r/m8
- 0F 97 SETA r/m8 符号なしで大きい場合に 1 を格納する。
REX 0F 97 SETA r/m8
- 0F 96 SETBE r/m8 符号なしで小さいか等しい場合に 1 を格納する。
REX 0F 96 SETBE r/m8
- 0F 92 SETB r/m8 符号なしで小さい場合に 1 を格納する。
REX 0F 92 SETB r/m8
- 0F 93 SETAE r/m8 符号なしで大きいか等しい場合に 1 を格納する。
REX 0F 93 SETAE r/m8
- 0F 9F SETG r/m8 大きい場合に 1 を格納する。
REX 0F 9F SETG r/m8
- 0F 9E SETLE r/m8 小さいか等しいの場合に 1 を格納する。
REX 0F 9E SETLE r/m8
- 0F 9C SETL r/m8 小さい場合に 1 を格納する。
REX 0F 9C SETL r/m8
- 0F 9D SETGE r/m8 大きいか等しい場合に 1 を格納する。
REX 0F 9D SETGE r/m8
- 0F 9A SETP r/m8 パリティが偶数の場合に 1 を格納する。
REX 0F 9A SETP r/m8
- 0F 9B SETNP r/m8 パリティが奇数の場合に 1 を格納する。
REX 0F 9B SETNP r/m8
- 0F 92 SETC r/m8 キャリーがある場合に 1 を格納する。
REX 0F 92 SETC r/m8
- 0F 93 SETNC r/m8 キャリーがない場合に 1 を格納する。
REX 0F 93 SETNC r/m8
- 0F 90 SETO r/m8 オーバーフローがある場合に 1 を格納する。
REX 0F 90 SETO r/m8
- 0F 91 SETNO r/m8 オーバーフローがない場合に 1 を格納する。
REX 0F 91 SETNO r/m8
- 0F 98 SETS r/m8 2の補数で負の場合に 1 を格納する。
REX 0F 98 SETS r/m8
- 0F 99 SETNS r/m8 2の補数で正の場合に 1 を格納する。
REX 0F 99 SETNS r/m8

フラグの変化 : 変化しない。

フラグ OF SF ZF AF CF PF
実行後 - - - - - -

続く...


このページの目次